vue2和vue3的区别
对于 Vue3 的理解
性能更好了
- 响应式的原理换成了 Proxy
- 基本数据类型响应式还是通过 Object.defineProperty
- VNode Diff 算法进行了优化
体积更小了
- 删除了一些不太常用的 API,例如 filter,EventBus
- 按需导入,能配合 Webpack 支持 Tree Shaking
对 TS 支持更好了
Composition API
- 解决了对同一功能的数据和业务逻辑复用和维护的问题
- Vue2 实现一个功能或业务,需要在
data中定义数据,methods中定义方法,等等,每个业务的数据比较分散,不利于维护 - Vue3 中可以通过自定义 hooks 来抽离功能、业务,提高了复用性和维护性,使得 Vue3 也可以驾驭大型项目
新特性
创建一个 Vue3 项目
1 | // 按需导入一个 createApp 的函数 |
组合式 API
script setup 语法糖
defineProps接受数据defineEmits生成emit提交自定义事件defineExposescript setup中数据默认外界是不能访问的- 如果需要访问,通过此函数暴露一下
setup 中的参数
参数一:props
- 接受父组件传递的值
参数二:context
emit:传递自定义事件attrs:非props属性,父组件传递了值,子组件没有通过props接收slots:插槽信息
ref
包裹任意数据(普通和复杂)将其转换为响应式对象
注意
- JS 代码中使用
ref响应式对象要加.value - 模板中不用加,会自动加
- JS 代码中使用
reactive
- 可以把数组或对象包装成响应式的数据
reactive内部的数据如果是一个复杂数据类型的话(内部会借助reactive),其实它还是一个reactive对象
toRef
- 可以把响应式对象中某一个属性转换未单独的响应式
ref对象 - 并且转换后的数据和原对象是关联的
toRefs
- 可以把响应式对象中的多个属性转换为单独的响应式
ref对象
computed
如果要修改
computed数据,需要使用set的方式1
2
3
4
5
6
7
8
9
10state.fullName = computed({
get() {
return state.firstName + '~' + state.lastName
},
set(newFullName) {
const [firstName, lastName] = newFullName.split('~')
state.firstName = firstName
state.lastName = lastName
}
})
watch
监听 ref
1 | <template> |
- 监听
ref默认是浅监听,只监听一层,可以开启深度监听 - 只修改第一层
obj.vue也能触发监听 ref包裹的如果是一个对象,对象内部的复杂的数据类型其实是一个reactive类型的数据,那就符合监听reactive数据的特点
监听 reactive
- 强制开启深度监听,
deep配置无效 - 其实监听是
reactive内部的数据,对本身的修改不会触发监听 - 注意点
reactive内部的数据如果是一个复杂数据类型的话,其实它还是一个reactive,对这个数据的监听还是符合监听reactive数据的特点
监听普通值
watch(() => 普通值, () => {} )如果监听
reactive中的某个对象本身和内部数据的修改1
2
3
4
5watch(() => state.list, (newList) => {
localStorage.setItem('TODOS', JSON.stringify(newList))
}, {
deep: true
})
生命周期
1 | onBeforeMount(() => { |
- 把 Vue2 中的
beforeCreate和created变成了setup - 相同的生命周期可以写多次
setup
- 执行时机:比
beforeCreate和created还要早 - 内部没有
this,this是undefined - 使用
setup中的数据或方法需要在setup里面return
跨层级组件通信(依赖注入)
- 祖先通过
provide提供数据 - 后代通过
inject注入数据- 根据单项数据流的思想,注入过来的这个数据不能直接修改
- 如果想改需要祖先再提供一个修改数据的方法到后代
v-model
- 相当于
:modelValue和@update:modelValue的语法糖 - 把 Vue2 中的
v-model和.sync修饰符综合起来了,组件上也可以写多次v-model
