這次給大家帶來實戰項目中使用Vue內slots/scoped slots,實戰項目中使用Vue內slots/scoped slots的注意事項有哪些,下面就是實戰案例,一起來看一下。
一直對Vue中的slot插槽比較感興趣,以下是自己的一些簡單理解,希望可以幫助大家更好的理解slot插槽
下面結合一個例子,簡單說明slots的工作原理
dx-li子組件的template如下:
傳遞的插槽內容'hello juejin!'會被編譯成dx-li子組件VNode節點的子節點。
渲染dx-li子元件,其中子元件的render函數:
module.exports={ render:function (){ var _vm=this; var _h=_vm.$createElement; var _c=_vm._self._c||_h; // 其中_vm._v 函数为renderSlot函数 return _c('li', {staticClass: "dx-li" }, [_vm._t("default", [_vm._v("你好 掘金!")])], 2 ) }, staticRenderFns: [] }
初始化dx-li子元件vue實例過程中,會呼叫initRender函數:
function initRender (vm) { ... // 其中_renderChildren数组,存储为 'hello juejin!'的VNode节点;renderContext一般为父组件Vue实例 这里为dx-ul组件实例 vm.$slots = resolveSlots(options._renderChildren, renderContext); ... }
其中resolveSlots函數為:
/** * 主要作用是将children VNodes转化成一个slots对象. */ export function resolveSlots ( children: ?Array<vnode>, context: ?Component ): { [key: string]: Array<vnode> } { const slots = {} // 判断是否有children,即是否有插槽VNode if (!children) { return slots } // 遍历父组件节点的孩子节点 for (let i = 0, l = children.length; i * 编译成span的VNode节点data = {attrs:{slot: "abc"}, slot: "abc"},所以这里删除该节点attrs的slot */ if (data && data.attrs && data.attrs.slot) { delete data.attrs.slot } /* 判断是否为具名插槽,如果为具名插槽,还需要子组件/函数子组件渲染上下文一致。主要作用: *当需要向子组件的子组件传递具名插槽时,不会保持插槽的名字。 * 举个栗子: * child组件template: * <p> * </p> <p><slot></slot></p> * <p><slot></slot></p> * * parent组件template: * <child><slot></slot></child> * main组件template: * <parent><span>foo</span></parent> * 此时main渲染的结果: * <p> * </p> <p><span>foo</span></p> <p></p> * */ if ((child.context === context || child.fnContext === context) && data && data.slot != null ) { const name = data.slot const slot = (slots[name] || (slots[name] = [])) // 这里处理父组件采用template形式的插槽 if (child.tag === 'template') { slot.push.apply(slot, child.children || []) } else { slot.push(child) } } else { // 返回匿名default插槽VNode数组 (slots.default || (slots.default = [])).push(child) } } // 忽略仅仅包含whitespace的插槽 for (const name in slots) { if (slots[name].every(isWhitespace)) { delete slots[name] } } return slots }</vnode></vnode>
然後掛載dx-li元件時,會呼叫dx-li元件render函數,在此過程中會呼叫renderSlot函數:
export function renderSlot ( name: string, // 子组件中slot的name,匿名default fallback: ?Array<vnode>, // 子组件插槽中默认内容VNode数组,如果没有插槽内容,则显示该内容 props: ?Object, // 子组件传递到插槽的props bindObject: ?Object // 针对<slot></slot> obj必须是一个对象 ): ?Array<vnode> { // 判断父组件是否传递作用域插槽 const scopedSlotFn = this.$scopedSlots[name] let nodes if (scopedSlotFn) { // scoped slot props = props || {} if (bindObject) { if (process.env.NODE_ENV !== 'production' && !isObject(bindObject)) { warn( 'slot v-bind without argument expects an Object', this ) } props = extend(extend({}, bindObject), props) } // 传入props生成相应的VNode nodes = scopedSlotFn(props) || fallback } else { // 如果父组件没有传递作用域插槽 const slotNodes = this.$slots[name] // warn duplicate slot usage if (slotNodes) { if (process.env.NODE_ENV !== 'production' && slotNodes._rendered) { warn( `Duplicate presence of slot "${name}" found in the same render tree ` + `- this will likely cause render errors.`, this ) } // 设置父组件传递插槽的VNode._rendered,用于后面判断是否有重名slot slotNodes._rendered = true } // 如果没有传入插槽,则为默认插槽内容VNode nodes = slotNodes || fallback } // 如果还需要向子组件的子组件传递slot /*举个栗子: * Bar组件: <p><slot></slot></p> * Foo组件:<p><bar><slot></slot></bar></p> * main组件:<p><foo>hello</foo></p> * 最终渲染:<p></p> <p>hello</p> */ const target = props && props.slot if (target) { return this.$createElement('template', { slot: target }, nodes) } else { return nodes } }</vnode></vnode>
scoped slots理解
dx-li子元件的template如下:
#其中_vm._u函數:
function resolveScopedSlots ( fns, // 为一个对象数组,见上文scopedSlots res ) { res = res || {}; for (var i = 0; i <p style="text-align: left;">子元件的後續渲染過程與slots類似。 scoped slots原理與slots基本上一致,不同的是編譯父元件模板時,會產生一個傳回結果為VNode的函數。當子元件比對到父元件傳遞作用域插槽函數時,呼叫該函數產生對應VNode。 </p><p>相信看了本文案例你已經掌握了方法,更多精彩請關注php中文網其它相關文章! </p><p>推薦讀取:</p><p><a href="http://www.php.cn/js-tutorial-402723.html" target="_blank">怎麼使用vue做出單頁應用前端路由</a><br></p><p><a href="http://www.php.cn/js-tutorial-402740.html" target="_blank" style="font-size: 14px;">#本地環境操作node伺服器跨域用法總結</a><br></p>
以上是實戰項目中使用Vue內slots/scoped slots的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

Python更適合數據科學和自動化,JavaScript更適合前端和全棧開發。 1.Python在數據科學和機器學習中表現出色,使用NumPy、Pandas等庫進行數據處理和建模。 2.Python在自動化和腳本編寫方面簡潔高效。 3.JavaScript在前端開發中不可或缺,用於構建動態網頁和單頁面應用。 4.JavaScript通過Node.js在後端開發中發揮作用,支持全棧開發。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

WebStorm Mac版
好用的JavaScript開發工具

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

記事本++7.3.1
好用且免費的程式碼編輯器

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器