Vue.js中文API閱讀筆記及自己踩過的坑

? ? ? ?emmmmm,,之前因為開項目來不及仔細讀一遍,只能是用到什么找什么,然而深感對vue了解的無力(?д?;)。。還有一個周開新項目,恩,認真看一哈!( ̄▽ ̄)
【本文并沒有講解全部API,因為太多了。。總結了部分我覺得重要的點加以分析】
傳送門:Vue.js中文API

  1. Vue參考MVVM模式,使用vm (ViewModel 的簡稱)來表示Vue實例

? ? ? ?vue是一個虛擬DOM的,以數(shù)據(jù)驅(qū)動為核心的前端框架。數(shù)據(jù)驅(qū)動也可以稱為響應式系統(tǒng),當屬性的值發(fā)生變化時,視圖都會“及時響應”,并更新相應的新值。

  1. 實例生命周期鉤子函數(shù)

? ? ? ?每個 Vue 實例在被創(chuàng)建之前,都要經(jīng)過一系列的初始化過程,例如,Vue 實例需要設置數(shù)據(jù)觀察(set up data observation)、編譯模板(compile the template)、在 DOM 掛載實例(mount the instance to the DOM),以及在數(shù)據(jù)變化時更新 DOM(update the DOM when data change)。在這個過程中,Vue 實例還會調(diào)用執(zhí)行一些生命周期鉤子函數(shù),這樣用戶能夠在特定階段添加自己的代碼。

Vue生命周期

? ? ? ?(圖可能不是很清晰,小伙伴們可以參考原圖

  • 對于數(shù)據(jù)的操作,比如props、data、computed的初始化都是在beforeCreate與created之間完成的,所以不了解的時候很可能會出現(xiàn)在別的鉤子操作數(shù)據(jù)而產(chǎn)生奇奇怪怪的問題。
  • 有一點要注意, 一般情況下vue組件總是會走完全部的生命周期的,即使你在created或者其他早期的生命周期鉤子中使用了路由跳轉或者location.herf重定向。
  • 一些因生命周期問題而導致無法使頁面刷新的問題有如下解決方案:
    ①this.nextTick({ })具體使用方法請移步傳送門
    ②vuex
    ③setTimeout(code,millisec) 【可以強制推遲頁面加載xx毫秒,強烈不推薦,暫緩之計,具體病因還是要具體解決】
  • 生命周期鉤子是一個很強大的功能,可以很好地處理掛載以及異步加載相關的事件,在特定階段執(zhí)行特定的代碼,比如某幾張圖的出現(xiàn)順序、比如axios請求數(shù)據(jù)來異步刷新等。
  • 注意,任何生命周期鉤子 中 this 上下文都會指向調(diào)用它的 Vue 實例。

關于生命周期具體理解推薦一篇文章來自segmentfault

3. 關于computed和watcher,留個flag,匯總一下再寫

4. 修飾符(modifier)是以 . 表示的特殊后綴,表明應當以某種特殊方式綁定指令。

? ? ? ?關于修飾符,請移步我的一篇搬運文章? Vue修飾符詳解

5. 渲染

? ? ? ?1. 根據(jù)條件進行渲染:v-if與v-show
  • v-if與v-show可以對內(nèi)容進行靈活的選擇性加載,是使用比較多的指令。
    ? ? ? ?其二者的區(qū)別是,v-if是“真實”的條件渲染,因為它會確保條件塊(conditional block)在切換的過程中,完整地銷毀(destroy)和重新創(chuàng)建(re-create)條件塊內(nèi)的事件監(jiān)聽器和子組件。且v-if是惰性的(lazy),如果在初始渲染時條件為 false,它不會執(zhí)行任何操作。直到在條件第一次變?yōu)?true 時,才開始渲染條件塊。
    ? ? ? ?相比之下,v-show 要簡單得多 - 不管初始條件如何,元素始終渲染,并且只是基于 CSS 的切換。
    ? ? ? ?通常來說,v-if 在切換時有更高的性能開銷,而 v-show 在初始渲染時有更高的性能開銷。因此,如果需要頻繁切換,推薦使用 v-show,如果條件在運行時改變的可能性較少,推薦使用 v-if。
    v-if的渲染控制
