Vue3相关

130 阅读3分钟

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方法
    • 需要使用mittpubsub-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
  • 通过ref得到真实DOM

  // 使用ref标识子组件
  <Son ref="sonRef"/>
  // 定义ref
  const sonRef = ref<InstanceType<typeof Son> | null>(null)
  // 通过ref得到子组件对象, 调用其暴露的方法
  sonRef.value?.borrowMoney(num)