前端面試題(框架部分)

Vue:
1、MVVM模式與MVC模式的區別
MVVM即Model-View-ViewModel。
它是將「數據模型數據雙向綁定」的思想做爲核心,所以在View和Model之間沒有聯繫,經過ViewModel進行交互,並且Model和ViewModel之間的交互是雙向的,所以視圖的數據的變化會同時修改數據源,而數據源數據的變化也會當即反應到View上。
Vue是以數據爲驅動的,Vue自身將DOM和數據進行綁定,一旦建立綁定,DOM和數據將保持同步,每當數據發生變化,DOM會跟着變化。 ViewModel是Vue的核心,它是Vue的一個實例。Vue實例時做用域某個HTML元素上的,這個HTML元素能夠是body,也能夠是某個id所指代的元素。 DOM Listeners和Data Bindings是實現雙向綁定的關鍵。DOM Listeners監聽頁面全部View層DOM元素的變化,當發生變化,Model層的數據隨之變化;Data Bindings監聽Model層的數據,當數據發生變化,View層的DOM元素隨之變化。
MVC即Model-View-Controller
MVC是比較直觀的架構模式,用戶操做->View(負責接收用戶的輸入操做)->Controller(業務邏輯處理)->Model(數據持久化)->View(將結果反饋給View)。
2、v-show與v-if的區別
條件渲染指令,與v-if不一樣的是,不管v-show的值爲true或false,元素都會存在於HTML代碼中;而只有當v-if的值爲true,元素纔會存在於HTML代碼中。v-show指令只是設置了元素CSS的style值
3、如何讓css只在當前組件中起做用css

在每個vue組件中均可以定義各自的css,js,若是但願組件內寫的css只對當前組件起做用,只須要在style中寫入scoped,即:
<style scoped></style>
4、指令keep-alive
在vue-router寫着keep-alive,keep-alive的含義: 若是把切換出去的組件保留在內存中,能夠保留它的狀態或避免從新渲染。爲此能夠添加一個keep-alive指令
<component :is='curremtView' keep-alive></component>
5、Vue.js與其餘框架的區別?
1.與AngularJS的區別
相同點:
都支持指令:內置指令和自定義指令。
都支持過濾器:內置過濾器和自定義過濾器。
都支持雙向數據綁定。
都不支持低端瀏覽器。
不一樣點:
(1).AngularJS的學習成本高,好比增長了Dependency Injection特性,而Vue.js自己提供的API都比較簡單、直觀。
(2).在性能上,AngularJS依賴對數據作髒檢查,因此Watcher越多越慢。
Vue.js使用基於依賴追蹤的觀察而且使用異步隊列更新。全部的數據都是獨立觸發的。
(3).vue中數據放在data對象裏面,angular數據綁定在$scope上面
(4).vue有組件化概念,angular中沒有
2.與React的區別
相同點:
React採用特殊的JSX語法,Vue.js在組件開發中也推崇編寫.vue特殊文件格式,對文件內容都有一些約定,二者都須要編譯後使用。
中心思想相同:一切都是組件,組件實例之間能夠嵌套。
都提供合理的鉤子函數,可讓開發者定製化地去處理需求。
都不內置列數AJAX,Route等功能到核心包,而是以插件的方式加載。
在組件開發中都支持mixins的特性。
不一樣點:
React依賴Virtual DOM,而Vue.js使用的是DOM模板。React採用的Virtual DOM會對渲染出來的結果作髒檢查。
Vue.js在模板中提供了指令,過濾器等,能夠很是方便,快捷地操做DOM。
參考:http://blog.csdn.net/haoshidai/article/details/52346865
6、Vue的雙向數據綁定原理是什麼?
vue.js 是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。html

具體步驟:vue

第一步:須要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上 setter和getter
這樣的話,給這個對象的某個值賦值,就會觸發setter,那麼就能監聽到了數據變化node