? ? ? ?2. 列表渲染:v-for
  • 在 v-for 代碼塊中,我們可以完全地訪問父級作用域下的屬性。v-for 還支持可選的第二個參數(shù),作為當前項的索引:
<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

結果:
  • 也可以使用 v-for 來遍歷對象的屬性,接著提供第二個參數(shù),作為對象的鍵名(key),然后第三個參數(shù)作為索引(index):
<div v-for="(value, key, index) in object">
  {{ index }}. {{ key }}: {{ value }}
</div>
new Vue({
  el: '#v-for-object',
  data: {
    object: {
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    }
  }
})

結果:

注意,在遍歷一個對象時,是按照 Object.keys() 得出 key 的枚舉順序來遍歷,無法保證在所有 JavaScript 引擎實現(xiàn)中完全一致。

  • 關于key,下列是API的原文
<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>
推薦在使用 v-for 時,盡可能提供一個 key,除非迭代的 DOM 內(nèi)容足夠簡單,
或者你是故意依賴于默認行為來獲得性能提升。
由于這是 Vue 識別節(jié)點的通用機制,因此 key 并不是僅限于與 v-for 關聯(lián),
我們將在之后的指南中看到,key 還可以其他場景使用。

因為沒有用到過所以不是很理解,給個flag后續(xù)了解。

  • 帶有v-if的v-for
    當它們都處于同一節(jié)點時,v-for 的優(yōu)先級高于 v-if。這意味著,v-if 將分別在循環(huán)中的每次迭代上運行。當你只想將某些項渲染為節(jié)點時,這會非常有用,如下:
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>
  • 關于v-once
    用法:<span v-once></span>
    在API中給出的建議是性能優(yōu)化,事實也確實如此,不過需要注意的是,用v-once指令修飾的html內(nèi)容在加載的時候會且只會加載一次

? ? ? ?劃重點?。。?!

? ? ? ?3. 數(shù)組變化檢測(Array Change Detection)

? ? ? ?Vue 將觀察數(shù)組(observed array)的變化數(shù)組方法(mutation method)包裹起來,以便在調(diào)用這些方法時,也能夠觸發(fā)視圖更新。這些包裹的方法如下:

push()
pop()
shift()
unshift()
splice()
sort()
reverse()

由于 JavaScript 的限制,Vue 無法檢測到以下數(shù)組變動:

  1. 當你使用索引直接設置一項時,例如 vm.items[indexOfItem] = newValue
  2. 當你修改數(shù)組長度時,例如 vm.items.length = newLength

? ? ? ?所以,使用Vue.set(example1.items, indexOfItem, newValue)來解決第一個問題,
使用example1.items.splice(indexOfItem, 1, newValue)來解決第一和第二個問題。
這兩種方法可以通過響應式系統(tǒng)觸發(fā)狀態(tài)更新。

? ? ? ?4. 對象變化檢測(Array Change Detection)

受現(xiàn)代 Javascript 的限制, Vue 無法檢測到對象屬性的添加或刪除:

var vm = new Vue({
 data: {
  a: 1
 }
})
// `vm.a` 是響應的

vm.b = 2
// `vm.b` 不是響應的

? ? ? ?Vue 不允許在已經(jīng)創(chuàng)建的實例上,動態(tài)地添加新的根級響應式屬性(root-level reactive property)。然而,可以使用 Vue.set(object, key, value) 方法,將響應式屬性添加到嵌套的對象上。例如:

var vm = new Vue({
 data: {
   userProfile: {
     name: 'Anika'
   }
 }})

? ? ? ?可以向嵌套的 userProfile 對象,添加一個新的 age 屬性:
? ? ? ?Vue.set(vm.userProfile, 'age', 27)
? ? ? ?還可以使用 vm.$set 實例方法,這也是全局 Vue.set 方法的別名:
? ? ? ?vm.$set(this.userProfile, 'age', 27)

? ? ? ?這是剛接觸Vue的時候踩到過的一個大坑,現(xiàn)在想起來還頭皮發(fā)麻
∑(?Д?ノ)ノ

6. DOM 模板解析

當時用DOM模板時,會受到一些來源于HTML的限制,比如,這種寫法是報錯的:

<table>
  <!--my-row是自定義模板-->
  <my-row>...</my-row>
</table>

解決方案:

<table>
  <tr is="my-row"></tr>
</table>

is屬性請自行百度。

敲黑板

