2020秋招前端面經知識點彙總(二)

接上篇,這裏繼續知識點的總結javascript

Vue部分:

Vue和Jquery相比的優缺點:

  • Vue適用的場景:複雜數據操做的後臺頁面,表單填寫及驗證頁面;
  • Vue側重數據綁定;(框架)
  • jQuery適用的場景:html5的動畫頁面,須要js來操做頁面樣式的頁面;
  • jQuery側重樣式操做以及動畫效果等。(類庫)

Vue和React的區別:

  1. 監聽數據變化的實現原理不一樣:

Vue經過getter/setter以及數據劫持來實現監聽數據的變化 React則是經過比較引用(diff算法)來實現,若是不優化可能致使大量沒必要要的VDOM的從新渲染。 二者設計理念不一樣,Vue使用的是可變的數據,React則強調數據的不可變,Vue更加簡單,React構建大型應用的時候更加魯棒。 2. 數據流向不一樣
Vue2.0中組件與DOM能夠經過v-model雙向綁定,2.0中再也不支持父子組件之間經過props雙向綁定,不鼓勵組件對props進行修改,會警告。 React提倡單向數據流,使用Redux進行數據流狀態管理 3. 組件間的通訊方式不一樣
Vue的組件通訊由三種方式:父組件經過props向子組件傳遞數據或者回到,子組件經過事件想父組件傳遞消息,經過2.2.0中新增的provide/inject實現父組件向子組件注入數據,能夠跨越多個層級。 React的組件通訊有三種方式:父組件經過props能夠向子組件傳遞數據或者回調,能夠經過context進行跨層級的通訊,這其實和provide/inject起到的做用差很少,React自己不支持自定義時間,React中子組件向父組件傳遞消息使用回調函數。 4. 模板渲染方式不一樣
React經過JSX渲染模板,Vue經過拓展的HTML語法進行渲染。 React是在組件的js代碼中,經過原生js來實現模板中的常見語法,好比插值,條件,循環等等,更加純粹原生,而Vue是在和組件js代碼分離的單獨的模板中經過指令來實現的。 5. 渲染過程不一樣
Vue能夠更快計算出虛擬DOM的差別,由於渲染過程當中,Vue會收集依賴,而後根據註冊的組件渲染對應的DOM,不須要從新渲染每個組件 React在應用的狀態改變時,所有子組件都會從新渲染。 6. 框架本質不一樣
Vue本質是MVVM框架,由MVC發展而來; React是前端組件化框架,由後端組件化發展而來。 7. Vuex和Redux的區別
Redux使用的是不可變數據,而Vuex的數據是可變的,所以,Redux每次都是用新state替換舊state,而Vuex是直接修改。Redux在檢測數據變化的時候,是經過diff的方式比較差別的,而Vuex其實和Vue的原理同樣,是經過getter/setter來比較的,這兩點的區別,也是由於React和Vue的設計理念不一樣。React更偏向於構建穩定大型的應用,很是的科班化。相比之下,Vue更偏向於簡單迅速的解決問題,更靈活,不那麼嚴格遵循條條框框。css

組件間的通訊:

父組件向子組件傳值總結:

  1. 子組件在props中建立一個屬性,用以接收父組件傳過來的值
  2. 父組件中註冊子組件
  3. 在子組件標籤中添加子組件props中建立的屬性
  4. 把須要傳給子組件的值賦給該屬性

子組件向父組件傳值總結:

  1. 子組件中須要以某種方式例如點擊事件的方法來觸發一個自定義事件
  2. 將須要傳的值做爲$emit的第二個參數,該值將做爲實參傳給響應自定義事件的方法
  3. 在父組件中註冊子組件並在子組件標籤上綁定對自定義事件的監聽

在通訊中,不管是子組件向父組件傳值仍是父組件向子組件傳值,他們都有一個共同點就是有中間介質,子向父的介質是自定義事件,父向子的介質是props中的屬性。抓準這兩點對於父子通訊就好理解了html

vue兄弟組件之間的傳值:

  1. 建立一個事件總線,例如demo中的eventBus.js,new一個vue對象並向外暴露,用它做爲通訊橋樑

2.在須要傳值的組件中引入eventBus.js,用bus.$emit觸發一個自定義事件,並傳遞參數 3. 在須要接收數據的組件中引入eventBus.js,在mounted() 鉤子函數(掛載實例) 中用bus.$on監聽自定義事件,並在回調函數中處理傳遞過來的參數前端

Vue經常使用指令

  • v-once:能執行一次性地插值,當數據改變時,插值處的內容不會更新。
  • v-show:和v-if同樣,區別是if是將代碼註釋掉,v-show是給一個display:none的屬性 讓它不顯示。v-if 有更高的切換消耗而 v-show 有更高的初始渲染消耗。所以,若是須要頻繁切換使用 v-show 較好,若是在運行時條件不大可能改變則使用 v-if 較好。
  • v-for:基於數據渲染一個列表,相似於JS中的遍歷。其數據類型能夠是 Array | Object | number | string。
  • v-html:雙大括號會將數據解釋爲普通文本,而非HTML 代碼。爲了輸出真正的 HTML,你須要使用 v-html 並且給一個標籤加了v-html 裏面包含的標籤都會被覆蓋。
  • v-text:給一個便籤加了v-text 會覆蓋標籤內部原先的內容
  • v-bind:動態屬性綁定,縮寫:
  • v-on:動態事件綁定,縮寫@
  • v-model:雙向數據綁定,限制在<input><select><textarea>components中使用

Vue的自定義指令

