|Vue.js源码全方位深入解析,快人一步进名企-完结( 五 )
去缓存数据 , 下一次再次根据 key 查找数据 , 我们就可以直接通过 accessCache[key
获取对应的值 , 就不需要依次调用 hasOwn 去判断了 。 这也是一个性能优化的小技巧 。
如果 key 以$开头 , 那么接下来又会有一系列的判断 , 首先判断是不是 Vue.js 内部公开的$xxx 属性或方法(比如 $parent);然后判断是不是 vue-loader 编译注入的 css 模块内部的 key;接着判断是不是用户自定义以 $开头的 key;最后判断是不是全局属性 。 如果都不满足 , 就剩两种情况了 , 即在非生产环境下就会报两种类型的警告 , 第一种是在 data 中定义的数据以$开头的警告 , 因为$是保留字符 , 不会做代理;第二种是在模板中使用的变量没有定义的警告 。 接下来是 set 代理过程 , 当我们修改 instance.ctx 渲染上下文中的属性的时候 , 就会进入 set 函数 。 我们来看一下 set 函数的实现:
const PublicInstanceProxyHandlers = <{p>
set ({ _: instancekey value) <{p>
const { data setupState ctx= instance
if (setupState !== EMPTY_OBJ && hasOwn(setupState key)) <{p>
// 给 setupState 赋值
setupState[key
= value
else if (data !== EMPTY_OBJ && hasOwn(data key)) <{p>
// 给 data 赋值
data[key
= value
else if (key in instance.props) <{p>
// 不能直接给 props 赋值
(process.env.NODE_ENV !== 'production') &&
warn(`Attempting to mutate prop \"${key\". Props are readonly.` instance)
return false
if (key[0
=== '$' && key.slice(1) in instance) <{p>
// 不能给 Vue 内部以 $ 开头的保留属性赋值
(process.env.NODE_ENV !== 'production') &&
warn(`Attempting to mutate public property \"${key\". ` +
`Properties starting with $ are reserved and readonly.` instance)
return false
else <{p>
// 用户自定义数据赋值
ctx[key
= value
return true
结合代码来看 , 函数主要做的事情就是对渲染上下文 instance.ctx 中的属性赋值 , 它实际上是代理到对应的数据类型中去完成赋值操作的 。 这里仍然要注意顺序问题 , 和 get 一样 , 优先判断 setupState , 然后是 data , 接着是 props 。 我们对之前的例子做点修改 , 添加一个方法:
<template>
<p>< msg ></p>
<button @click=\"random\">Random msg</button>
</template>
<script>
import { reffrom 'vue'
export default <{p>
data() <{p>
return <{p>
msg: 'msg from data'
setup() <{p>
const msg = ref('msg from setup')
return <{p>
msg
methods: <{p>
random() <{p>
this.msg = Math.random()
</script>
我们点击按钮会执行 random 函数 , 这里的 this 指向的就是 instance.ctx , 我们修改 this.msg 会触发 set 函数 , 所以最终修改的是 setupState 中的 msg 对应的值 。 注意 , 如果我们直接对 props 中的数据赋值 , 在非生产环境中会收到一条警告 , 这是因为直接修改 props 不符合数据单向流动的设计思想;如果对 Vue.js 内部以 $ 开头的保留属性赋值 , 同样也会收到一条警告 。 如果是用户自定义的数据 , 比如在 created 生命周期内定义的数据 , 它仅用于组件上下文的共享 , 如下所示:
export default <{p>created() <{p>this.userMsg = 'msg from user'
当执行 this.userMsg 赋值的时候 , 会触发 set 函数 , 最终 userMsg 会被保留到 ctx 中 。 最后是 has 代理过程 , 当我们判断属性是否存在于 instance.ctx 渲染上下文中时 , 就会进入 has 函数 , 这个在平时项目中用的比较少 , 同样来举个例子 , 当执行 created 钩子函数中的 'msg' in this 时 , 就会触发 has 函数 。
- 36氪独家|「蛙声科技」完成亿元级B轮融资,围绕音视频、大屏写作及SaaS构建全方位远程会议智能解决方案
- 直播回顾|不仅仅是重点!带你全方位解读FLIR智能巡检功能插件
- 华硕|轻薄性能全都要,全方位解读华硕无畏Pro15 2022:真的全能吗?
- 视频直播系统源码—需要哪些功能?
- 2022年6月|ManageEngine卓豪助力山东潍焦集团 | 全方位监控
- NothingPhone1近段时间可算是赚够了热度|Nothing Phone 1全方位渲染图曝光:全黑配色感觉
- 渲染图|Nothing Phone 1全方位渲染图曝光:全黑配色感觉大不一样
- 机箱|九州风神CK500WH幻城装机分享+12700K+3070雪鹰全方位实测
- vivo|平板圈的“战斗机”!vivo首款平板给你全方位体验
- 3D打印|源码系统和saas账号的区别