|Vue.js源码全方位深入解析,快人一步进名企-完结( 四 )
return props[key
else if (setupState !== EMPTY_OBJ && hasOwn(setupState key)) <{p>
accessCache[key
= 0
// 从 setupState 中取数据
return setupState[key
else if (data !== EMPTY_OBJ && hasOwn(data key)) <{p>
accessCache[key
= 1
// 从 data 中取数据
return data[key
else if (
type.props &&
hasOwn(normalizePropsOptions(type.props)[0
key)) <{p>
accessCache[key
= 2
// 从 props 中取数据
return props[key
else if (ctx !== EMPTY_OBJ && hasOwn(ctx key)) <{p>
accessCache[key
= 3
// 从 ctx 中取数据
return ctx[key
else <{p>
// 都取不到
accessCache[key
= 4
const publicGetter = publicPropertiesMap[key
let cssModule globalProperties
// 公开的 $xxx 属性或方法
if (publicGetter) <{p>
return publicGetter(instance)
else if (
// css 模块 , 通过 vue-loader 编译的时候注入
(cssModule = type.__cssModules) &&
(cssModule = cssModule[key
)) <{p>
return cssModule
else if (ctx !== EMPTY_OBJ && hasOwn(ctx key)) <{p>
// 用户自定义的属性 , 也用 `$` 开头
accessCache[key
= 3
return ctx[key
else if (
// 全局定义的属性
((globalProperties = appContext.config.globalProperties)
hasOwn(globalProperties key))) <{p>
return globalProperties[key
else if ((process.env.NODE_ENV !== 'production') &&
currentRenderingInstance && key.indexOf('__v') !== 0) <{p>
if (data !== EMPTY_OBJ && key[0
=== '$' && hasOwn(data key)) <{p>
// 如果在 data 中定义的数据以 $ 开头 , 会报警告 , 因为 $ 是保留字符 , 不会做代理
warn(`Property ${JSON.stringify(key) must be accessed via $data because it starts with a reserved ` +
`character and is not proxied on the render context.`)
else <{p>
// 在模板中使用的变量如果没有定义 , 报警告
warn(`Property ${JSON.stringify(key) was accessed during render ` +
`but is not defined on instance.`)
可以看到 , 函数首先判断 key 不以 $ 开头的情况 , 这部分数据可能是 setupState、data、props、ctx 中的一种 , 其中 data、props 我们已经很熟悉了;setupState 就是 setup 函数返回的数据 , 稍后我们会详细说;ctx 包括了计算属性、组件方法和用户自定义的一些数据 。 如果 key 不以 $ 开头 , 那么就依次判断 setupState、data、props、ctx 中是否包含这个 key , 如果包含就返回对应值 。 注意这个判断顺序很重要 , 在 key 相同时它会决定数据获取的优先级 , 举个例子:
<template>
<p>
</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
</script>
我们在 data 和 setup 中都定义了 msg 变量 , 但最终输出到界面上的是\"msg from setup\" , 这是因为 setupState 的判断优先级要高于 data 。 再回到 get 函数中 , 我们可以看到这里定义了 accessCache 作为渲染代理的属性访问缓存 , 它具体是干什么的呢?组件在渲染时会经常访问数据进而触发 get 函数 , 这其中最昂贵的部分就是多次调用 hasOwn 去判断 key 在不在某个类型的数据中 , 但是在普通对象上执行简单的属性访问相对要快得多 。 所以在第一次获取 key 对应的数据后 , 我们利用 accessCache[key
- 华为荣耀|荣耀X50全方位升级,1英寸大底+天玑8200,有点意外
- 编程|小米13 Pro全方位揭晓,陶瓷机身+1英寸超大底,有高端味了
- 陶瓷后壳|有高端味了!小米13 Pro陶瓷版全方位揭晓
- 陶瓷后壳|温润如玉!小米13 Pro陶瓷版全方位揭晓
- 雷军|直屏+直边!雷军晒小米13全方位外观图:比iPhone 14手感好
- 影驰|次旗舰全方位领先老卡皇!影驰RTX 4080 16GB星曜 OC评测:超频提升6%
- 徕卡|Ultra能力全面下放!小米13全方位继承徕卡影像
- 基于AM5708开发板——开箱初探+环境搭建、源码编译
- 年末送礼选关怀,全方位健康助手:dido E10S Pro智能手表上手
- |荣耀X50全方位升级,新增16GB版本,开启大存储时代