第二步:compile解析模板指令,將模板中的變量替換成數據,而後初始化渲染頁面視圖,並將每一個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變更,收到通知,更新視圖react

第三步:Watcher訂閱者是Observer和Compile之間通訊的橋樑,主要作的事情是:
一、在自身實例化時往屬性訂閱器(dep)裏面添加本身
二、自身必須有一個update()方法
三、待屬性變更dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。
7、vue如何實現父子組件通訊,以及非父子組件通訊?
一、父子:
使用props:
props監聽父組件傳遞過來的信息
傳遞過來後,可直接引用,就如已經傳遞過來數據塞到data
使用$refs:
this.$refs.XXX
二、子父:
自定義事件:
父組件能夠在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件
子組件$emit()觸發,父組件$on()監聽
使用$parent:
this.$parent.XXX
三、非父子:
簡單場景用bus,複雜場景用vuexwebpack

<div id="app4">
<display></display>
<increment></increment>
</div>
<script>
var bus = new Vue();
Vue.component('increment', {
template: `<button @click="add">+</button>`,
data: function () {
return {count: 0}
},
methods: {
add: function () {
bus.$emit('inc', this.count+=1)
}
}
});
Vue.component('display', {
template: `<span>Clicked: <mark>{{c}}</mark> times</span>`,
data: function () {
return {c: 0}
},
created: function () {
var self=this;
// bus.$on('inc', function (num) {
// self.c = num
// });
bus.$on('inc', (num) =>
this.c = num
);
}
});
vm = new Vue({
el: "#app4",
})
</script>

