# 前言
在开启本小节之前,我们先看一个有意思的示例,组件上有一个动态文本节点 {{ msg }},但是却有 2 处定义了 msg 响应式数据;另外有一个按钮,点击后会修改响应式数据。
html
复制代码<template>
<p>{{ msg }}</p>
<button @click="changeMsg">点击试试</button>
</template>
<script>
import { ref } from 'vue'
export default {
data() {
return {
msg: 'msg from data'
}
},
setup() {
const msg = ref('msg from setup')
return {
msg
}
},
methods: {
changeMsg() {
this.msg = 'change'
}
}
}
</script>
@前端进阶之旅: 代码已经复制到剪贴板
思考一下:
- 界面显示的内容是什么?
- 点击按钮后,修改的是哪部分的数据?是
data中定义的,还是setup中的呢?
先别急着找答案,相信你阅读完这一节,一定会得到答案。
上一节,我们知道了根组件在初始化渲染的过程中,会执行 mountComponent 的函数:
function mountComponent(initialVNode, container, parentComponent) {
// 1. 先创建一个 component instance
const instance = (initialVNode.component = createComponentInstance(
initialVNode,
parentComponent
));
// 2. 初始化组件实例
setupComponent(instance);
// 3. 设置并运行带副作用的渲染函数
setupRenderEffect(instance, initialVNode, container);
}
@前端进阶之旅: 代码已经复制到剪贴板
上文,我们简单介绍了关于 setupComponent 函数的作用是为了对实例化后的组件中的属性做一些优化、处理、赋值等操作。本小节我们将重点介绍 setupComponent 的内部实现和作用。
# 初始化组件实例
我们再来回顾一下 setupComponent 在源码中的实现:
export function setupComponent(instance, isSSR = false) {
const { props, children } = instance.vnode
<