在組件中定義自定義指令,使用directives屬性 全局自定義指定 鉤子函數
一個指令定義對象能夠提供以下幾個鉤子函數 (均爲可選):
vue

  • inserted:被綁定元素插入父節點時調用 (僅保證父節點存在,但不必定已被插入文檔中)。
  • bind:只調用一次,指令第一次綁定到元素時調用。在這裏能夠進行一次性的初始化設置。
  • update:所在組件的 VNode 更新時調用,可是可能發生在其子 VNode 更新以前。指令的值可能發生了改變,也可能沒有。可是你能夠經過比較更新先後的值來忽略沒必要要的模板更新 (詳細的鉤子函數參數見下)。
  • componentUpdated:指令所在組件的 VNode 及其子 VNode 所有更新後調用。
  • unbind:只調用一次,指令與元素解綁時調用。

指令鉤子函數會被傳入如下參數:
html5

  • el:指令所綁定的元素,能夠用來直接操做 DOM 。
  • binding:一個對象,包含如下屬性:
  • name:指令名,不包括 v- 前綴。
  • value:指令的綁定值,例如:v-my-directive=「1 + 1」 中,綁定值爲 2。
  • oldValue:指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。不管值是否改變均可用。
  • expression:字符串形式的指令表達式。例如 v-my-directive=「1 + 1」 中,表達式爲 「1 + 1」。
  • arg:傳給指令的參數,可選。例如 v-my-directive:foo 中,參數爲 「foo」。
  • modifiers:一個包含修飾符的對象。例如:v-my-directive.foo.bar 中,修飾符對象爲 { foo: true, bar: true }。
  • vnode: Vue編譯生成的虛擬節點。移步 VNode API 來了解更多詳情。
  • oldVnode:上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。

Vue的生命週期

一個組件從開始到最後消亡所經歷的各類狀態,就是一個組件的生命週期
java

  • beforeCreate()

說明:在實例初始化以後,數據觀測 (data observer) 和 event/watcher 事件配置以前被調用
注意:此時,沒法獲取 data中的數據、methods中的方法
node

  • created()

說明:這是一個經常使用的生命週期,能夠調用methods中的方法、改變data中的數據
react

  • beforeMounted()

說明:在掛載開始以前被調用,此時沒法獲取到el中的DOM元素
webpack

  • mounted()

說明:此時,vue實例已經掛載到頁面中,能夠獲取到el中的DOM元素,進行DOM操做

  • beforeUpdated()

說明:數據更新時調用,發生在虛擬 DOM 從新渲染和打補丁以前。你能夠在這個鉤子中進一步地更改狀態,這不會觸發附加的重渲染過程。
注意:此處獲取的數據是更新後的數據,可是獲取頁面中的DOM元素是更新以前的

  • updated()

說明:組件 DOM 已經更新,因此你如今能夠執行依賴於 DOM 的操做

  • beforeDestroy()

說明:實例銷燬以前調用。在這一步,實例仍然徹底可用。
使用場景:實例銷燬以前,執行清理任務,好比:清除定時器等

  • destroyed()

說明:Vue 實例銷燬後調用。調用後,Vue 實例指示的全部東西都會解綁定,全部的事件監聽器會被移除,全部的子實例也會被銷燬。

Vue父子組件生命週期執行順序

  • 加載渲染過程

父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

  • 子組件更新過程

父beforeUpdate->子beforeUpdate->子updated->父updated

  • 父組件更新過程

父beforeUpdate->父updated

  • 銷燬過程

父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

Vuex是什麼?怎麼使用?那種功能場景使用它

只要來讀取的狀態集中放在store中;改變狀態的方式就是提交mutations。這是個同步的實物;異步邏輯應該封裝中action中。

  • state:Vuex 使用單一狀態樹,既每一個應用將僅僅包含一個store實例,單單一狀態樹和模塊化並不衝突。存放的數據狀態,不能夠直接修改裏面的數據。能夠經過this.$store.state調用state中的參數。
  • mutations:mutations定義的方法動態修改Vuex的store中的狀態或數據。Mutatison中必須是同步函數。能夠經過this.$store.commit('increment',args)來調用並更改state中的參數狀態
  • getters:相似vue的計算屬性,主要用來過濾一些數據。
  • action:action能夠理解爲經過mutations裏面處理數據的方法變成可異步的處理數據的方法,簡單的說就是異步操做數據。經過this.$store.dispatch('increment')來調用action方法。Action提交的是mutation,而不是直接改變裝填,action能夠包含異步操做

Modeules:項目特別複雜的時候,可讓每個模塊擁有本身的state,mutation,action,getters,使得結構很是清晰,方便管理

Vuex中的數據流向:

  1. vue組件先調用dispatch 來觸發Actions作些異步處理或批量的同步操做,緊接着Actions經過提交commit來調用Mutations , Mutations 中放的是一個一個同步的對state的修改,只有經過mutations才能改變公用數據的值。最後經過this.$store.state.id的方法將值映射到頁面上。
  2. 若是邏輯簡單,vue 組件也能夠略過actions, 讓組件直接調用mutations來修改state的公用數據的值

vue-router的概念與使用:

vue-router路由管理器

vue router和vue.js的核心深度集成,能夠方便的用於spa的應用程序開發
它的功能有:
支持HTML5 history模式,和hash模式;支持嵌套路由;支持路由參數,支持編程式路由,支持命名路由。
路由的進階,導航守衛,路由元信息,過渡效果,數據獲取,滾動行爲,路由懶加載。

vue-router的基本使用

基本使用步驟:

  • 第一步,引入相關的庫文件,<script src="./lib/vue-routerxxx.js"></script>
  • 第二步,添加路由鏈接,<router-link to="/user">User</router-link>
  • 第三步,添加路由填充位,<router-view></router-view>
  • 第四步,定義路由組件,var User = {template: '<div>user</div>'}
  • 第五步,配置路由規則並建立路由實例,

路由重定向

路由重定向值的是,用戶在訪問地址a的時候,強制用戶跳轉到地址c,從而展現特定的組件頁面,經過路由規則的redirect屬性,指定一個新的路由地址,能夠方便地設置路由的重定向。

