吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】


吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】


前言

前面兩篇文章總結了 Vue 開發的大部分技巧和內容,最後一篇文章來對它進行一個收尾

這篇文章我們來談談一些 Vue 理解和實踐要求高一點的問題

首先是生命週期這一塊內容,隨著實踐越多它的意義越大,理解也越深刻

mixin 功能強大,對代碼複用組織都有很高的要求,算是 Vue 後期發力的高級技巧

服務端渲染可能是學習 Vue 最後一塊陣地了,對於 SPA 框架的一個里程碑

最後,總結一下我在使用 Vue 中使用的技巧和經驗

常規操作,先點贊後觀看哦!你的點贊是我創作的動力之一!

前情提要

我將從 16 個方面來論述 Vue 開發過程中的一些技巧和原理。如果你還未觀看上節文章,可以移步至

本篇概覽

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

Vue 生命週期

什麼是 Vue 生命週期?

Vue 生命週期大概就是:一個從 Vue 實例的創建到組件銷燬的一個的過程。

具體情況下,我們分為幾個核心的階段,並且每個階段都有一套鉤子函數來執行我們需要的代碼。

生命週期階段與鉤子

我們整理分類一下這些生命週期鉤子,為了記憶方便分為 4 大核心階段:

方便讀者記憶,這裡儘量使用圖示:

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

可以看到每一個階段中的鉤子命名都很好記憶,階段開始前使用 beforeXxx,階段後結束後使用xxxed

除這 8 個核心鉤子,另外還有 3 個新增功能型鉤子,目前總共是 11 個鉤子 順帶提一下這 3 個鉤子的功能

  1. 組件緩存,activated 與 deactivated,這兩個鉤子也是一對的,分別表示被 keep-alive 緩存的組件激活和停用時調用。
  2. 組件錯誤捕獲,errorCaptured,對組件中出現對異常錯誤進行處理,使用較少。

圖解生命週期

我們看看官方的圖解,在 Vue 教程實例這節 官方教程直接跳轉

官方圖解

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

官方圖解並沒有詳細解釋這張圖。我猜一方面原因是這個圖裡面涉及的細節都是在 vue 源碼裡面體現,要真正解釋起來也沒那麼簡單。另一方面是希望我們多在實踐中去理解裡面的意義。

Vue 源碼基本流程

對於上面那張圖的理解,我們需要對 Vue 源碼進行梳理,才能真正的理解。大概根據現有的源碼,我梳理了一下大致的流程:

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

我們可以清楚地看到,從 Vue 實例創建、組件掛載、渲染的一些過程中,有著明顯的週期節點。

簡化文字圖解

結合上面源碼的流程和相關實踐,簡化每一個階段做了哪些時期,每一個鉤子裡面是組件處於什麼狀態。

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

實踐驗證一下生命週期

提出問題

下面我們提出一些問題:

  1. 什麼時期創建 el ?
  2. 什麼時期掛載 data ?
  3. 什麼時期可以訪問 dom ?
  4. 什麼情況下組件會更新?更新是同步更新還是異步更新?
  5. 什麼情況下組件會被銷燬?
  6. 銷燬組件後,還可以訪問哪些內容?

編寫代碼

  1. 首先寫一個小 demo,打印關鍵組件信息
<code><template>


{{message}}


/<template>


複製代碼/<code>
  1. 增加核心的 8 個生命週期鉤子,分別調用打印方法
<code>  // ...
beforeCreate() {
this.printComponentInfo('beforeCreate')
},
created() {
this.printComponentInfo('created')
},
beforeMount() {
this.printComponentInfo('beforeMount')
},
mounted() {
this.printComponentInfo('mounted')
},
beforeUpdate() {
this.printComponentInfo('beforeUpdate')
},
updated() {
this.printComponentInfo('updated')
},
beforeDestroy() {
this.printComponentInfo('beforeDestroy')
},
destroyed() {
this.printComponentInfo('destroyed')
},
// ...
複製代碼/<code>

創建階段

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

beforeCreate 中methods中方法直接報錯無法訪問,直接訪問 el 和 data 後

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

發現只能訪問到 watch, el 和 data 均不能訪問到

created 時期 el 無法訪問到,但是可以訪問到 data 了

掛載階段

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

beforeMount 中可以訪問 data 但是仍然訪問不到 el

