大家请先看这个问题:https://segmentfault.com/q/1010000041497872/a-1020000041498716,看看你们能不能给出答案。
Vue3 增加了 Composition API,是一个很大的改进。一方面可以提升代码复用效率,另一方面通过更好的 tree-shaking,打包体积也会小很多:作为参考,前面博客中提到 mywordle.org,打包后 vendor.js 只有区区 96kB,里面可是用到了 vue3 全家桶。
最初的 Composition API 是在 Options API 基础上改进的,不仅需要使用 setup()
函数,还要在 setup()
末尾返回所有模版需要用到的变量和函数,使用起来相当繁琐。于是后面就增加了 <script setup>
语法糖:
- 从生命周期来讲,相当于
created
支持顶层await
(因为实际上这还是个setup()
函数)- 所有
import
的内容、声明的变量和函数默认都返回 - 至少省了两层缩进
但是由于少了 export
,没法传参,也不方便暴露接口,所以作者就增加了三个工具方法:
defineProps
defineEmits
defineExpose
注意,这三个工具方法只是帮助 Vue 编译器构建组件,它们不会出现在最终代码里,我们也不能预期它们会像普通函数那样工作。比如下面这段代码,就得不到常见的结果:
const props = defineProps({
userMenu: {
type: Array,
default() {
return []
}
}
})
console.log(props) // 该对象中的 userName 总是有值
console.log(props.userMenu) // 该对象始终是一个空数据
因为 Vue 是 MVVM 框架,它的视图会在数据变化后自动渲染,于是通常情况下,props
里的值什么时候被填充并不重要,Vue 开发团队也不想追求 defineProps
工作的一般化。所以使用目前版本,上面这段代码,访问到的 props
是的 reactive
对象,数据被填充后就能看到 userName
里有值;而 props.userMenu
在访问时还没有被填充,所以得到的是 default()
返回的默认值,一直是空的。
同时大家还要知道,console.log()
输出的是对象的指针,而非快照。所以里面的值只跟你展开时有关,跟运行时关系不大。
欢迎吐槽,共同进步