var router = new VueRouter({
 routers: [
  // 其中,path表示須要被重定向的原地址,redirect表示將要被重定向的新地址
  {path;'/', redirect: '/user'},
  {path:'/user', component: User},
  {path:'/register', component:Register}
 }
})
複製代碼

vue-router動態路由匹配(傳參)

什麼是動態路由匹配,爲啥要動態路由匹配?即經過路由傳參。
路由傳參的三種方式:

  1. 直接調用$router.push 實現攜帶參數的跳轉

很顯然,須要在path中添加/:id來對應 $router.push 中path攜帶的參數。在子組件中可使用來獲取傳遞的參數值。

getDescribe(id) {
  this.$router.push({
    path: `/describe/${id}`,
})
{
  path: '/describe/:id',
  name: 'Describe',
  component: Describe
}
//對應子組件: 這樣來獲取參數 this.$route.params.id
複製代碼
  1. 父組件中:經過路由屬性中的name來肯定匹配的路由,經過params來傳遞參數。
this.$router.push({
   name: 'Describe',
   params: {
     id: id
   }
 })
{
  path: '/describe',
  name: 'Describe',
  component: Describe
}
//對應子組件: 這樣來獲取參數 this.$route.params.id
複製代碼
  1. 父組件:使用path來匹配路由,而後經過query來傳遞參數,這種狀況下 query傳遞的參數會顯示在url後面?id=?
this.$router.push({
         path: '/describe',
         query: {
           id: id
         }
       })
//對應子組件: 這樣來獲取參數 this.$route.query.id
複製代碼

什麼叫作命名路由

路由的name能夠指定命名名稱,不用寫path。命名路由的配置規則

// 路由導航
const router = new VueRouter({
 routes: [
  {
   path: '/user/id',
   name: 'user',
   component: User
  }
 ]
})
<router-link :to="{name:'user', params: {id:1} }">dada</router-link>
router.push({name:'user', params: {id:1} }}
複製代碼

vue-router 路由導航守衛

  • 全局守衛

使用router.beforeEach 註冊一個全局的路由守衛
當一個導航守衛觸發時,全局前置守衛按照建立順序調用,守衛是異步解析執行,此時導航在全部守衛resolve完成以前一直處於等待狀態中
全局後置鉤子 router.afterEach((to,from)=){})
全局後置鉤子就是在路由跳轉以後執行的鉤子函數
頁面獨享的守衛
以下能夠在路由的配置上面定義beforeEnter()

  • 組件內的守衛

經過meta屬性實現要監聽的路由元信息

  • 設置頁面是否被緩存

鉤子函數的執行順序

  • 不使用keep-alive

beforeRouteEnter --> created --> mounted --> destroyed

  • 使用keep-alive

beforeRouteEnter --> created --> mounted --> activated --> deactivated
再次進入緩存的頁面,只會觸發beforeRouteEnter -->activated --> deactivated 。created和mounted不會再執行。由於這個頁面須要緩存。只有第一次進入時纔會執行created和mounted方法,再次進入就不執行了。而activated每次進入都執行,因此在這個鉤子函數中獲取數據。

Vue-router中的兩種導航模式

  1. hash模式。

#後面的hash的變化,不會致使瀏覽器向服務器發送請求,瀏覽器不發出請求,也就不會刷新頁面,每次hash值的變化,會觸發hashchange這個時間,經過這個時間咱們能夠知道hash值發生了什麼變化,能夠監聽hashchange來實現更新頁面部份內容的操做,這就是前端路由的實現原理。 並且hash發生變化的url會被瀏覽器記錄下來,因此瀏覽器的前進後退等功能均可以用了。頁面狀態和url關聯起來
特色:hash值雖然出如今url中,可是不會被包括在http請求中,對後端徹底沒有影響,因此改變hash不會重現加載頁面
2. History模式
Url以/分割,單頁面沒有跳轉,這種模式須要服務端支持,服務端在接收到全部請求後,都指向同一個html文件,否則404,單頁面應用只有一個html,整個網站的內容都在html中,由於咱們的應用是個單頁客戶端應用,若是後臺沒有正確的配置,當用戶在瀏覽器直接訪問www.yongcun.wang/tclass就會返回 404,這就很差看了。這須要在後臺配置匹配不到資源的時候返回主頁面。
History模式利用了html5中新增的pushState()和replaceState()方法,這兩個方法能夠改變url且不會發送請求,不只能夠讀取歷史記錄棧,還能夠對瀏覽器的歷史記錄棧進行修改,以上兩個方法用於修改歷史狀態,還有back,froward,go三個方法用來切換歷史狀態。

Vue默認使用hash模式,能夠設置成history模式
區別:
hashchange,你只能改變#後面的url片斷。而pushState設置的新URL能夠是與當前URL同源的任意URL
history模式則會將URL修改得就和正常請求後端的URL同樣,如後端沒有配置對應/user/id的路由處理,則會返回404錯誤

r o u t e r router與 route的區別

  1. r o u t e 能夠從當前的 r o u t e r 跳轉對象中獲取 n a m e p a t h q u e r y p a r a m s 等。例如使用 t h i s . route能夠從當前的router跳轉對象中獲取name,path,query,params等。例如使用`this. route.querythis.$route.params獲取`中的動態參數
  2. r o u t e r V u e R o u t e r 實例,想要導航到不一樣的 U R L 。則要使用 router爲VueRouter實例,想要導航到不一樣的URL。則要使用` router.push(url)方法,返回上一個history也要使用$router.go(-1)`方法

MVVM和MVC

Vue 最獨特的特性

  • MVVM是model-view-viewmodel的縮寫
  • Model表明數據模型,能夠在model中定義數據的修改和操做的業務邏輯
  • View表明UI組件,負責將數據模型轉化成UI展現出來
  • ViewModel監聽模型數據的改變和控制視圖行爲,處理用戶交互,簡單理解就是一個同步View和Model的對象。
  • 在MVVM架構下,model和view並無直接的聯繫,而是經過VIewModel進行交互,model和viewmodel之間的交互是雙向的,所以view的數據變化會同步到model中,而model的數據變化也會反映到view上

