Vue3
1. Vue3和Vue2的区别
- vue3 用组合式API代替选项API,提高阅读性、方便代码维护
- vue3 体积更小, 更便于复用功能代码,封装组件
- 使用proxy代替defineProperty来实现数据劫持(后面会详细说明)
- diff算法优化。 静态虚拟节点添加静态标记,不进行diff比较,直接复用真实的DOM
- 更好的支持typescript
- vite打包工具,启动更快
- 引入树摇
tree-shaking优化,在vite打包压缩时,将无用的模块过滤掉(比如element中,不需要的样式,组件等)
详细说明 vue2和 vue3数据响应式
- vue2响应式
- 对象类型:使用defineProperty对对象已有属性的读取、修改进行劫持(侦听/监视)
- 数组类型:重写更新数组的方法实现对元素修改的劫持
- 问题:对象直接添加、修改或对数组的下标进行替换、更新时,页面不会自动更新
- vue3响应式
- 使用proxy(代理)拦截对data任意属性的操作:读、增、改等
- 通过Reflect(反射):动态对被代理对象的相应属性进行特定操作
- 解决了vue2不更新页面的问题
- 给对象添加新属性
- 删除对象已有属性
- 通过下标替换元素时
2.常用的组合API
- setup: 所有组合API都在此选项函数中执行(它本身并不是组合API)
- ref : 一般用来定义基本类型数据的响应式
- reactive: 一般用来定义包含多个数据的对象/数组的响应式
- computed: 定义基于已有响应式数据的计算属性(getter/setter)
- watch与watchEffect: 监视响应式数据
- toRefs: 将一个被代理对象中所有属性都转换为ref对象
- onMounted: 当初始化挂载显示后执行回调
3. vue3生命周期
- setup函数
- onBeforeMount
- onMounted
- onBeforeUpdate
- onUpdated
- onBeforeUnmount
- onUnmounted
3. 状态管理pinia
- Pinia 没有
mutations, 在actions中可以直接同步更新state或异步更新state - Pinia中可以包含多个store, 而且相互独立, 且不进行合并, 没有模块的嵌套结构
- 无需手动注册 store,创建出的store直接就可以使用
- 更好的
TypeScript支持, 提示补全很到位
4. vue-router@4
- 创建路由器有变化
- new Router 变成 createRouter
- createWebHistory()与createWebHashHistory() 取代了 'history' 与 'hash'
- 动态添加路由
- 以前可以一次添加多个: router.addRoutes(routes)
- 现在只能一次添加一个: router.addRoute(route)
- 通配路由的path变了
- 以前的path: *
- 现在的path: /:pathMatch(.*)
5. vue3&ts语法
- 声明接收props
// 定义接口, 约束prop
interface Props {
count: number;
updateCount(val: number): void;
}
defineProps<Props>()
- 自定义事件
const emit = defineEmits<{
(e: 'click', val: object): void
}>()
// 模板中分发事件
$emit('increment', 5)
-
全局事件总线
- vue本身不再提供事件总线的API. 没有$on方法
- 需要使用
mitt或pubsub-js第三方工具包
-
v-model的本质
- 原生标签上: 动态value和原生的input监听
<input type="text" :value="msg1" @input="msg1=($event.target as HTMLInputElement).value" /> - 组件标签上: 动态modelValue(默认)和自定义的input监听
<custom-input title="消息2" :modelValue="msg2" @update:modelValue="msg2=$event" /> - 没有了.sync
- 原生标签上: 动态value和原生的input监听
-
通过ref得到真实DOM
// 使用ref标识子组件
<Son ref="sonRef"/>
// 定义ref
const sonRef = ref<InstanceType<typeof Son> | null>(null)
// 通过ref得到子组件对象, 调用其暴露的方法
sonRef.value?.borrowMoney(num)