8、vue響應式原理?
工做原理是當咱們把一個普通的JavaScript對象傳給Vue 實例的data選項的時候,Vue會遍歷此對象的全部屬性,並使用Object.definePropert把這些屬性所有轉化爲getter/setter。(Object.definePropert是僅ES5支持,且沒有墊片腳本的特性,所以Vue不支持IE8及更低版本瀏覽器。)用戶看不到getter/setter,可是在內部它們讓Vue追蹤依賴,在屬性被訪問和修改時通知變化。每一個組件實例都有相應的watcher實例對象,它會在組件渲染的過程當中把屬性記錄爲依賴,以後當依賴項的setter被調用時,會通知watcher從新計算,從而使它關聯的組件得以更新。
9、vue-router相關
一、vue-router實現原理?
單頁面應用(SPA)的核心之一是: 更新視圖而不從新請求頁面,
實現這一點主要是兩種方式:
1.Hash: 經過改變hash值
2.History: 利用history對象新特性(詳情可出門左拐見: http://www.cnblogs.com/yanze/p/7641774.html)es6

而在vue-router中,它提供mode參數來決定採用哪種方式,選擇流程以下:
默認Hash-->若是瀏覽器支持History新特性改用History-->若是不在瀏覽器環境則使用abstractweb

基本方法分析:
Hash
1.push()
功能: 設置新的路由添加歷史記錄並更新視圖,經常使用狀況是直接點擊切換視圖
調用流程:
1 $router.push() //顯式調用方法
2 HashHistory.push() //根據hash模式調用,設置hash並添加到瀏覽器歷史記錄(window.location.hash= XXX)
3 History.transitionTo() //開始更新
4 History.updateRoute() //更新路由
5 {app._route= route}
6 vm.render() //更新視圖ajax

2.replace
功能: 替換當前路由並更新視圖,經常使用狀況是地址欄直接輸入新地址
流程與push基本一致
但流程2變爲替換當前hash (window.location.replace= XXX)不懂此方法的可見: http://www.w3school.com.cn/jsref/met_loc_replace.asp算法

3.監聽地址欄變化
在setupListeners中監聽hash變化(window.onhashchange)並調用replace

History
1.push
與hash模式相似,只是將window.hash改成history.pushState
2.replace
與hash模式相似,只是將window.replace改成history.replaceState
3.監聽地址變化
在HTML5History的構造函數中監聽popState(window.onpopstate)

兩種模式對比
History模式的優勢:
1.History模式的地址欄更美觀。。。
2.History模式的pushState、replaceState參數中的新URL可爲同源的任意URL(可爲不一樣的html文件),而hash只能是同一文檔
3.History模式的pushState、replaceState參數中的state可爲js對象,能攜帶更多數據
4.History模式的pushState、replaceState參數中的title能攜帶字符串數據(固然,部分瀏覽器,例如firefox不支持title,通常title設爲null,不建議使用)
缺點:
對於單頁面應用來講,理想的場景是僅僅在進入應用時加載頁面(例如index.html),後續的網絡操做靠ajax完成,
而不會從新請求頁面。
但當用戶直接在用戶欄輸入地址時則會從新請求,當地址帶有參數時二者狀況不同
Hash 例如: xxx.com/#/id=5 HTTP請求不會包含後面的hash值,因此請求的仍然是 xxx.com,沒有問題
History 例如: xxx.com/id=5 這時請求的即是xxx.com/id=5,如後端沒有配置對應id=XXX的路由處理,則會返回404錯誤。
二、怎麼定義vue-router的動態路由?怎麼獲取傳過來的動態參數?
在router目錄下的index.js文件中,對path屬性加上/:id。 使用router對象的params.id
三、vue-router有哪幾種導航鉤子?
三種,一種是全局導航鉤子:router.beforeEach(to,from,next),做用:跳轉前進行判斷攔截。第二種:組件內的鉤子;第三種:單獨路由獨享組件
四、vue-router是什麼?它有哪些組件?
vue用來寫路由一個插件。router-link、router-view
五、導航鉤子有哪些?它們有哪些參數?
導航鉤子有:a/全局鉤子和組件內獨享的鉤子。b/beforeRouteEnter、afterEnter、beforeRouterUpdate、beforeRouteLeave
參數:有to(去的那個路由)、from(離開的路由)、next(必定要用這個函數才能去到下一個路由,若是不用就攔截)最經常使用就這幾種
10、scss是什麼?安裝使用的步驟是?有哪幾大特性?
預處理css,把css當前函數編寫,定義變量,嵌套。 先裝css-loader、node-loader、sass-loader等加載器模塊,在webpack-base.config.js配置文件中加多一個拓展:extenstion,再加多一個模塊:module裏面test、loader
有哪幾大特性:
一、能夠用變量,例如($變量名稱=值);
二、能夠用混合器,例如()
三、能夠嵌套
11、vuex相關
一、vuex是什麼?怎麼使用?哪一種功能場景使用它?
vue框架中狀態管理。
在main.js引入store,注入。新建了一個目錄store,….. export 。
應用級的狀態集中放在store中; 改變狀態的方式是提交mutations,這是個同步的事物; 異步邏輯應該封裝在action中。
場景有:單頁應用中,組件之間的狀態。音樂播放、登陸狀態、加入購物車
二、vuex有哪幾種屬性?
有五種,分別是 State、 Getter、Mutation 、Action、 Module

三、vuex的State特性是?
1、Vuex就是一個倉庫,倉庫裏面放了不少對象。其中state就是數據源存放地,對應於與通常Vue對象裏面的data
2、state裏面存放的數據是響應式的,Vue組件從store中讀取數據,如果store中的數據發生改變,依賴這個數據的組件也會發生更新
3、它經過mapState把全局的 state 和 getters 映射到當前組件的 computed 計算屬性中

四、vuex的Getter特性是?
1、getters 能夠對State進行計算操做,它就是Store的計算屬性
2、 雖然在組件內也能夠作計算屬性,可是getters 能夠在多組件之間複用
3、 若是一個狀態只在一個組件內使用,是能夠不用getters

五、vuex的Mutation特性是?
1、Action 相似於 mutation,不一樣在於:
2、Action 提交的是 mutation,而不是直接變動狀態。
3、Action 能夠包含任意異步操做

六、Vue.js中ajax請求代碼應該寫在組件的methods中仍是vuex的actions中?
1、若是請求來的數據是否是要被其餘組件公用,僅僅在請求的組件內使用,就不須要放入vuex 的state裏。
2、若是被其餘地方複用,這個很大概率上是須要的,若是須要,請將請求放入action裏,方便複用,幷包裝成promise返回,在調用處用async await處理返回的數據。若是不要複用這個請求,那麼直接寫在vue文件裏很方便。

七、不用Vuex會帶來什麼問題?
1、可維護性會降低,你要想修改數據,你得維護三個地方
2、可讀性會降低,由於一個組件裏的數據,你根本就看不出來是從哪來的
3、增長耦合,大量的上傳派發,會讓耦合性大大的增長,原本Vue用Component就是爲了減小耦合,如今這麼用,和組件化的初衷相背。
12、生命週期相關
一、請詳細說下你對vue生命週期的理解?
總共分爲8個階段建立前/後,載入前/後,更新前/後,銷燬前/後。
建立前/後: 在beforeCreated階段,vue實例的掛載元素$el和數據對象data都爲undefined,還未初始化。在created階段,vue實例的數據對象data有了,$el尚未。
載入前/後:在beforeMount階段,vue實例的$el和data都初始化了,但仍是掛載以前爲虛擬的dom節點,data.message還未替換。在mounted階段,vue實例掛載完成,data.message成功渲染。
更新前/後:當data變化時,會觸發beforeUpdate和updated方法。
銷燬前/後:在執行destroy方法後,對data的改變不會再觸發周期函數,說明此時vue實例已經解除了事件監聽以及和dom的綁定,可是dom結構依然存在
二、什麼是vue生命週期?
Vue 實例從建立到銷燬的過程,就是生命週期。也就是從開始建立、初始化數據、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,咱們稱這是 Vue 的生命週期。
三、vue生命週期的做用是什麼?
它的生命週期中有多個事件鉤子,讓咱們在控制整個Vue實例的過程時更容易造成好的邏輯。

四、vue生命週期總共有幾個階段?
它能夠總共分爲8個階段:建立前/後, 載入前/後,更新前/後,銷燬前/銷燬後

五、第一次頁面加載會觸發哪幾個鉤子?
第一次頁面加載時會觸發 beforeCreate, created, beforeMount, mounted 這幾個鉤子

六、DOM 渲染在 哪一個週期中就已經完成?
DOM 渲染在 mounted 中就已經完成了。

七、簡單描述每一個週期具體適合哪些場景?
答:生命週期鉤子的一些使用方法: beforecreate : 能夠在這加個loading事件,在加載實例時觸發 created : 初始化完成時的事件寫在這裏,如在這結束loading事件,異步請求也適宜在這裏調用 mounted : 掛載元素,獲取到DOM節點 updated : 若是對數據統一處理,在這裏寫上相應函數 beforeDestroy : 能夠作一個確認中止事件的確認框 nextTick : 更新數據後當即操做dom
十3、請說下封裝 vue 組件的過程?
首先,組件能夠提高整個項目的開發效率。可以把頁面抽象成多個相對獨立的模塊,解決了咱們傳統項目開發:效率低、難維護、複用性等問題。
而後,使用Vue.extend方法建立一個組件,而後使用Vue.component方法註冊組件。子組件須要數據,能夠在props中接受定義。而子組件修改好數據後,想把數據傳遞給父組件。能夠採用emit方法。
十4、vue-loader是什麼?使用它的用途有哪些?
解析.vue文件的一個加載器,跟template/js/style轉換成js模塊。
用途:js能夠寫es六、style樣式能夠scss或less、template能夠加jade等
十5、你對Vue.js的template編譯的理解?
簡而言之,就是先轉化成AST樹,再獲得的render函數返回VNode(Vue的虛擬DOM節點)
詳情步驟:
首先,經過compile編譯器把template編譯成AST語法樹(abstract syntax tree 即 源代碼的抽象語法結構的樹狀表現形式),compile是createCompiler的返回值,createCompiler是用以建立編譯器的。另外compile還負責合併option。
而後,AST會通過generate(將AST語法樹轉化成render funtion字符串的過程)獲得render函數,render的返回值是VNode,VNode是Vue的虛擬DOM節點,裏面有(標籤名、子節點、文本等等)

React:
1、當你調用setState的時候,發生了什麼?
當調用 setState 時,React會作的第一件事情是將傳遞給 setState 的對象合併到組件的當前狀態。這將啓動一個稱爲和解(reconciliation)的過程。和解(reconciliation)的最終目標是以最有效的方式,根據這個新的狀態來更新UI。 爲此,React將構建一個新的 React 元素樹(您能夠將其視爲 UI 的對象表示)。
一旦有了這個樹,爲了弄清 UI 如何響應新的狀態而改變,React 會將這個新樹與上一個元素樹相比較( diff )。
經過這樣作, React 將會知道發生的確切變化,而且經過了解發生什麼變化,只需在絕對必要的狀況下進行更新便可最小化 UI 的佔用空間。
2、在 React 當中 Element 和 Component 有何區別?
簡單地說,一個 React element 描述了你想在屏幕上看到什麼。換個說法就是,一個 React element 是一些 UI 的對象表示。
一個 React Component 是一個函數或一個類,它能夠接受輸入並返回一個 React element t(一般是經過 JSX ,它被轉化成一個 createElement 調用)。
3、何時在功能組件( Class Component )上使用類組件( Functional Component )?
若是您的組件具備狀態( state )或生命週期方法,請使用 Class 組件。不然,使用功能組件
4、什麼是 React 的 refs ,爲何它們很重要?
refs就像是一個逃生艙口,容許您直接訪問DOM元素或組件實例。爲了使用它們,您能夠向組件添加一個 ref 屬性,該屬性的值是一個回調函數,它將接收底層的 DOM 元素或組件的已掛接實例,做爲其第一個參數。

class UnControlledForm extends Component {
handleSubmit = () => {
console.log("Input Value: ", this.input.value)
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
ref={(input) => this.input = input} />
<button type='submit'>Submit</button>
</form>
)
}
}

以上注意到咱們的輸入字段有一個 ref 屬性,其值是一個函數。該函數接收咱們而後放在實例上的實際的 DOM 元素,以便在 handleSubmit 函數內部訪問它。常常誤解的是,您須要使用類組件才能使用 ref ,但 ref 也能夠經過利用 JavaScript 中的 閉包 與 功能組件( functional components )一塊兒使用。

function CustomForm ({handleSubmit}) {
let inputElement
return (
<form onSubmit={() => handleSubmit(inputElement.value)}>
<input
type='text'
ref={(input) => inputElement = input} />
<button type='submit'>Submit</button>
</form>
)
}

5、React 中的keys是什麼,爲何它們很重要?
keys是什麼幫助 React 跟蹤哪些項目已更改、添加或從列表中刪除。

return (
<ul>
{this.state.todoItems.map(({task, uid}) => {
return <li key={uid}>{task}</li>
})}
</ul>
)
}

每一個 keys 在兄弟元素之間是獨一無二的。咱們已經談過幾回關於和解(reconciliation)的過程,並且這個和解過程(reconciliation)中的一部分正在執行一個新的元素樹與最前一個的差別。keys 使處理列表時更加高效,由於 React 可使用子元素上的 keys 快速知道元素是新的仍是在比較樹時才被移動。