觀察者模式與發佈訂閱模式

觀察者模式:

定義了對象間一種一對多的關係,當目標對象Subject的狀態發生改變時,全部依賴他的對象observer都會獲得通知
模式特徵:

  • 一個目標者對象Subject,擁有方法:添加/刪除/通知Observer
  • 對個觀察者對象Observer,擁有方法:接收Subject狀態變動通知並處理
  • 目標對象Subject狀態變動時,通知全部Observer
  • Subject添加一系列Observer,Subject負責維護這些Observer之間的聯繫。

優勢:目標者與觀察者,功能上的關聯性下降,專一自身的功能邏輯,觀察者被動接收更新,時間上的關聯性下降,實時接收目標更新狀態
缺點:觀察者模式雖然減小了對象間的依賴關係,但卻不能對事件通知進行細分管控,如篩選通知,指定主題事件通知。

發佈訂閱模式:

  • 基於一個事件通道,但願接收通知的對象Subscriber經過各自定義一個事件來訂閱對應的主題,被激活事件的對象Publisher經過發佈主題事件的方式通知各個訂閱該主題的Subscriber對象。
  • 發佈訂閱模式與觀察者模式不一樣,存在事件中心這個模塊,目標對象的變化不是直接通知觀察者,而是經過事件中心來對訂閱了該對象的觀察進行通知派發,並且要先訂閱後發佈時纔會通知。

觀察者模式是爲了實現對象間的解耦,是鬆耦合的,而發佈訂閱模式則是徹底解耦的。

Vue2.0雙向數據綁定的原理

Vue 最獨特的特性之一,是其非侵入性的響應式系統。數據模型僅僅是普通的 JavaScript 對象。而當你修改它們時,視圖會進行更新。 那麼,Vue是如何實現的呢?
vue.js 則是採用數據劫持結合發佈者-訂閱者模式的方式,經過Object.defineProperty()來劫持各個屬性的setter,getter,在數據變更時發佈消息給訂閱者,觸發相應的監聽回調。當把一個普通的js對象傳給vue實例來做爲它的data選項時,vue將遍歷它的屬性,用object.defineproperty()將它們轉化爲getter/setter,用戶看不到getter/setter,可是內部它們讓vue追蹤依賴,並在屬性被訪問和修改時通知變化
總體思路 經過Object.defineProperty()來實現對屬性的劫持,達到監聽數據變更的目的
要實現mvvm的雙向綁定,就必需要實現如下幾點:

  1. 實現一個數據監聽器Observer,可以對數據對象的全部屬性進行監聽,若有變更可拿到最新值並通知訂閱者
  2. 實現一個指令解析器Compile,對每一個元素節點的指令進行掃描和解析,根據指令模板替換數據,以及綁定相應的更新函數
  3. 實現一個Watcher,做爲鏈接Observer和Compile的橋樑,可以訂閱並收到每一個屬性變更的通知,執行指令綁定的相應回調函數,從而更新視圖
  4. mvvm入口函數,整合以上三者

Vue響應式原理

總共分爲三步驟:

  1. init 階段: Vue 的 data的屬性都會被reactive化,也就是加上 setter/getter函數。其中這裏的Dep就是一個觀察者類,至關於發佈訂閱模式中的事件中心這個模塊,每個data的屬性都會有一個dep對象。當getter調用的時候,去dep裏註冊函數。setter的時候,就是去通知執行剛剛註冊的函數。
  2. mount 階段:mount 階段的時候,會建立一個Watcher類的對象。這個Watcher其實是鏈接Vue組件與Dep的橋樑。每個Watcher對應一個vue component。

new watcher的時候會在watch中生成一個updateComponent函數,這個函數會調用render函數來從新渲染對應的component。
當render一個vue組件的時候,若是這個組件用到了某個屬性title,那麼這個組件對應的watcher對象會被註冊到這個屬性title的dep對象中,這就是收集依賴,收集完屬性全部的依賴組件以後,當這個屬性title發生改變以後,就會找到dep中註冊過的全部的watcher對象,通知他們執行updateComponent函數來更新對應的組件
在組件更新的時候,render函數裏,會訪問他所依賴的data的getter函數。
3. 更新階段:
當某個屬性title發生改變的時候,就去調用Dep的notify函數,而後通知全部的Watcher調用updateComponent函數更新。
總結
第一步:組件初始化的時候,先給每個data屬性都註冊getter,setter,也就是reactive化。而後再new 一個本身的Watcher對象,此時watcher會當即調用組件的render函數去生成虛擬DOM。在調用render的時候,就會須要用到data的屬性值,此時會觸發getter函數,將當前的Watcher函數註冊進dep裏。
第二步:當data屬性發生改變以後,就會遍歷dep裏全部的watcher對象,通知它們去從新渲染組件。

Vue diff算法原理

vue-diff 是什麼?
提到vue的diff算法就不得不提一個名詞 虛擬dom(Virtual DOM) ,什麼是虛擬dom,個人理解是使用js對象來描述dom節點,是js和html的中間層,是一層對真實 DOM 的抽象。之前傳統的開發直接使用js操做dom,如今使用js操做js對象(虛擬dom),在合適的時機將虛擬dom轉化爲真實dom節點
爲何須要虛擬dom?
爲何須要虛擬dom,直接操做dom不是更方便嗎?實際上真正的 DOM 元素是很是龐大的,裏面有很是多的屬性,當咱們頻繁的去作 DOM 更新,會產生必定的性能問題。而虛擬dom使用js對象來描述dom節點,因此它比建立一個 DOM 的代價要小不少。
虛擬DOM的最終目標是將虛擬節點渲染到視圖上。可是若是直接使用虛擬節點覆蓋舊節點的話,會有不少沒必要要的DOM操做。例如,在一個dom元素很是多的頁面你只改裏其中的一個地方,這種狀況下若是使用新的虛擬節點覆蓋舊節點的話,形成了性能上的浪費,這個時候就須要比較計算新老虛擬節點的不一樣,差量的更新。因此這個時候vue-diff 就出現了。
下面說說 Diff 的比較邏輯

  1. 能不移動,儘可能不移動
  2. 沒得辦法,只好移動
  3. 實在不行,新建或刪除

比較處理流程是下面這樣
在新舊節點中

  1. 先找到 不須要移動的相同節點,消耗最小
  2. 再找相同可是須要移動的節點,消耗第二小
  3. 最後找不到,纔會去新建刪除節點,保底處理

比較是爲了修改DOM樹
其實這裏存在三種樹,一個是頁面DOM樹,一個是舊VNode樹,一個是新Vnode樹
頁面DOM樹和舊VNode樹節點一一對應的
而新Vnode樹則是表示更新後頁面DOM樹該有的樣子
這裏把舊Vnode樹和新Vnode樹進行比較的過程當中
不會對這兩棵Vode樹進行修改,而是以比較的結果直接對真實DOM 進行修改,好比說,在舊Vnode樹同一層中,找到和新Vnode樹中同樣但位置不同節點,此時須要移動這個節點,可是不是移動舊Vnode樹中的節點,而是直接移動DOM,總的來講,新舊Vnode樹是拿來比較的,頁面DOM 樹是拿來根據比較結果修改的

Vue computed和watch的區別

計算屬性computed

  1. 支持緩存,只有依賴數據發生改變,纔會從新進行計算
  2. 不支持異步,當computed內有異步操做時無效,沒法監聽數據的變化
  3. computed 屬性值會默認走緩存,計算屬性是基於它們的響應式依賴進行緩存的,也就是基於data中聲明過或者父組件傳遞的props中的數據經過計算獲得的值
  4. 若是一個屬性是由其餘屬性計算而來的,這個屬性依賴其餘屬性,是一個多對一或者一對一,通常用computed
  5. 若是computed屬性屬性值是函數,那麼默認會走get方法;函數的返回值就是屬性的屬性值;在computed中的,屬性都有一個get和一個set方法,當數據變化時,調用set方法。


偵聽屬性watch

  1. 不支持緩存,數據變,直接會觸發相應的操做;
  2. watch支持異步;
  3. 監聽的函數接收兩個參數,第一個參數是最新的值;第二個參數是輸入以前的值;
  4. 當一個屬性發生變化時,須要執行對應的操做;一對多;
  5. 監聽數據必須是data中聲明過或者父組件傳遞過來的props中的數據,當數據變化時,觸發其餘操做,函數有兩個參數,

  immediate:組件加載當即觸發回調函數執行,
  deep: 深度監聽,爲了發現對象內部值的變化,複雜類型的數據時使用,例如數組中的對象內容的改變,注意監聽數組的變更不須要這麼作。注意:deep沒法監聽到數組的變更和對象的新增,參考vue數組變異,只有以響應式的方式觸發纔會被監聽到。

總結:

computed特性
  1. 是計算值,不支持異步操做,單純的返回一個值
  2. 應用:就是簡化tempalte裏面{{}}計算和處理props或$emit的傳值
  3. 具備緩存性,頁面從新渲染值不變化;計算屬性會當即返回以前的計算結果,而沒必要再次執行函數,只有依賴數據發生改變,纔會從新進行計算
watch特性
  1. 是觀察的動做,支持異步操做,能夠進行一系列異步操做,
  2. 應用:監聽props,$emit或本組件的值執行異步操做
  3. 無緩存性,頁面從新渲染時值不變化也會執行

vue.nextTick()方法

定義:在下次DOM更新循環結束以後執行延遲迴調,在修改數據以後當即使用這個方法,獲取更新後的DOM。
理解:nextTick(),是將回調函數延遲在下一次dom更新數據後調用,就是當數據更新以後,而且在dom中渲染以後,自動執行該函數。 何時要用到?

  1. created()鉤子函數中的DOM操做必定要放在this.nextTick()的回調函數中,由於在created()時雖然數據能夠調用,可是DOM並無進行更新,因此操做DOM是無效的。

2. 當項目中要對改變以後的DOM元素作必定的操做時,將操做放在this.nextTick()的回調函數中 3. 在使用某些第三方插件時,想要在vue生成的某些DOM發生變化後從新應用該插件時,須要在this.nextTick()的回調函數中從新執行該插件的方法

Vue 3.0新特性

Vue主要的特色有三個方面,響應式機制,模板,以及對象式組件聲明語法。

  1. 響應式

2.x的響應式是基於Object.defineProperty實現的代理,可以監聽數據對象的變化,可是監聽不到對象屬性的增刪,數組元素和長度的變化,同時會在Vue初始化的時候把全部的Observer創建,實現數據視圖與數據的響應式更新,底層須要Observer的支持,因此須要Observer都創建好,才能觀察到數據對象的變化。
3.0中使用es6中的Proxy來代替Object.defineProperty,在目標對象之上架了一層攔截,代理的是對象而不是對象的屬性。這樣能夠將本來對對象屬性的操做變爲對整個對象的操做,能夠監聽到對象屬性的增刪和數組長度的變化,還能夠監聽Map,Set,WeakSet,WeakMap等,同時實現了惰性監聽,即不會再初始化的時候建立全部的observer,而是會在用到的時候纔去監聽。

