每天學習一個vue知識點呀
函式式元件特點:
- 沒有管理任何狀態
- 沒有監聽任何傳遞給它的狀態
- 沒有生命週期方法
- 它只是接收一些prop的函
我們將這樣的元件標記為functional:
- 無狀態 == 無響應式資料
- 無例項 == 無this上下文
函式式元件的優點:
- 渲染開銷低,因為函式式元件只是函式;
函式式元件基本寫法:
{
functional: true,
// Props 是可選的
props: {
// ...
},
// 為了彌補缺少的例項
// 提供第二個引數作為上下文
render: function (createElement, context) {
// ...
}
}
複製程式碼
元件需要的一切都是通過 context 引數傳遞,它是一個包含如下欄位的物件:
- props: 提供所有prop的物件
- children:VNode 子節點的陣列
- slots: 一個函式,返回了包含所有插槽的物件
- scoptedSlots:(2.6.0) 一個暴露傳入的作用域插槽的物件,也以函式形式暴露普通插槽
- data:傳遞個元件的整個資料物件,作為createElement的第二個引數傳入元件
- parent:對父元件的引用
- listeners:(2.3.0+) 一個包含了:所有父元件為當前元件祖冊的事件監聽器物件,是data.on的一個別名
- injections:(2.3.0+) 如果使用了inject選項,則改物件包含了:應當被注入的屬性;
使用場景1:包裝元件
-
程式化地在多個元件中選擇一個來代為渲染;
-
在將 children、props、data 傳遞給子元件之前操作它們; 下面是一個 smart-list 元件的例子,它能根據傳入 prop 的值來代為渲染更具體的元件:
var EmptyList = { /* ... */ } var TableList = { /* ... */ } var OrderedList = { /* ... */ } var UnorderedList = { /* ... */ } Vue.component('smart-list', { functional: true, props: { items: { type: Array, required: true }, isOrdered: Boolean }, render: function (createElement, context) { function appropriateListComponent () { var items = context.props.items if (items.length === 0) return EmptyList if (typeof items[0] === 'object') return TableList if (context.props.isOrdered) return OrderedList return UnorderedList } return createElement( appropriateListComponent(), context.data, context.children ) } }) 複製程式碼
slots() 和children的對比
分析:
從字面意思顯而易見:
-
children,可以獲取當前元件節點的所有的子節點;
-
slots()函式返回了所有的插槽物件; 舉例:
<my-functional-component> <p v-slot:foo> first </p> <p>second</p> </my-functional-component> 複製程式碼
對於以上示例元件:
- children 會給你兩個段落標籤;
- slots().default 只會傳遞第二個匿名段落標籤
- slots().foo 會傳遞第一個具名段落標籤
總結:
- 你可以選擇使用slots()讓元件感知某個插槽機制,也可以簡單地通過傳遞 children,移交給其它元件去處理