在使用以下字符串模板之一的場景中,這些限制將不再適用:

  • <script type="text/x-template">
  • JavaScript 內(nèi)聯(lián)模板字符串
  • .vue 組件
所以,用.vue吧,畢竟用的就是vue框架233333_(:з」∠)_

7. 組件復用

組件(component)是 Vue 最強大的功能之一。組件可以幫助你擴展基本的 HTML 元素,以封裝可重用代碼。

在編寫組件時,記住是否要復用組件有好處。一次性組件跟其它組件緊密耦合沒關系,但是可復用組件應當定義一個清晰的公開接口。

Vue 組件的 API 來自三部分 - props, events 和 slots :

  • Props 允許外部環(huán)境傳遞數(shù)據(jù)給組件
  • Events 允許組件對外部環(huán)境產(chǎn)生副作用(side effects)
  • Slots 允許外部環(huán)境將額外的內(nèi)容組合在組件中。

8. 組件的組合與通信

組件,意味著組合在一起使用的元件,多數(shù)場景是父子關系:組件 A 可以在自己的模板中使用組件 B。這就必然的需要彼此相互通信:父組件可能會向下傳遞數(shù)組給子組件,然后子組件也可能會將自身發(fā)生的變化通知到父組件。然而,重要的是,為了盡可能將父子組件解耦,需要有一個定義清晰的接口。定義清晰的通信方式,可以確保組件可以相對隔離地組織代碼,以及合乎邏輯易于推斷,從而使它們更加易于維護,并且可能更加易于復用。

vue的大方面的功能核心就是組件,正是組件的組合嵌套復用構成了快速且多樣的vue項目生態(tài)圈,而組件通信又是組件中比較重要的知識點。

  1. 父向子組件:

    • 在子組件中添加props(既可以傳遞數(shù)據(jù)也可以傳遞方法)
      常用形式<child :msg = "parentMsg"/>
      含有路由出口的使用形式<router-view :propsdata="data"/>
    • this.$broadcast 調(diào)用子組件方法(子組件在events中寫被調(diào)用方法)
    • 父組件通過this.$ref獲得子組件的引用
      【$refs 只在組件渲染完成后才填充,并且它是非響應式的。它僅僅作為一個直接訪問子組件的應急方案 - 應當避免在模板或計算屬性中使用 $refs。】
    • 使用this.$children()獲得子組件的Vue實例
  2. 子向父組件:

    • this.$emit (父組件在methods中寫被調(diào)用方法,并通過@event綁定到子組件) ,子組件中通過這種方法傳遞數(shù)給父組件同時激活父組件的被調(diào)用方法。
    • this.$dispath (父組件在events中寫被調(diào)用方法)
    • 在子組件中添加插槽slot,父組件可以向子組件中插入模板 <template/> ,通過slot-scope獲得子組件返回的值
    • 使用this.$parent獲得父組件Vue實例 (this.$root獲得根組件的Vue實例)

一點補充:在某些場景中,我們可能需要對一個 prop 進行「雙向綁定」 - 事實上,這個功能在 Vue 1.x 中已經(jīng)由 .sync 修飾符實現(xiàn)。但是在2.0中移除,在2.3.0+中以語法糖的形式再次加入。雖然用的不多,如果想了解請移步API

  1. 通過bus.js或者自身的vue實例來進行不同組件之間的數(shù)據(jù)傳遞
    • 通過new一個Vue對象作為通信的橋梁(bus.$emit() => bus.$on())
    • 自身的vue實例(this.$emit() => this.$on())
  2. Flux以及Vuex(全局單例模式)同時也可用于解決不同組件之間的通信問題(解決了繁雜事件訂閱和廣播)
  3. 路由傳參
    這里要注意,第一種方式是無法傳參的,要傳參必須通過第二種方式,即以 name 的形式而不能以路徑的形式。所以在路由中的定義如下第三張圖。
    不帶參
    帶參
    路由表中的定義

關于slot,與props相似,簡單來說就是props把數(shù)據(jù)扔到子組件中,slot把html扔到子組件中。關于slot留個flag后續(xù)寫個專欄具體補充。。。

請注意,props是單向數(shù)據(jù)流,按照自上而下單向流動方式構成

9. 動態(tài)組件

  • 簡單來說,與v-bind動態(tài)選擇css一個樣子,根據(jù)父組件給的變量決定顯示哪個組件,或者都不顯示。
  • 使用方式:<component v-bind:is="組件名"></component>
  • 有一點需要注意,像v-if一樣,動態(tài)加載組件是需要重渲染的,所以如果想避免重新渲染可以添加keep-alive屬性來保持已渲染的組件不被移除。
    <component v-bind:is="組件名" keep-alive></component>
  • activate延遲加載
    activate是和data等屬性平級的一個屬性,形式是一個函數(shù),函數(shù)里默認有一個參數(shù),而這個參數(shù)是一個函數(shù)。
    如下實例:
data(){
    return{
      //...
    }
},
activate (done) { //執(zhí)行這個參數(shù)時,才會切換組件  
    var self = this;  
    // 
    axios.get("/test", function (data) {    
    self.hello = data;  
    done(); //ajax執(zhí)行成功,切換組件  
    })  
}  

注意:
【1】只有在第一次渲染組件時,才會執(zhí)行activate,且該函數(shù)只會執(zhí)行一次(在第一次組件出現(xiàn)的時候延遲組件出現(xiàn))

【2】沒有keep-alive時,每次切換組件出現(xiàn)都是重新渲染(因為之前隱藏時執(zhí)行了destroy過程),因此會執(zhí)行activate方法。

10. 組件雜項

以下全部有待補充,慣例,flaggggggggggggg

  • 異步組件/代碼分離
    應用做大了以后可以進行性能優(yōu)化,后續(xù)詳細補充
  • 命名規(guī)范
  • 組件之間的循環(huán)引用
  • 組件庫
  • 其他

11. 過渡&動畫

概述

過渡和動畫可以對頁面內(nèi)容以及用戶體驗做一些良好的提升,避免生硬的切換效果帶來的挫頓感。個人看法:如果不考慮模塊化發(fā)布或者工程量不是很大,在系統(tǒng)功能完善之后進行過度動畫的添加可以對頁面逼格進行大幅提升~

從頁面中添加(顯示)、移除(隱藏)或者更新一些成員的時候,Vue提供了多種的過渡動畫來避免生硬的元素轉變。包括以下工具:

  • 在 CSS 過渡和動畫中自動處理 class
  • 可以配合使用第三方 CSS 動畫庫,如 Animate.css
  • 在過渡鉤子函數(shù)中使用 JavaScript 直接操作 DOM
  • 可以配合使用第三方 JavaScript 動畫庫,如 Velocity.js
單元素/組件的過渡

Vue提供了transition外層包裹容器組件(wrapper component),可以給下列情形中的任何元素和組件添加進入/離開(enter/leave)過渡:

  • 條件渲染(使用 v-if)
  • 條件展示(使用 v-show)
  • 動態(tài)組件
  • 組件根節(jié)點

一個demo:

<template>
<div id="demo">
  <button v-on:click="show = !show">
    Toggle
  </button>
  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>
</template>

<script>
new Vue({
  el: '#demo',
  data: {
    show: true
  }
})
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity .5s;
}

.fade-enter, .fade-leave-to /* .fade-leave-active 在低于版本 2.1.8 中 */ {
  opacity: 0;
}
</style>
其他的予以保留 flaggggg

正在開新項目,閑下來繼續(xù)更新

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Vue 實例 屬性和方法 每個 Vue 實例都會代理其 data 對象里所有的屬性:var data = { a:...
    云之外閱讀 2,368評論 0 6
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對于 Vue 1.0 印象不深的內(nèi)容。關于...
    云之外閱讀 5,174評論 0 29
  • Vue 框架的入口就是 Vue 實例,其實就是框架中的 view model ,它包含頁面中的業(yè)務處理邏輯、數(shù)據(jù)模...
    阿根廷斗牛閱讀 962評論 0 2
  • JavaScript 變量可以是局部變量或全局變量。私有變量可以用到閉包。 全局變量 變量聲明時如果不使用 var...
    S大偉閱讀 358評論 0 0
  • 《詩經(jīng)》所反映的社會生活內(nèi)容十分豐富,它包括天文地理,政治經(jīng)濟,祭祀典禮,戰(zhàn)爭徭役,定都建國,燕饗歡,狩獵...
    熠悅之閱閱讀 362評論 0 0

友情鏈接更多精彩內(nèi)容