函数式组件的实现相对容易。一个函数式组件本质上就是一个普通函数,该函数的返回值是虚拟DOM。
在用户接口层面,一个函数式组件就是一个返回虚拟DOM的函数,如下面的代码所示:
function MyFuncComp(props){
return {type:'h1',children: porps.title}
}
函数式组件没有自身状态,但仍然可以接收由外部传入的props。为了给函数式组件定义props,需要在组件函数上添加静态的props属性,如下面代码所示:
function MyFuncComp(props){
return {type:'h1',children:props.title}
}
// 定义props
MyFuncComp.props = {
title: String
}
在有状态组件的基础上,实现函数式组件将变得非常简单,因为挂载组件的逻辑可以复用mountComponent函数,为此,需要在patch函数内支持函数类型的vnode.type,如下面patch函数的代码所示:
function patch(n1,n2,container, anchor){
if(n1 && n1.type !== n2.type){
unmount(n1)
n1 = null
}
const {type} = n2
if(typeof type === 'string'){
// 省略部分代码
}else if(type === Text) {
// 省略部分代码
}else if(type === Fragment) {
// 省略部分代码
}else if(type === 'object' || typeof type === 'function') {
// component
if(!n1){
mountComponent(n2,container,anchor)
}else{
patchComponent(n1,n2,anchor)
}
}
}
在patch函数内部,通过检测vnode.type的类型来判断组件的类型
- 如果vnode.type是一个对象,则它是一个有状态组件,并且vnode.type是组件选项对象;
- 如果vnode.type是一个函数,则它是一个函数式组件
下面是修改后的mountComponent函数,其支持挂载函数式组件:
function mountComponent(vnode,container,anchor){
// 检查是否是函数式组件
const isFunctional = typeof vnode.type === 'function'
let componentOptions = vnode.type
if(isFunctional){
// 如果是函数式组件,则将vnode.type作为渲染函数,将vnode.type.props作为props选项定义即可
componentOptions = {
render:vnode.type,
props: vnode.type.props
}
}
// 省略部分代码
}
实现对函数式组件的兼容非常简单。首先,在mountComponent函数内检查组件的类型,如果是函数式组件,则直接将组件函数作为组件选项对象的render选项,并将组件函数的静态props属性作为组件的props选项即可。
当然,出于更加严谨的考虑,我们需要通过isFunctional变量实现选择性地执行初始化逻辑,
到此这篇关于Vue函数式组件专篇深入分析的文章就介绍到这了,更多相关Vue函数式组件内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!