Webpack
ESLint
CI(Continuous integration)
瀏覽器原理
- async 和 defer
- 一張圖:
Web Component
React
生命週期
- 一張圖:
- setState 爲何是異步的?
- 批量更新事務:
- batchingStrategy.isBatchingUpdates 和 batchingStrategy.batchedUpdates()
- react是經過合成事件實現了對於事件的綁定,當進入事件處理流程後,該事務的isBatchingUpdates爲true,若是在事件中調用setState方法,也會進入dirtyComponent流程。
- 若是咱們在瀏覽器的 click 句柄(handler)中,Child 和 Parent 都調用了 setState,則咱們不但願從新渲染 Child 兩次,而是傾向於將它們標記爲髒,而後在瀏覽器事件結束的時候從新渲染它們。
- 保證內部一致性:
- 使併發更新變得可行:React 能夠根據 setState() 來自的不一樣的位置:事件句柄,網絡響應,動畫等,來爲它們分配不一樣的優先級。
- 鉤子函數(函數組件不能使用這些方法,由於這須要繼承react Component這個類)
- constructor(props, context)
- getDefaultProps()
- 對於每一個組件實例來說,這個方法只會調用一次,該組件類的全部後續應用,getDefaultPops 將不會再被調用,其返回的對象能夠用於設置默認的 props值。
- getInitialState()
- 對於組件的每一個實例來講,這個方法的調用有且只有一次,用來初始化每一個實例的 state,在這個方法裏,能夠訪問組件的 props。
- getInitialState 和 getDefaultPops 的調用是有區別的,getDefaultPops 是對於組件類來講只調用一次,後續該類的使用都不會被調用,至關於 Object.prototype.XXX。而 getInitialState 是對於每一個組件實例來說都會調用,而且只調一次,至關於 this.XXX。
- componentWillMount()
- 在組件掛載到DOM前調用,且只會被調用一次,在這邊調用this.setState不會引發組件從新渲染,也能夠把寫在這邊的內容提早到constructor()中,因此項目中不多用。
- render()
- 根據組件的props和state(無二者的重傳遞和重賦值,論值是否有變化,均可以引發組件從新render) ,return 一個React元素(描述組件,即UI),不負責組件實際渲染工做,以後由React自身根據此元素去渲染出頁面DOM。render是純函數(Pure function:函數的返回結果只依賴於它的參數;函數執行過程裏面沒有反作用),不能在裏面執行this.setState,會有改變組件狀態的反作用。
- setState引發的state更新 或 父組件從新render引發的props更新,更新後的state和props相對以前不管是否有變化,都將引發子組件的從新render。可經過shouldComponentUpdate方法優化。
- componentDidMount()
- 組件掛載到DOM後調用,且只會被調用一次,這裏通常是發起異步請求,由於在componentWillMount裏發起AJAX,無論多快獲得結果也趕不上首次render。
- 該方法被調用時,已經渲染出真實的 DOM,能夠再該方法中經過 this.getDOMNode() 訪問到真實的 DOM(推薦使用 ReactDOM.findDOMNode())。
- componentWillReceiveProps(nextProps)
- 在此函數中調用 this.setState() 將不會引發第二次渲染。因此能夠把外部 props 轉換成本身的state,達到優化渲染的效果。
- shouldComponentUpdate(nextProps, nextState)
- componentWillUpdate(nextProps, nextState)
- 此方法在調用render方法前執行,在這邊可執行一些組件更新發生前的工做,通常較少用。
re- render() 從新調用
- componentDidUpdate(prevProps, prevState)
- 此方法在組件更新後被調用,能夠操做組件更新的DOM,prevProps和prevState這兩個參數指的是組件更新前的props和state
- componentWillUnmount()
- 此方法在組件被卸載前調用,能夠在這裏執行一些清理工做,好比清楚組件中使用的定時器,清楚componentDidMount中手動建立的DOM元素等,以免引發內存泄漏。
- 16版本新增生命週期
- static getDerivedStateFromProps(props, state)
- 在組件建立時和更新時的render方法以前調用,它應該返回一個對象來更新狀態,或者返回null來不更新任何內容。強制開發者在render以前只作無反作用的操做,並且能作的操做侷限在根據props和state決定新的state,而已。
- getSnapshotBeforeUpdate()
- 被調用於render以後,能夠讀取但沒法使用DOM的時候。它使您的組件能夠在可能更改以前從DOM捕獲一些信息(例如滾動位置)。今生命週期返回的任何值都將做爲參數傳遞給componentDidUpdate(prevProps, prevState, snapshot)
Context
- 解決嵌套組件自頂向下多層傳遞 props 和 state 的問題,this.context.XXX 能夠跨級傳遞數據。
- 生產者消費者模式
- 父組件是生產者,父組件必須用靜態屬性 childContextTypes 聲明提供給子組件的 Context 內容,並實現一個實例getChildContext方法,返回一個表明Context的純對象 (plain object)
- 子組件是消費者,子組件必須用靜態屬性 contextTypes 申請要消費的 Context 內容,以後才能經過 this.context.XXX 來訪問父組件提供的 Context 內容。
- 無狀態子組件
- 使用:ChildComponent = (props, context) => {console.log(context.propsA)};
- 聲明:ChildComponent.contextProps = { propA: PropTypes.string };
- React.createContext() 會建立一個 Context 對象(例如 TestContext)
<Provider />
:<TestContext.Provider value={{propsA: 'xxxxx'}} />
的value至關於的 getChildContext()
<Consumer />
:<TestContext.Consumer>{context => (<h1>{context.propsA}</h1>)}</TestContext.Consumer>
的children必須是一個函數,經過函數的參數獲取<Provider />
提供的Context。
- context 從哪來
- this.context
- constructor(props, context)
- componentWillReceiveProps(nextProps, nextContext)
- shouldComponentUpdate(nextProps, nextState, nextContext)
- componetWillUpdate(nextProps, nextState, nextContext)
- 無狀態函數式組件 ChildComponent = (props, context) => {console.log(context.propsA)};
- 爲何要用父聲明子申請的設計
- 父子組件是一對多的線性依賴。隨意的使用Context其實會破壞這種依賴關係,致使組件之間一些沒必要要的額外依賴,下降組件的複用性,進而可能會影響到App的可維護性。經過childContextTypes和contextTypes這兩個靜態屬性的約束,能夠在必定程度保障,只有組件自身,或者是與組件相關的其餘子組件才能夠爲所欲爲的訪問Context的屬性,不管是數據仍是函數。
JSX
React-Router
Redux
數據流
- 一張圖:
- Store > subscribe > Component > trigger >Action > dispatch > Reducer > put > Store
Reducer
- 一個純函數,執行一個action而且返回一個新的狀態。
- 入參是state 和 action
- state是當前保存在store中的數據,初始時無值須要入參處指定初始值。
- action至關於一個容器,有兩個 key
- type - 一個簡單的字符串常量,例如ADD, UPDATE, DELETE等。
- payload - 用於更新state的數據。
- 代碼設計上不該該在reducer裏用 if-else/switch 來取針對不一樣的 action.type作業務處理,service code 不該該寫在這一層,應該用 myActionsaction.type 解耦。dva就是作了這件事,把 action處理單獨抽出來
- 多個 reducer 的場景:
let store = redux.createStore(redux.combineReducers({reducer1, reducer2}));
- Action觸發流:
- 抽離的 action 方法是接收 payload,組裝並返回一個 action 容器,例如
function action1(data1, data2) {return {type: 'ACTION_1', payload: {data1, data2}}};
- 用 store.dispatch()去分發這個 action:如
store.dispatch(action1('data_1', 'data_2'));
- reducer接收到相應的 action 開始處理:如
reducer1(state, action){ if(action.type === 'ACTION_1'){return {...state, ...action.payload}};
- Immutability(不可變性)
- 若是代碼只處理原始數據類型(numbers, strings, booleans),那麼你不用擔憂。可是,若是在處理Arrays和Objects時,則須要當心執行可變操做。不可變操做實現有 immutable.js/Object.assign()/{...Obj}
- immutable.js
- React 結合
- react-redux
- 用 Provider 包起來
ReactDOM.render(<Provider store={store}> <h1>xxx</h1></Provider>, document.getElementById('root'));
- 異步數據處理
- Redux自己只能處理同步的Action,但能夠經過中間件來攔截處理其它類型的action,好比 Thunk 函數,再用回調觸發普通Action,從而實現異步處理,在這點上全部Redux的異步方案都是相似的。
- 概念
- 模塊
- redux-thunk
- redux-promise
- redux-loop
- redux-saga
- redux-observable
- redux-action-tools
Diff
Vue
生命週期
- 一張圖:
- 鉤子函數(Vue的全部生命週期函數都是自動綁定到this的上下文上,因此箭頭函數會報錯)
-
beforeCreatehtml
-
createdvue
-
el 和 template 過程參與node
- 實例沒有指定 el 屬性時就不會觸發下面的 beforeMount 和 mounted,能夠用$mount 方法手動掛載 el,生命週期方法會按序觸發。
- render函數 > template屬性 > 外部html, vue 的編譯過程就是把tempalte編譯成render函數的過程。
-
beforeMountreact
-
mountednginx
-
beforeUpdate編程
- 這裏的數據只有和模版中的數據綁定了纔會發生更新,纔會調用 berforeUpdate 和 updated 這兩個鉤子。
-
updatedredux
-
beforeDestroy數組
- 在 beforeDestroy 生命鉤子調用以前,全部實例均可以用,可是當調用後,Vue 實例的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。
-
destroyedpromise
-
其餘鉤子瀏覽器
- activated:當組件激活的時候調用
- deactivated:當組件停用的時候調用
- errorCaptured:這個生命鉤子能夠看官網,2.5.0以後纔有的。當捕獲一個來自子孫組件的錯誤時被調用。
自帶屬性方法
- data = $data
- 在定義一個組件時,data 必須聲明爲一個返回初始數據對象的無反作用的函數,由於可能會使用此函數建立多個實例。若是 data 是一個普通對象,則全部建立出來的實例將共享引用同一個數據對象!
- data: (vm) => ({x: vm.myProp});
指令
- v-text = textContent
- v-html = innerHtml
- v-bind:href = :href
- 做用:當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM
- 語法:v-bind:href="url"
- 簡寫::href="url"
- 說明:綁定的數據從 data 或 props中獲取
- v-on:click = @click
- 做用:綁定事件
- 語法:v-on:click="say" or v-on:click="say('參數', $event)"
- 簡寫:@click="say"
- 說明:綁定的事件從methods中獲取
- 事件修飾符 *
v-on:click.stop="say"
阻止冒泡,調用 event.stopPropagation()
v-on:click.prevent
阻止默認事件,調用 event.preventDefault()
v-on:click.capture="say"
添加事件偵聽器時使用事件捕獲模式
v-on:click.self="say"
只當事件在該元素自己(好比不是子元素)觸發時觸發回調
- v-on:click.once="say" 事件只觸發一次
- 順序很重要:
v-on:click.prevent.self
會阻止全部的點擊,而 v-on:click.self.prevent
只會阻止對元素自身的點擊。
- v-model
- 做用:在表單元素上建立雙向數據綁定
- 說明:監聽用戶的輸入事件以更新數據
- demo:
<input v-model="message" placeholder="edit me"><p>Message is: {{ message }}</p>
- v-for
- item 爲值,key 爲鍵,index 爲索引
- demo:
<p v-for="(item, key, index) in obj" :key="item.key">{{item}} -- {{key}}</p>
- 性能:使用 key,VUE會基於 key 的變化從新排列元素順序,而且會移除 key 不存在的元素。
- 樣式處理 v-bind
- :class="[{active: true}, 'warning', errorClass]"
- :style="[{fontSize: fs + 'px'}, baseStyle, overridingStyles]"
- v-if: 根據表達式的值的真假條件,銷燬或重建元素
- v-show: 根據表達式之真假值,切換元素的 display CSS 屬性
- 性能和體驗
- v-cloak: 這個指令保持在元素上直到關聯實例結束編譯。
- 防止未編譯的 Mustache 模板數據出如今頁面上。
- CSS 樣式
[v-cloak] { display: none }
能夠在實例 ready 前隱藏未編譯的 Mustache 標籤。
- v-pre: 跳過這個元素和它的子元素的編譯過程。能夠用來顯示原始 Mustache 標籤,跳過大量沒有指令的節點會加快編譯。
- v-once: 只渲染元素和組件一次。隨後的從新渲染,元素/組件及其全部的子節點將被視爲靜態內容並跳過。這能夠用於優化更新性能。
- 自定義指令
- 全局註冊
- 註冊方法:
Vue.directive( directiveName, [definition] )
- demo:
<div id="app" class="demo">
<!-- 全局註冊 -->
<input type="text" v-focus>
</div>
<script>
Vue.directive("focus", {
inserted: function(el){
el.focus();
}
})
new Vue({
el: "#app"
})
</script>
複製代碼
- 局部註冊
- 註冊方法:在Vue實例中添加 directives 對象
- demo:
<div id="app" class="demo">
<!-- 局部註冊 -->
<input type="text" v-focus2>
</div>
<script>
new Vue({
el: "#app",
directives: {
focus2: {
inserted: function(el){
el.focus();
}
}
}
})
</script>
複製代碼
- 自定義指令的鉤子函數
bind(el, binding, vnode)
:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
inserted(el, binding, vnode)
:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。
update(el, binding, vnode, oldVnode)
:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新。
componentUpdated(el, binding, vnode, oldVnode)
:指令所在組件的 VNode 及其子 VNode 所有更新後調用。
unbind(el, binding, vnode)
:只調用一次,指令與元素解綁時調用。
Vue-Router
VueX
Node
EventLoop
- 一張圖:
- Timer(setTimeout/setInterval) --tick-- I/O --tick-- Check(setImmediate)
- macrotasks: setTimeout setInterval setImmediate I/O UI渲染
- microtasks: Promise process.nextTick Object.observe MutationObserver
- 一個有趣的例子:process.nextTick是註冊在當前的tick階段進行拼接,繼續執行,從而致使了死循環
process.nextTick(function tick () {
process.nextTick(tick)
});
複製代碼
函數式編程
柯里化
function realSum(...args) {
return args.reduce((prev, next) => prev + next, 0);
}
function sum(...args1) {
let value = realSum(...args1);
function fn(...args2) {
value += realSum(...args2)
return fn
};
fn.valueOf = () => value;
return fn;
}
sum(1,2)(3)(4)(2,3).valueOf(); // 15
複製代碼
尋找對稱數
function findSymmetricNum(min, max) {
let num = min;
let temp = '';
const result = [];
for(let i=0; i< max-min+1;i++) {
temp = num + '';
// 字符串反轉後是否與以前相等
if(temp.split('').reverse().join('') === temp) {
result.push(num);
}
num ++;
}
return result;
};
複製代碼
異步鏈式調用
複製代碼
Sass
Less
HTTP
原理
HTTP2
長連接複用
數據 chunk 方式通訊
CDN
- 查找鏈路
- 一張圖:
- 客戶端 -> ( * CNAME:把自有域名換成 cdn 域名) -> DNS查詢 -> 全局負載均衡系統 -> (透傳客戶端 IP 和目標資源 URL) -> 區域負載均衡系統 ->(根據客戶端 IP 和目標資源 URL,獲取距離客戶端最近且有相應資源的cdn 緩存服務器的地址) -> 全局負載均衡系統 -> (cdn 緩存服務器地址)-> 客戶端 -> (請求緩存服務器上的文件)
- 回源
- 當 cdn 緩存服務器中沒有符合客戶端要求的資源的時候,緩存服務器會請求上一級緩存服務器,以此類推,直到獲取到。最後若是仍是沒有,就會回到咱們本身的服務器去獲取資源。沒有資源,資源過時,訪問的資源是不緩存資源等都會致使回源。
- 更新數據
DNS
-
一張圖
-
查找方式
- 遞歸查詢:遞歸查詢是一種DNS 服務器的查詢模式,在該模式下DNS 服務器接收到客戶機請求,必須使用一個準確的查詢結果回覆客戶機。若是DNS 服務器本地沒有存儲查詢DNS 信息,那麼該服務器會詢問其餘服務器,並將返回的查詢結果提交給客戶機。
- 迭代查詢:DNS 服務器會向客戶機提供其餘可以解析查詢請求的DNS 服務器地址,當客戶機發送查詢請求時,DNS 服務器並不直接回複查詢結果,而是返回客戶機另外一臺DNS 服務器地址,客戶機再向這臺DNS 服務器提交請求,依次循環直到返回查詢的結果爲止。
-
多域名查詢優化
TypeScript
Node
多進程開發
nginx 原理
PM2
反模式