前言
修改测试项目 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数据的可读属性。