mounted 中可以訪問到 el 了

首次加載頁面,更新階段和銷燬階段到鉤子都未觸發

更新階段

我們增加一行代碼

<code>this.message = this.message + 1
複製代碼/<code>

如果增加在 created 階段,發現 update鉤子仍然未觸發,但是 el 和 data 的值都變成了 2

如果增加在 mounted 階段,發現 update鉤子此時觸發了

吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

銷燬階段

怎樣觸發銷燬的鉤子呢? 大概有這幾種方法

  • 手動調用 $destory
  • v-if 與 v-for 指令,(v-show 不行)
  • 路由切換和關閉或刷新瀏覽器 我們在 mounted 鉤子裡面增加一行代碼手動銷燬當前組件,或者跳轉路由
吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

<code>this.$destory('lifecycle') 

複製代碼/<code>
吃透 Vue 項目開發實踐|16個方面深入前端工程化開發技巧【下】

發現beforeDestory 和 destoryed 都觸發了,而且el、data都一樣還是可以訪問到

生命週期鉤子常見使用的場景

beforeCreate 謹慎操作 this

beforeCreate 無法訪問到 this 中的 data、method

<code>// 錯誤實例
beforeCreate() {
// 允許
console.log('ok')

// 不允許
this.print() // 報錯找不到
this.message = 1 // 報錯找不到

}
複製代碼/<code>

請求應放在 created 鉤子中

created 可以訪問 this,但無法訪問 dom,dom 未掛載

<code>created() {
// 允許並推薦
this.$http.get(xxx).then(res => {
this.data = res.data
})
// 不允許
this.$el
this.$ref.demo
const a = document.getElementById('demo')
}
複製代碼/<code>

操作 DOM 代碼應放在 mounted 鉤子中

mounted 已經掛載 dom,可以訪問 this

<code>mounted() {
// 允許
this.$el
this.$ref.demo
let a = document.getElementById('')
}
複製代碼/<code>

生命週期相關demo 代碼見github-lifecycle-demo

理解併合理使用 mixin

什麼是 mixin(混入)

當組件使用混入對象時,所有混入對象的選項將被“混合”進入該組件本身的選項 大致原理就是將外來的組件、方法以某種方式進行合併。合併的規則有點像繼承和擴展。

當組件和混入對象含有同名選項時,這些選項將以恰當的方式進行“合併”

我們看一下一個組件裡面有哪些東西是可以合併的

<code>// mixins/demo
export default {
data() {
return {}
},
mounted() {},
methods: {},
computed: {},
components: {},
directives: {}
}
複製代碼/<code>

data、methods、computed、directives、components 生命週期鉤子

沒錯這些都可以混入

<code>import demoMixin form '@/mixins/demo'
export default {
mixins: [demoMixin]
}
複製代碼/<code>

這樣看來,很多頁面重複的代碼我們都可以直接抽取出來

或者是封裝成一個公共的 mixin

比如我們做 H5 頁面,裡面很多短信驗證的邏輯固有邏輯,但是需要訪問到 this。使用工具函數肯定不行。

這時候就可以考慮使用 mixin,封裝成一個具有響應式的模塊。供需要的地方進行引入。

mixin 規則

首先是優先級的問題,當重名選項時選擇哪一個為最後的結果

默認規則我這裡分為 3 類

  1. data 混入: 以當前組件值為最後的值
  2. 生命週期鉤子: 保留所有鉤子,先執行 mixins 的,後執行當前組件的
  3. methods、computed、directives、components 這種健值對形式,同名key,統統以當前組件為準

當然如果想改變規則,也可以通過配置來改變規則

<code>Vue.config.optionMergeStrategies.myOption = function (toVal, fromVal) {
// 返回合併後的值
}

複製代碼/<code>

mixin 的好處

我們知道 Vue 最能複用代碼的就是組件。一般情況,我們通過 props 來控制組件的,將原有組件封裝成 HOC 高階組件。而控制 props 的生成不一樣的功能的代碼還是寫在基礎組件裡。

<code><template>
div.dib
van-button.btn(
@click="$emit('click')"
:class="getClass" v-bind="$attrs"
:style="{'width': size === 'large' ? '345px': '', 'backgroundColor': getBgColor, borderColor: getBgColor, color: getBgColor}")
slot
/<template>

/<code>


分享到:


相關文章: