vue 函数式组件/高阶组件(HOC)

300 阅读2分钟
函数式组件的特点
  • Stateless(无状态):组件自身是没有状态的;
  • Instanceless(无实例):组件自身没有实例,也就是没有this;
  • 由于函数式组件拥有的这两个特性,我们就可以把它用作高阶组件(High order components),所谓高阶,就是可以生成其它组件的组件。
js文件中创建函数组件
  1. js文件内容
export default {
    name: 'functionComponent',  // 组件名称
    props: {   // 接受传递的值
        name: String
    },
    functional: true,  // 定义一个函数式组件
    render: function (createElement, context) {  // 渲染函数
        console.log(context)
        // 函数式组件中没有shit,context中包含了所有的内容信息 
        let { data, children, props } = context
        /**
        * createElement 方法接受三个参数
        * 第一个参数:可以是 {String | Object | Function}不管是那种类型,最终返回到都是需要渲染的普通DOM标签 例如:'div' 'button'
        * 第二个参数:是一个对象,这个参数是可选的,定义了需要渲染组件的参数,相对于普通HTML标签的属性是一样的。
        * 第三个参数:类型{String | Array},子级虚拟节点 (VNodes),由 `createElement()` 构建而成,也可以使用字符串来生成“文本虚拟节点”。可选。例如[
        */
        return createElement(
            'div',  // 第一个参数
            // 第二个参数
            {      
                ...data,
                style: {
                    color: 'red',
                    fontSize: '14px',
                    marginTop: '20px'
                },
            },
            //  第三个参数
            [
                '先写一些文字',   // 自定义的一段文本
                props.name,       // 传递过来的值
                createElement('h1', '一则头条'),  //  由 `createElement()` 构建而成子级虚拟节点 (VNodes)
                createElement('button', 'Click'), //  由 `createElement()` 构建而成子级虚拟节点 (VNodes)
            ]
        )
    }
}
  1. 组件页面中使用
// 引入
import FunctionComponent from './functionComponent'
// 注册
components:{
    FunctionComponent
},
// 页面中使用
<FunctionComponent name="JP" @click="fn" ><p>像不像Slot</p></FunctionComponent>
在组件中的components中直接创建函数组件
    // 组件的components中直接创建,在页面中直接使用
    components:{
        FunctionComponent:{
            functional:true,
            props:{
                name:String,
                info:Object,
                render:Function
            },
            render:(createElement,context)=>{
                console.log(context)
                return createElement('button',context.data,['JP_',...context.children])
            }
        },
    },