並且 keys 不只使這個過程更有效率,並且沒有 keys ,React 不知道哪一個本地狀態對應於移動中的哪一個項目。因此當你 map 的時候,不要忽略了 keys 。
6、受控組件( controlled component )與不受控制的組件( uncontrolled component )有什麼區別?
React 的很大一部分是這樣的想法,即組件負責控制和管理本身的狀態。

當咱們將 native HTML 表單元素( input, select, textarea 等)投入到組合中時會發生什麼?咱們是否應該使用 React 做爲「單一的真理來源」,就像咱們習慣使用React同樣? 或者咱們是否容許表單數據存在 DOM 中,就像咱們習慣使用HTML表單元素同樣? 這兩個問題是受控(controlled) VS 不受控制(uncontrolled)組件的核心。

受控組件是React控制的組件,也是表單數據的惟一真理來源。

以下所示, username 不存在於 DOM 中,而是以咱們的組件狀態存在。每當咱們想要更新 username 時,咱們就像之前同樣調用setState。

class ControlledForm extends Component {
state = {
username: ''
}
updateUsername = (e) => {
this.setState({
username: e.target.value,
})
}
handleSubmit = () => {}
render () {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
value={this.state.username}
onChange={this.updateUsername} />
<button type='submit'>Submit</button>
</form>
)
}
}

