功能组件在React社区中非常受欢迎,它们允许通过传递一个背景来创建简单的组件,使它们非常简单。
什么是功能组件
你可以认为一个功能组件是函数的等价,带到组件世界. 也就是说,它是一个组件,它采取了渲染的背景,并返回了渲染的HTML。
一个功能组件是:
- 无状态:它不保留任何状态
- 无时:它没有实例,因此没有
此
由于其性质,它的两种用例是演示式和高级序列组件。
创建一个功能组件
要定义一个功能组件,你必须创建一个具有功能: true
属性和一个 返回函数的对象。
1[label FunctionalButton.js]
2export default {
3 functional: true,
4 render(createElement, context) {
5 return createElement('button', 'Click me');
6 }
7};
提供背景
您在渲染
函数中看到的背景
参数被称为 渲染背景. 它是一个包含以下属性的对象:
props
children
slots
:函数返回一个 slots对象parent
listeners
injections
data
:一个包含所有以前的属性 的对象
假设您有一个 App.vue 组件,您可以导入 FunctionalButton.js 来使用其模板:
1[label App.vue]
2<template>
3 <FunctionalButton>
4 Click me
5 </FunctionalButton>
6</template>
这样,现在可以使用孩子
属性,而不是硬代码的点击我
:
1[label FunctionalButton.js]
2export default {
3 functional: true,
4 render(createElement, { children }) {
5 return createElement("button", children);
6 }
7};
通过普罗普斯
让我们用这个组件有更多的乐趣;没有禁用
属性的按钮是什么?
1[label App.vue]
2<template>
3 <FunctionalButton>
4 Click me
5 </FunctionalButton>
6</template>
1[label FunctionalButton.js]
2export default {
3 functional: true,
4 render(createElement, { props, children }) {
5 return createElement('button', { attrs: props }, children);
6 }
7};
请记住,按钮是一个HTML标签,而不是一个组件,所以‘props’不会产生任何效果,所以为什么使用‘attrs’属性从‘createElement’参数中,这会给渲染背景带来略有不同的结构。
触发事件
鉴于功能组件没有实例,事件倾听者来自context.listeners
属性上的母子。
考虑到这一点,您可以实施这样的点击
事件:
1[label App.vue]
2<template>
3 <FunctionalButton @click="log">
4 Click me
5 </FunctionalButton>
6</template>
1[label FunctionalButton.js]
2export default {
3 functional: true,
4 render(createElement, { props, listeners, children }) {
5 return createElement(
6 'button',
7 {
8 attrs: props,
9 on: {
10 click: listeners.click
11 }
12 },
13 children
14 );
15 }
16};
大家一起
请记住,数据
包括所有createElement
背景属性,所以我们可以这样重写 FunctionalButton:
1[label FunctionalButton.js]
2export default {
3 functional: true,
4 render(createElement, { data, children }) {
5 return createElement( 'button', data, children );
6 }
7};
想想创建一个包装组件,也被称为 Higher Order Component(HOC),可以为组件添加一些东西是多么容易。
1createElement('button', data, ['Hello ', ...children]);
包装上
在这里,我一直在使用渲染函数语法来显示较低级别的细节,但我们将在未来的文章中探索其他方法来渲染功能元件。
查找此按钮示例中的所有代码在 this Sandbox