91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue.js之slot深度復制的示例分析

發布時間:2021-08-13 10:15:42 來源:億速云 閱讀:139 作者:小新 欄目:web開發

這篇文章給大家分享的是有關Vue.js之slot深度復制的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

前言

在Vue中,slot是一個很有用的特性,可以用來向組件內部插入一些內容。slot就是“插槽”的意思,用大白話說就是:定義組件的時候留幾個口子,由用戶來決定插入的內容。

例如我們定義一個組件MyComponent,其包含一個slot:

Vue.component('MyComponent', {
 template: `
 <div>
  <slot></slot>
 </div>
 `
})

當調用<MyComponent>123</MyComponent>時,會渲染為如下DOM結構:

<div>
 123
</div>

現在又有新需求了,我們希望調用<MyComponent>123</MyComponent>時,渲染出這樣的DOM結構:

<div>
 123
 123
</div>

看起來很容易實現,即再為MyComponent添加一個slot:

Vue.component('MyComponent', {
 template: `
 <div>
  <slot></slot>
  <slot></slot>
 </div>
 `
})

渲染出的結構也確實如你所愿,唯一美中不足的是控制臺有一個小小的Warning:

Duplicate presence of slot "default" found in the same render tree

如果你不是強迫癥患者,這時候你可以收工安心回家睡覺了。直到有一天你的同事向你抱怨,為什么向MyComponent插入一個自定義組件會渲染不出來?

例如有一自定義組件MyComponent2:

Vue.component('MyComponent2', {
 template: `
 <div>456</div>
 `
})

當調用<MyComponent><MyComponent2></MyComponent2></MyComponent>時,預期渲染為如下DOM結構:

<div>
 <div>456</div>
 <div>456</div>
</div>

為什么不能正常工作呢?估計是前面的那個Warning搞得鬼,通過查詢發現在Vue 2.0中不允許有重名的slot:

重名的 Slots 移除

同一模板中的重名 已經棄用。當一個 slot 已經被渲染過了,那么就不能在同一模板其它地方被再次渲染了。如果要在不同位置渲染同一內容,可一用 prop 來傳遞。

文檔中提示可以用props來實現,然而在我的用例中顯然是不合適的。經過搜索后,最靠譜的方法是手寫render函數,將slot中的內容復制到其他的位置。

將之前的MyComponent改為render函數的方式定義:

Vue.component('MyComponent', {
 render (createElement) {
 return createElement('div', [
  ...this.$slots.default,
  ...this.$slots.default
 ])
 }
})

在上面的定義中我們插入了兩個this.$slots.default,測試下能不能正常工作。然而并沒有什么卵用,Vue文檔在render函數這一章有以下說明:

VNodes 必須唯一

所有組件樹中的 VNodes 必須唯一

這意味著我們不能簡單地在不同位置引用this.$slots.default,必須對slot進行深度復制。深度復制的函數如下:

function deepClone(vnodes, createElement) {
 function cloneVNode (vnode) {
 const clonedChildren = vnode.children && vnode.children.map(vnode => cloneVNode(vnode));
 const cloned = createElement(vnode.tag, vnode.data, clonedChildren);
 cloned.text = vnode.text;
 cloned.isComment = vnode.isComment;
 cloned.componentOptions = vnode.componentOptions;
 cloned.elm = vnode.elm;
 cloned.context = vnode.context;
 cloned.ns = vnode.ns;
 cloned.isStatic = vnode.isStatic;
 cloned.key = vnode.key;
 return cloned;
 }
 const clonedVNodes = vnodes.map(vnode => cloneVNode(vnode))
 return clonedVNodes;
}

上面的核心函數就是cloneVNode() ,它遞歸地創建VNode,實現深度復制。VNode的屬性很多,我并不了解哪些是關鍵屬性,只是參照著Vue的源碼一并地復制過來。

基于以上函數,我們更改MyComponent的定義:

Vue.component('MyComponent', {
 render (createElement) {
 return createElement('div', [
  ...this.$slots.default,
  ...deepClone(this.$slots.default, createElement)
 ])
 }
})

經測試,一切正常。

感謝各位的閱讀!關于“Vue.js之slot深度復制的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

屏东市| 女性| 合肥市| 尚义县| 上高县| 四子王旗| 普安县| 中方县| 门源| 威远县| 鹰潭市| 富平县| 汾西县| 梁河县| 平泉县| 宁南县| 屯昌县| 五峰| 荃湾区| 苏尼特左旗| 安吉县| 湖州市| 青阳县| 遂平县| 焦作市| 麻栗坡县| 兴化市| 郎溪县| 孝昌县| 龙海市| 耿马| 武邑县| 昌吉市| 珠海市| 额敏县| 南投市| 兖州市| 汝南县| 天水市| 涟源市| 清新县|