不受控制( uncontrolled component )的組件是您的表單數據由 DOM 處理,而不是您的 React 組件。

咱們使用 refs 來完成這個。

class UnControlledForm extends Component {
handleSubmit = () => {
console.log("Input Value: ", this.input.value)
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<input
type='text'
ref={(input) => this.input = input} />
<button type='submit'>Submit</button>
</form>
)
}
}

雖然不受控制的組件一般更容易實現,由於您只需使用引用從DOM獲取值,可是一般建議您經過不受控制的組件來支持受控組件。

主要緣由是受控組件 支持即時字段驗證 ,容許您有條件地禁用/啓用按鈕,強制輸入格式
7、在哪一個生命週期事件中你會發出 AJAX 請求,爲何?

AJAX 請求應該在 componentDidMount 生命週期事件中。 有幾個緣由:

Fiber,是下一次實施React的和解算法,將有能力根據須要啓動和中止渲染,以得到性能優點。其中一個取捨之一是 componentWillMount ,而在其餘的生命週期事件中出發 AJAX 請求,將是具備 「非肯定性的」。 這意味着 React 能夠在須要時感受到不一樣的時間開始調用 componentWillMount。這顯然是AJAX請求的很差的方式。
-您不能保證在組件掛載以前,AJAX請求將沒法 resolve。若是這樣作,那意味着你會嘗試在一個未掛載的組件上設置 StState,這不只不會起做用,反而會對你大喊大叫。 在 componentDidMount 中執行 AJAX 將保證至少有一個要更新的組件。
8、shouldComponentUpdate 應該作什麼,爲何它很重要?
在生命週期方法 shouldComponentUpdate 中,容許咱們選擇退出某些組件(和他們的子組件)的 reconciliation 過程。

咱們爲何要這樣作?

如上所述,「和解( reconciliation )的最終目標是以最有效的方式,根據新的狀態更新用戶界面」。若是咱們知道咱們的用戶界面(UI)的某一部分不會改變,那麼沒有理由讓 React 很麻煩地試圖去弄清楚它是否應該渲染。經過從 shouldComponentUpdate 返回 false,React 將假定當前組件及其全部子組件將保持與當前組件相同。
9、您如何告訴React 構建(build)生產模式,該作什麼?
一般,您將使用Webpack的 DefinePlugin 方法將 NODE_ENV 設置爲 production。這將剝離像 propType 驗證和額外的警告。除此以外,還有一個好主意,能夠減小你的代碼,由於React使用 Uglify 的 dead-code 來消除開發代碼和註釋,這將大大減小你的包的大小。

爲何要使用 React.Children.map(props.children,()=>) 而不是 props.children.map(()=>)

由於不能保證props.children將是一個數組。

以此代碼爲例,

<Parent>
<h1>Welcome.</h1>
</Parent>
在父組件內部,若是咱們嘗試使用 props.children.map 映射孩子,則會拋出錯誤,由於 props.children 是一個對象,而不是一個數組。

