都不是必須的,如果是普通組件那么只能是一個靜態html,如果是函數式組件, 那么可以直接使用props等函數式組件屬性。
函數式組件
<anchored-heading :level="1"> <span>Hello</span> world! </anchored-heading>
這個錨點標題組件是比較簡單的,沒有管理任何狀態,也沒有監聽任何傳遞給它的狀態,也沒有生命周期方法。實際上,它只是一個接受一些 prop 的函數。在這樣的場景下,我們可以將組件標記為 functional
,這意味它無狀態 (沒有響應式數據),也沒有實例 (沒有 this
上下文)。一個函數式組件就像這樣:
Vue.component('my-component', { functional: true, // Props 是可選的 props: { // ... }, // 為了彌補缺少的實例 // 提供第二個參數作為上下文 render: function (createElement, context) { // ... } })
注意:在 2.3.0 之前的版本中,如果一個函數式組件想要接收 prop,則 props
選項是必須的。在 2.3.0 或以上的版本中,你可以省略 props
選項,所有組件上的 attribute 都會被自動隱式解析為 prop。
當使用函數式組件時,該引用將會是 HTMLElement,因為他們是無狀態的也是無實例的。
在 2.5.0 及以上版本中,如果你使用了單文件組件,那么基於模板的函數式組件可以這樣聲明:
<template functional> </template>
組件需要的一切都是通過 context
參數傳遞,它是一個包括如下字段的對象:
props
:提供所有 prop 的對象children
:VNode 子節點的數組slots
:一個函數,返回了包含所有插槽的對象scopedSlots
:(2.6.0+) 一個暴露傳入的作用域插槽的對象。也以函數形式暴露普通插槽。data
:傳遞給組件的整個數據對象,作為createElement
的第二個參數傳入組件parent
:對父組件的引用listeners
:(2.3.0+) 一個包含了所有父組件為當前組件注冊的事件監聽器的對象。這是data.on
的一個別名。injections
:(2.3.0+) 如果使用了inject
選項,則該對象包含了應當被注入的 property。
在添加 functional: true
之后,需要更新我們的錨點標題組件的渲染函數,為其增加 context
參數,並將 this.$slots.default
更新為 context.children
,然后將 this.level
更新為 context.props.level
。
因為函數式組件只是函數,所以渲染開銷也低很多。
在作為包裝組件時它們也同樣非常有用。比如,當你需要做這些時:
- 程序化地在多個組件中選擇一個來代為渲染;
- 在將
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 ) } })