前言
修改测试项目 example 中 App.js,将其中一个子节点的渲染方式改成子组件,并传入数据count
。
新建 Foo.js
实现的 props 功能需要满足一下 3 点:
setup
接受props
传参,打印props
可以输出count
- 渲染函数中可以通过
this
获取到props
中count
对象 props
只读不可修改,修改count
值无效
运行 example 项目,目前是无法如期看到结果的。
依据以上总结的 3 项功能点,依次实现。
props传参
在setup
函数中接受props
参数,那需要实现的焦点可以放在setup
,component.ts 文件setupStatefulComponent
方法中处理了setup
函数,将函数执行结果赋给setupState
。
那setup
接受入参props
,即在setup
函数执行时,传入props
。props
数据来源于父组件中引用子组件时,在第 2 个参数位置传入了props
对象,也就是{count: 1}
,在创建父组件虚拟节点createVNode
方法中接受了这个props
对象,因此props
数据是vnode
上,而在setupStatefulComponent
方法里就可以通过instance.vnode.props
获取。
在setupComponent
方法中预留了initProps
位置,在这个方法中初始化props
,这里先简单的处理,把props
对象直接挂载到实例instance
上。
新建 componentProps.ts 文件,
在 component.ts 中引入,
在setup
函数中传入props
这样setup
中接受props
参数的功能点就实现了,我们期望的打印props
就能输出{count: 1}
可以看出控制台已经如期打印结果,但是在页面渲染中,this.count
无法识别,还是显示的undefined
。
this获取props对象
在之前的文章中,我们已经实现了setup
返回的值,可以渲染到页面上。实现方法PublicInstanceProxyHandlers
在 componentPublicInstance.ts 中。
验证
props只读不可修改
上面的验证结果可以看到,props
是可以修改的,但是官方的实现是props
不能修改,这样保证数据的单向传输。
之前文件已经实现了只读的方法,这里在引用的时候将其包裹即可,但是需要注意的是,props
的只读不是readonly
,而是shallowReadonly
只做了一层的只读限制。
验证
总结
本文实现了props
的 3 个功能点,setup
支持接受props
传参,渲染函数中可以通过this
获取到props
对象,最后就是props
只读不可修改。
功能点的实现是其次,更重要的是实现的思路,也就是写代码的思路。3 个功能点的实现是依次完成,实现的关键从setup
入手,既然setup
函数是有props
参数的,只需要在setup
调用时传入即可;渲染函数中this
能直接调取props
中对象,和this
能直接获取到setup
返回值是一样的,是实现上也是一样的,都是通过proxy
代理,那焦点自然就放到PublicInstanceProxyHandlers
的get
函数中;只读属性的实现,直接调用之前的实现方法,在传参时候调用,就保证了props
数据的可读属性。