若是有多個子元素,React 只會使props.children成爲一個數組。就像下面這樣:

<Parent>
<h1>Welcome.</h1>
<h2>props.children will now be an array</h2>
</Parent>
這就是爲何你喜歡 React.Children.map ,由於它的實現考慮到 props.children 多是一個數組或一個對象。
10、概述下 React 中的事件處理邏輯

爲了解決跨瀏覽器兼容性問題,React 會將瀏覽器原生事件(Browser Native Event)封裝爲合成事件(SyntheticEvent)傳入設置的事件處理器中。這裏的合成事件提供了與原生事件相同的接口,不過它們屏蔽了底層瀏覽器的細節差別,保證了行爲的一致性。另外有意思的是,React 並無直接將事件附着到子元素上,而是以單一事件監聽器的方式將全部的事件發送到頂層進行處理。這樣 React 在更新 DOM 的時候就不須要考慮如何去處理附着在 DOM 上的事件監聽器,最終達到優化性能的目的。
11、createElement 與 cloneElement 的區別是什麼?
createElement 函數是 JSX 編譯以後使用的建立 React Element 的函數,而 cloneElement 則是用於複製某個元素並傳入新的 Props。
12、傳入 setState 函數的第二個參數的做用是什麼?
該函數會在setState函數調用完成而且組件開始重渲染的時候被調用,咱們能夠用該函數來監聽渲染是否完成:

this.setState(
{ username: 'tylermcginnis33' },
() => console.log('setState has finished and the component has re-rendered.')
)
十3、react的優缺點
優勢:
能夠經過函數式方法描述視圖組件(好處:相同的輸入會獲得一樣的渲染結果,不會有反作用;組件不會被實例化,總體渲染性能獲得提高)集成虛擬DOM(性能好)
單向數據流(好處是更容易追蹤數據變化排查問題
一切都是component:代碼更加模塊化,重用代碼更容易,可維護性高
大量擁抱 es6 新特性
jsx
缺點:
jsx的一個問題是,渲染函數經常包含大量邏輯,最終看着更像是程序片斷,而不是視覺呈現。後期若是發生需求更改,維護起來工做量將是巨大的
大而全,上手有難度
十4、React:組件的生命週期
實例化
首次實例化

getDefaultProps
getInitialState
componentWillMount
render
componentDidMount
實例化完成後的更新

getInitialState
componentWillMount
render
componentDidMount
存在期
組件已存在時的狀態改變

componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate
render
componentDidUpdate
銷燬&清理期
componentWillUnmount
說明
生命週期共提供了10個不一樣的API。

1.getDefaultProps

做用於組件類,只調用一次,返回對象用於設置默認的props,對於引用值,會在實例中共享。

2.getInitialState

做用於組件的實例,在實例建立時調用一次,用於初始化每一個實例的state,此時能夠訪問this.props。

3.componentWillMount

在完成首次渲染以前調用,此時仍能夠修改組件的state。

4.render

必選的方法,建立虛擬DOM,該方法具備特殊的規則:

只能經過this.props和this.state訪問數據
能夠返回null、false或任何React組件
只能出現一個頂級組件(不能返回數組)
不能改變組件的狀態
不能修改DOM的輸出
5.componentDidMount

真實的DOM被渲染出來後調用,在該方法中可經過this.getDOMNode()訪問到真實的DOM元素。此時已可使用其餘類庫來操做這個DOM。

在服務端中,該方法不會被調用。

6.componentWillReceiveProps

組件接收到新的props時調用,並將其做爲參數nextProps使用,此時能夠更改組件props及state。

componentWillReceiveProps: function(nextProps) {
if (nextProps.bool) {
this.setState({
bool: true
});
}
}
7.shouldComponentUpdate

組件是否應當渲染新的props或state,返回false表示跳事後續的生命週期方法,一般不須要使用以免出現bug。在出現應用的瓶頸時,可經過該方法進行適當的優化。

在首次渲染期間或者調用了forceUpdate方法後,該方法不會被調用

8.componentWillUpdate

接收到新的props或者state後,進行渲染以前調用,此時不容許更新props或state。

9.componentDidUpdate

完成渲染新的props或者state後調用,此時能夠訪問到新的DOM元素。

10.componentWillUnmount

組件被移除以前被調用,能夠用於作一些清理工做,在componentDidMount方法中添加的全部任務都須要在該方法中撤銷,好比建立的定時器或添加的事件監聽器。
十5、React組件通訊
一、父組件向子組件通訊:使用 props
這是最簡單也是最經常使用的一種通訊方式:父組件經過向子組件傳遞 props,子組件獲得 props 後進行相應的處理。
二、子組件向父組件通訊:使用 props 回調
利用回調函數,能夠實現子組件向父組件通訊:父組件將一個函數做爲 props 傳遞給子組件,子組件調用該回調函數,即可以向父組件通訊。
三、跨級組件間通訊:使用 context 對象
所謂跨級組件通訊,就是父組件向子組件的子組件通訊,向更深層的子組件通訊。跨級組件通訊能夠採用下面兩種方式:

中間組件層層傳遞 props
使用 context 對象

對於第一種方式,若是父組件結構較深,那麼中間的每一層組件都要去傳遞 props,增長了複雜度,而且這些 props 並非這些中間組件本身所須要的。不過這種方式也是可行的,當組件層次在三層之內能夠採用這種方式,當組件嵌套過深時,採用這種方式就須要斟酌了。
使用 context 是另外一種可行的方式,context 至關於一個全局變量,是一個大容器,咱們能夠把要通訊的內容放在這個容器中,這樣一來,無論嵌套有多深,均可以隨意取用。

使用 context 也很簡單,須要知足兩個條件:

上級組件要聲明本身支持 context,並提供一個函數來返回相應的 context 對象
子組件要聲明本身須要使用 context

若是是父組件向子組件單向通訊,可使用變量,若是子組件想向父組件通訊,一樣能夠由父組件提供一個回調函數,供子組件調用,回傳參數。
在使用 context 時,有兩點須要注意:

父組件須要聲明本身支持 context,並提供 context 中屬性的 PropTypes
子組件須要聲明本身須要使用 context,並提供其須要使用的 context 屬性的 PropTypes
父組件需提供一個 getChildContext 函數,以返回一個初始的 context 對象
四、非嵌套組件間通訊:使用事件訂閱
非嵌套組件,就是沒有任何包含關係的組件,包括兄弟組件以及不在同一個父級中的非兄弟組件。對於非嵌套組件,能夠採用下面兩種方式:

利用兩者共同父組件的 context 對象進行通訊
使用自定義事件的方式

若是採用組件間共同的父級來進行中轉,會增長子組件和父組件之間的耦合度,若是組件層次較深的話,找到兩者公共的父組件不是一件容易的事
自定義事件是典型的發佈/訂閱模式,經過向事件對象上添加監聽器和觸發事件來實現組件間通訊。
十6、react中prop和state的區別?
須要理解的是,props是一個父組件傳遞給子組件的數據流,這個數據流能夠一直傳遞到子孫組件。而state表明的是一個組件內部自身的狀態(能夠是父組件、子孫組件)。
十7、redux的原理?Redux 把一個應用程序中,全部應用模塊之間須要共享訪問的數據,都應該放在 State 對象中。這個應用模塊多是指 React Components,也多是你本身訪問 AJAX API 的代理模塊,具體是什麼並無必定的限制。State 以 「樹形」 的方式保存應用程序的不一樣部分的數據。這些數據可能來自於網絡調用、本地數據庫查詢、甚至包括當前某個 UI 組件的臨時執行狀態(只要是須要被不一樣模塊訪問)

相關文章
相關標籤/搜索