# 介绍
函数式组件是可以在没有状态管理的情况下,实现组件逻辑的函数。在组件中将其标记为functional。
# 模版定义
<template functional>
<div>{{ props.msg }}</div>
</template>
<script>
export default {
props: {
msg: {
type: String,
default: 'Hello World',
},
},
};
</script>
# render函数定义
export default {
name: 'FunctionalComponent',
functional: true,
props: {
msg: {
type: String,
default: 'Hello World',
}
},
render(h, context) {
return h('div', {}, [h('h2'), {}, context.props.msg])
}
}
// render函数 context 参数介绍
组件需要的一切都是通过 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。
# 定义一个函数式组件Button
# render函数方式
export default {
name: 'MyButton',
functional: true,
props: {
person: {
type: Object,
default: () => ({ name: '张小小', age: 23 }),
},
},
render(h, { props, scopedSlots, listeners }) {
// NOTE default 是关键字,需要重命名
const { left, right, default: _defaultSlot } = scopedSlots
const defaultSlot = (_defaultSlot && _defaultSlot({ person: props.person })) || <span>按钮</span>
const leftSlot = (left && left()) || ''
const rightSlot = right && right(props.person)
const button = h(
'button',
{
on: {
click: () => {
listeners.click && listeners.click(props.person)
},
},
},
[defaultSlot]
)
return (
<div>
{leftSlot}
{button}
{rightSlot}
</div>
)
},
}
# 模版定义方式
<template functional>
<div>
<slot name="left"></slot>
<button @click="listeners['click'] && listeners['click'](props.person)">
<slot :person="props.person">
<span>按钮</span>
</slot>
</button>
<slot name="right" :age="props.age"></slot>
</div>
</template>
<script>
export default {
name: 'MyButton',
props: {
person: {
type: Object,
default: () => ({ name: '张小小', age: 24 }),
},
},
}
</script>
# 注意事项
- 函数式组件不能使用
this - 函数式组件不能使用
data - 函数式组件不能使用
watch - 函数式组件不能使用
computed - 函数式组件不能使用
methods - 函数式组件不能使用
生命周期钩子