成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Vue中你不知道但卻很實(shí)用的黑科技

Heier / 2154人閱讀

摘要:最近數(shù)月一直投身于的開源工作中,完成了大大小小多個(gè)組件,在組件化開發(fā)中積累了不少經(jīng)驗(yàn)。在開發(fā)全局提示組件通知提醒組件對(duì)話框組件時(shí),內(nèi)部都是使用來渲染,但卻是來隱式地創(chuàng)建這些實(shí)例,這樣我們就可以像標(biāo)題這樣使用,但其內(nèi)部還是通過來管理。

最近數(shù)月一直投身于 iView 的開源工作中,完成了大大小小 30 多個(gè) UI 組件,在 Vue 組件化開發(fā)中積累了不少經(jīng)驗(yàn)。其中也有很多帶有技巧性和黑科技的組件,這些特性有的是 Vue 文檔中提到但卻容易被忽略的,有的更是沒有寫在文檔里,今天就說說 Vue 組件的高級(jí)玩法。

寫在前面

本文所講內(nèi)容大多在 iView 項(xiàng)目中使用,大家可以前往關(guān)注,并結(jié)合源代碼來研究其中的奧妙。項(xiàng)目地址:
https://github.com/iview/iview

目錄

遞歸組件

自定義組件使用 v-model

使用$compile()在指定上下文中手動(dòng)編譯組件

內(nèi)聯(lián)模板inline-template

隱式創(chuàng)建 Vue 實(shí)例

遞歸組件

遞歸組件在文檔中有介紹,只要給組件指定一個(gè) name字段,就可以在該組件遞歸地調(diào)用自己,例如:

var iview = Vue.extend({
  name: "iview",
  template:
    "
" + // 遞歸地調(diào)用它自己 "" + "
" })

這種用法在業(yè)務(wù)中并不常見,在 iView 的級(jí)聯(lián)選擇組件中使用了該特性
(https://github.com/iview/iview/tree/master/src/components/cascader)
效果如下圖所示:

圖中每一列是一個(gè)組件(caspanel.vue),一開始想到用 v-for來渲染列表,但后面發(fā)現(xiàn)擴(kuò)展性極低,而且隨著功能的豐富,實(shí)現(xiàn)起來很困難,處理的邏輯很多,于是改寫成了遞歸組件:

props 比較多,可以忽略,但其中關(guān)鍵的兩個(gè)是datasublist,即當(dāng)前列數(shù)據(jù)和子集的數(shù)據(jù),因?yàn)轭A(yù)先不知道有多少下級(jí),所以只需傳遞下級(jí)數(shù)據(jù)給組件本身,如果為空時(shí),遞歸就結(jié)束了,Vue 這樣設(shè)計(jì)的確很精妙。
注:該方法在 Vue 1.x 和 2.x 中都支持。

自定義組件使用 v-model

我們知道,v-model是在表單類元素上進(jìn)行雙向綁定時(shí)使用的,比如:


這時(shí)data就是雙向綁定的,輸入的內(nèi)容會(huì)實(shí)時(shí)顯示在頁面上。在 Vue 1.x 中,自定義組件可以使用 props 的.sync雙向綁定,比如:

在 Vue 2.x 中,可以直接在自定義組件上使用 v-model了,比如:

在組件my-component中,通過this.$emit("input")就可以改變data的值了。
雖然 Vue 1.x 中無法這樣使用,但是如果你的組件的模板外層是 input、select、textarea等支持綁定 v-model 特性的元素,也是可以使用的,比如 my-component 的代碼是:

那也可以使用上面2.x的寫法。

使用$compile()在指定上下文中手動(dòng)編譯組件

注:該方法是在 Vue 1.x 中的使用介紹,官方文檔并沒有給出該方法的任何說明,不可過多依賴此方法。
使用$compile()方法,可以在任何一個(gè)指定的上下文(Vue實(shí)例)上手動(dòng)編譯組件,該方法在 iView 新發(fā)布的表格組件 Table 中有使用:
https://github.com/iview/iview/tree/master/src/components/table/cell.vue
由于表格的列配置是通過一個(gè) Object 傳入 props 的,因此不能像 slot 那樣自動(dòng)編譯帶有 Vue 代碼的部分,因?yàn)閭魅氲亩际亲址?,比如?/p>

{
    render (row) {
        return `${row.name}`
    }
}

render函數(shù)最終返回一個(gè)字符串,里面含有一個(gè)自定義組件 i-button,如果直接用{{{ }}}顯示,i-button 是不會(huì)被編譯的,那為了實(shí)現(xiàn)在單元格內(nèi)支持渲染自定義組件,就用到了$compile()方法。
比如我們?cè)诮M件的父級(jí)編譯:

// 代碼片段
const template = this.render(this.row);    // 通過上面的render函數(shù)得到字符串
const div = document.createElement("div");
div.innerHTML = template;
this.$parent.$compile(div);    // 在父級(jí)上下文編譯組件
this.$el.appendChild(cell);    // 將編譯后的html插入當(dāng)前組件

這樣一來, i-button就被編譯了。
在某些時(shí)候使用$compile()確實(shí)能帶來益處,不過也會(huì)遇到很多問題值得思考:

這樣編譯容易把作用域搞混,所以要知道是在哪個(gè)Vue實(shí)例上編譯的;

手動(dòng)編譯后,也需要在合適的時(shí)候使用$destroy()手動(dòng)銷毀;

有時(shí)候容易重復(fù)編譯,所以要記得保存當(dāng)前編譯實(shí)例的id,這里可以通過 Vue 組件的_uid來唯一標(biāo)識(shí)(每個(gè)Vue實(shí)例都會(huì)有一個(gè)遞增的id,可以通過this._uid獲?。?/p>

另外,Vue 1.x 文檔也有提到另一個(gè)$mount()方法,可以實(shí)現(xiàn)類似的效果,在 Vue 2.x 文檔中,有 Vue.compile()方法,用于在render函數(shù)中編譯模板字符串,讀者可以結(jié)合來看。

內(nèi)聯(lián)模板inline-template

內(nèi)聯(lián)模板并不是什么新鮮東西,文檔中也有說明,只是平時(shí)幾乎用不到,所以也容易忽略。簡(jiǎn)短解說,就是把組件的 slot 當(dāng)做這個(gè)組件的模板來使用,這樣更為靈活:



    {{ data }}



因?yàn)槭褂昧?inline-template 內(nèi)聯(lián)模板,所以子組件不需要