proxy在目標對象的外層搭建了一層攔截,外界對目標對象的某些操做,必須經過這層攔截
new Proxy()表示生成一個Proxy實例,target參數表示所要攔截的目標對象,handler參數也是一個對象,用來定製攔截行爲
Proxy 實例也能夠做爲其餘對象的原型對象
Proxy的做用
對於代理模式 Proxy 的做用主要體如今三個方面
1.攔截和監視外部對對象的訪問
2.下降函數或類的複雜度
3.在複雜操做前對操做進行校驗或對所需資源進行管理
Proxy所能代理的範圍--handler
實際上 handler 自己就是ES6所新設計的一個對象.它的做用就是用來 自定義代理對象的各類可代理操做 。它自己一共有13中方法,每種方法均可以代理一種操做.其13種方法以下
Proxy場景:實現私有變量,抽離校驗模塊,訪問日誌,預警和攔截,過濾操做,中斷代理

  1. 模板

模板方面沒有大的變動,只改了做用域插槽,2.x 的機制致使做用域插槽變了,父組件會從新渲染,而 3.0 把做用域插槽改爲了函數的方式,這樣只會影響子組件的從新渲染,提高了渲染的性能。
同時,對於 render 函數的方面,vue3.0 也會進行一系列更改來方便習慣直接使用 api 來生成 vdom 。
3. 對象式的組件聲明方式
vue2.x 中的組件是經過聲明的方式傳入一系列 option,和 TypeScript 的結合須要經過一些裝飾器的方式來作,雖然能實現功能,可是比較麻煩。
3.0 修改了組件的聲明方式,改爲了類式的寫法,這樣使得和 TypeScript 的結合變得很容易。
此外,vue 的源碼也改用了 TypeScript 來寫。其實當代碼的功能複雜以後,必須有一個靜態類型系統來作一些輔助管理。
如今 vue3.0 也全面改用 TypeScript 來重寫了,更是使得對外暴露的 api 更容易結合 TypeScript。靜態類型系統對於複雜代碼的維護確實頗有必要。
4. 其它方面的更改
vue3.0 的改變是全面的,上面只涉及到主要的 3 個方面,還有一些其餘的更改:
支持自定義渲染器,從而使得 weex 能夠經過自定義渲染器的方式來擴展,而不是直接 fork 源碼來改的方式。
支持 Fragment(多個根節點)和 Protal(在 dom 其餘部分渲染組建內容)組件,針對一些特殊的場景作了處理。
基於 treeshaking 優化,提供了更多的內置功能

Webpack部分:

Webpack配置模塊:

Webpack常見配置:

webpack的打包原理:

  1. 識別入口文件
  2. 經過逐層識別模塊依賴,commonjs,amd,import等進行分析,獲取代碼依賴
  3. Webpack作的就是分析代碼,轉換代碼,編譯代碼,輸出代碼
  4. 最終造成打包後的代碼

Loader和plugin的區別:

  • Loader:文件加載器,可以加載資源文件,並對這些文件進行一些處理,諸如編譯壓縮等,最終一塊兒打包到指定的文件中

處理一個文件可使用多個loader,loader的執行順序和配置中的順序是相反的
第一個loader接收源文件內容做爲參數,其餘loader接收前一個執行的loader的返回值做爲參數,最後一個執行的loader會返回此模塊的js源碼

  • Plugin:在webpack運行的生命週期中會廣播不少的時間,plugin能夠監聽這些事件,在合適的時機經過webpack提供的API改變輸出的結果,好比設置項目的html首頁,啓用熱更新機制等。
  • Loader和plugin的區別:

Loader是一個轉換器,對A文件進行編譯造成B文件,這裏操做的是文件,例如將A.scss轉換爲A.css,單純的文件轉換過程。
Plugin是一個擴展器,豐富了webpack自己,針對的是loader結束後,webpack打包的整個過程,它不直接操做文件,而是基於事件機制工做,會監聽webpack打包過程當中的某些結點,執行對應的任務。

Babel:

Babel是一個JavaScript編譯器。他把最新版的javascript編譯成當下能夠執行的版本,簡言之,利用babel就可讓咱們在當前的項目中隨意的使用這些新最新的es6,甚至es7的語法。

Babel運行原理:

  1. 解析:將代碼字符串解析成抽象語法樹(AST)

分爲兩個階段:詞法分析,語法分析
詞法分析:將字符串形式的代碼轉換爲令牌流
語法分析:使用令牌中的信息將它們轉換成一個AST表述的結構
2. 轉換:接收AST並對其進行遍歷,對結點進行添加更新移除等操做。
Babel提供了@babel/traverse(遍歷)方法維護這AST樹的總體狀態,而且可完成對其的替換,刪除或者增長節點,這個方法的參數爲原始AST和自定義的轉換規則,返回結果爲轉換後的AST。
3. 生成:把通過一系列轉換後的AST從新轉換成字符串形式的代碼,同時還會建立源碼映射。
本質實際上是深度優先遍歷整個AST,而後構建能夠表示轉換後的代碼的字符串,Babel使用@babel/generator將修改後的AST轉換成代碼,生成過程能夠對是否壓縮以及是否刪除註釋等進行配置,而且支持sourceMap。
Vue中配置babelrc

Git部分:

git經常使用命令:

git經常使用命令

  • git add # 將工做區的修改提交到暫存區
  • git commit # 將暫存區的修改提交到當前分支
  • git reset # 回退到某一個版本
  • git stash # 保存某次修改
  • git pull # 從遠程更新代碼
  • git push # 將本地代碼更新到遠程分支上
  • git reflog # 查看歷史命令
  • git status # 查看當前倉庫的狀態
  • git diff # 查看修改
  • git log # 查看提交歷史
  • git revert # 回退某個修改

git add相關

  • git add . 將文件的修改,新建添加到暫存區
  • git add -u 將文件的修改,刪除添加到暫存區
  • git add -A 將文件的修改,新建,刪除添加到暫存區

git commit 相關

  • git commit -m 「本次提交描述」 該命令會將git add . 存入暫存區修改內容提交至本地倉庫中,若文件未添加至暫存區,則提交時不會提交任何修改
  • git commit -a 至關於運行git add -u把全部當前目錄下的文件加入緩存區域再運行git commit,注意新增文件並無被commit
  • git commit -am 「本次提交描述」 或 git commit -a -m 「本次提交描述」,等同於git commit -mgit commit -a
  • git commit -amend 修改最近的一次提交,提交註釋書寫有誤或者漏提文件的時候使用,注意漏提的文件要先用git add添加到緩存區以後,git commit -amend才能追加到

git stash用法

  • git stash 將全部未提交的修改保存起來,用於後續恢復當前的工做目錄
  • git stash save 「name」 給每一個stash添加一個message,用於記錄版本
  • git stash pop/git stash apply 恢復最新緩存的工做目錄,並恢復緩存堆棧中的那個stash刪除(pop),apply則只恢復不刪除
  • git stash list 查看現有的全部stash
  • git stash drop 移除最新的stash,也能夠指定名字

git reset用法

  • git reset HEAD^ 回退版本,一個^表示一個版本
  • git reset HEAD~n 回退n個版本
  • git reset commit-id 回退到指定版本
  • git reset 命令有三個參數,git reset --soft HEAD~1
    • --soft:軟回退,表示將本地版本庫頭指針重置到指定版本,且將此次提交以後的全部變動都移動到暫存區
    • --mixed:默認參數,可不寫,將本地版本庫的頭指針重置到指定版本,且重置暫存區,即此次提交以後全部變動都移動到工做區
    • --hard:回退一個版本,將本地版本庫的頭指針重置到指定版本,重置暫存區,並將工做區代碼清空。
  • git reset HEAD filename 回退指定文件

git reflog用法

  • git reflog 查看全部分支的操做記錄,包括commit 和reset的操做,包括已經被刪除的commit操做,git log則不能查看已經刪除commit 記錄

git checkout用法

  • git checkout [<commit>] [--] <paths> 用於拿暫存區的文件覆蓋工做區的文件,或者用指定提交中的文件覆蓋暫存區和工做區中對應的文件,帶commit參數則是從暫存區檢出文件覆蓋工做區,不帶commit參數則用--path中的文件覆蓋暫存區和工做區的文件。
  • git checkout <branch> 用於切換分支
  • git checkout -b <new_branch> [<start_point>] 用於建立並切換分支,-b 選項表示建立新分支。

git revert用法

  • git revert 反轉提交,撤銷一個提交的同時會建立一個新的提交,至關於用一個新提交來消除一個歷史提交所作出的修改
  • git revert commit-id 反轉提交指定一個commit
  • git revert HEAD~3 反轉提交第四個commit
  • git revert --abort 終止這次revert,防止產生衝突

git branch用法

  • git branch -d <branchname> 刪除分支,前提要切換到其餘分支

git push用法

  • git push <遠程主機名> <本地分支名>:<遠程分支名> 將本地分支的更新,推送到遠程主機。
  • git push origin master 將本地的master分支推送到origin主機的master分支。若是master不存在,則會被新建。
  • git push origin :master 等同於 git push origin --delete master

省略本地分支名,則表示刪除指定遠程分支。若是本地分支和遠程分支之間存在追蹤關係,則直接git push origin,若是遠程倉庫只有一個分支,則git push

  • git push -u origin master 使用-u命令創建當前分支與某個主機的追蹤關係,能夠不加參數使用git push

git pull用法

  • git pull <遠程主機名> <遠程分支名>:<本地分支名> 從另外一個存儲庫或者本地分支獲取並整合,取回遠程主機某個分支的更新,再與本地的指定分支合併
  • git pull origin master:test 取回origin主機的master分支與本地的test分支合併,若是是與本地的master分支合併,則:test可省略
  • git pull = git fetch + git merge
  • git pull --rebase = git fetch + git rebase git中fetch命令是將遠程分支的最新內容拉到了本地,可是fetch後看不到變化,由於此時本地多了一個FETCH_HEAD指針,checkout改指針後能夠查看遠程分支的最新內容,而後checkout到master分支,執行merge,選中FETCH_HEAD指針,合併後並解決衝突後,能夠commit。

計算機網絡部分:

TCP/IP模型結構及協議

數據鏈路層:實現了網卡接口的網絡驅動程序,以處理數據在物理媒介上的傳輸

  • ARP協議(地址解析協議):實現了IP地址和物理機器地址之間的轉換。網絡層使用IP地址尋址到一臺機器,而數據鏈路層使用物理地址尋址一臺機器,所以網絡層必須先將目標機器的Ip地址轉化成物理地址,才能使用數據鏈路層提供的服務,這就是ARP協議的用途。
  • RARP協議(逆地址解析協議):僅用於網絡上的某些無盤工做站,由於缺少存儲設備,無盤工做站沒法記住本身的IP地址,但他們能夠利用網上的物理地址來向網絡管理者查詢本身的IP地址。

網絡層:實現數據包的選路和轉發,廣域網一般使用衆多分級的路由器來鏈接分散的主機,所以通訊的兩臺主機通常是經過多箇中間節點鏈接的,網絡層的任務就是選擇這些中間節點,以肯定兩臺主機以前的通訊路徑

  • IP協議(因特網協議):根據數據包的目的IP地址來決定如何投遞,若是數據包不能直接發送給目標主機,那麼IP協議就爲它尋找下一個合適的路由器,並將數據包交付給路由器進行轉發,屢次重複,知道數據包達到目的主機或因發送失敗而丟棄,IP協議使用逐跳的方式來肯定通訊路徑
  • ICMP協議(因特網報文控制協議):是IP協議的重要補充,主要用於檢測網絡鏈接,ICMP報文分爲差錯報文和查詢報文,使用16位檢驗和字段對整個報文進行循環冗餘校驗,檢驗報文在傳輸過程當中是否損壞。

傳輸層:爲兩臺主機上的應用程序提供端到端的通訊,與網絡層使用逐跳通訊的方式不一樣,傳輸層只關心通訊的起始端和目的端,而不在意數據包的中轉過程。

  • TCP協議
  • UDP協議

應用層:負責處理應用程序的邏輯,應用層在用戶空間實現,由於它負責處理衆多的邏輯,好比文件傳輸,名稱查詢和網絡管理等等。

  • Ping:是應用程序,而不是協議,它利用ICMP報文檢測網絡鏈接,是調試網絡環境的必備工具。
  • Telnet協議:是一種遠程登陸協議,它使咱們能在本地完成遠程任務
  • OSPF協議(開放最短路徑優先):是一種動態路由更新協議,因爲路由器之間的通訊,以告知對方各自的路由信息
  • DNS協議:提供機器域名到IP地址的轉換

TCP和UDP的區別:

  • TCP是面向鏈接的,UDP是無鏈接的即發送數據前不須要先創建連接。
  • TCP提供可靠的服務。也就是說,經過TCP鏈接傳送的數據,無差錯,不丟失,不重複,且按序到達;UDP盡最大努力交付,即不保證可靠交付。 而且由於TCP可靠,面向鏈接,不會丟失數據所以適合大數據量的交換。
  • TCP是面向字節流,UDP面向報文,而且網絡出現擁塞不會使得發送速率下降,所以會出現丟包,對實時的應用好比IP電話和視頻會議等。其中字節是散亂的數據,報文是添加了標記,封裝後的數據,字節流是由字節組成的。
  • TCP只能是1對1的,UDP支持1對1,1對多。
  • TCP的 首部較大爲20字節,而UDP只有8字節。
  • TCP是面向鏈接的可靠性傳輸,而UDP是不可靠的。
  • TCP用於在傳輸層有必要實現可靠傳輸的狀況,好比文件下載,UDP主要用於哪些對高速傳輸和實時性有較高要求的通訊或廣播通訊,好比實時通話

tcp三次握手與四次揮手:

TCP報文包含了哪些內容?

  1. TCP報頭中的源端口號和目的端口號同IP數據報中的源IP與目的IP惟一肯定一條TCP鏈接,TCP在發送數據前必須在彼此間創建鏈接,這裏鏈接的意思是:雙方須要內保存對方的信息(如IP,Port)
  2. 報文主要段的意思:
  • 序號:表示發送的數據字節流,確保TCP傳輸有序,對每一個字節編號。
  • 確認序號:發送方期待接收的下一序列號,接收成功後數據字節序列號加1,只有ACK=1時纔有效。
  • ACK:確認序號的標誌,ACK=1表示確認號有效,ACK=0表示報文不含確認序號信息。
  • SYN:鏈接請求序號標誌,用於創建鏈接,SYN=1表示請求鏈接。
  • FIN:結束標誌,用於釋放鏈接,爲1表示關閉本方數據流。

三次握手過程:

  • 第一次握手:客戶端發送初始序號hx和syn=1請求標誌。
  • 第二次握手:服務器發送請求標誌syn,發送確認標誌ACK,發送本身的序號seq=y,發送客戶端的確認序號,ack=x+1
  • 第三次握手:客戶端發送ACK確認信號,發送本身的序號seq=x+1,發送對方的確認號ack=y+1

三次握手過程分析:

  • 第一次:客戶端發送請求到服務器,服務器知道客戶端發送,本身接收正常。SYN=1,seq=x
  • 第二次:服務器發給客戶端,客戶端知道本身發送、接收正常,服務器接收、發送正常。ACK=1,ack=x+1,SYN=1,seq=y
  • 第三次:客戶端發給服務器:服務器知道客戶端發送,接收正常,本身接收,發送也正常.seq=x+1,ACK=1,ack=y+1

爲何要有三次握手的過程?
由於只有通過三次,服務器和客戶端才能夠互相知道對方和本身發送接收都正常,通過兩次握手的話服務端沒法知道客戶端是否具有接收以及本身是否具有發送的能力;而且兩次握手的話若是首次握手的報文超時客戶端再重發以後,服務端接收到以前的那個報文也會直接創建鏈接,浪費資源;

四次揮手過程:

  • 第一次揮手:客戶端發出釋放FIN=1,本身序列號seq=u,進入FIN-WAIT-1狀態
  • 第二次揮手:服務器收到客戶端的後,發出ACK=1確認標誌和客戶端的確認號ack=u+1,本身的序列號seq=v,進入CLOSE-WAIT狀態
  • 第三次揮手:客戶端收到服務器確認結果後,進入FIN-WAIT-2狀態。此時服務器發送釋放FIN=1信號,確認標誌ACK=1,確認序號ack=u+1,本身序號seq=w,服務器進入LAST-ACK(最後確認態)
  • 第四次揮手:客戶端收到回覆後,發送確認ACK=1,ack=w+1,本身的seq=u+1,客戶端進入TIME-WAIT(時間等待)。客戶端通過2個最長報文段壽命後,客戶端CLOSE;服務器收到確認後,馬上進入CLOSE狀態。、

四次揮手過程分析:

  • 第一次:客戶端請求斷開FIN,seq=u
  • 第二次:服務器確認客戶端的斷開請求ACK,ack=u+1,seq=v
  • 第三次:服務器處理完數據以後請求斷開FIN,seq=w,ACK,ack=u+1
  • 第四次:客戶端確認服務器的斷開ACK,ack=w+1,seq=u+1

爲何揮手要進行四次?
由於服務器端發送確認客戶端斷開的ACK以後,還要進行數據處理,處理完數據以後才能夠發送本身的斷開請求。這裏不能合併成一個請求過程。

PS:以上知識點的內容是樓主根據本身的理解和其餘大神的博客內容整理出來的,可能有一些內容是原文,若是侵犯到了哪位大大的版權,請聯繫我及時刪掉對應的內容。

相關文章
相關標籤/搜索