Vue3 v.s Vue2

112 阅读2分钟

如何把Vue 2项目升级到Vue 3

使用Vue官方提供的工具(vue-codemod)和教程

1. Vue 3 搭建项目有三种方式

优点:远大于Webpack的开发速度,利用ES6中import会发送请求加载文件的特性,拦截请求,做一些预编译,省去了webpack冗长的打包时间;缺点是插件不够多

yarn global add create-vite-app  //安装vite
cva project-name  //创建项目目录
cd project-name
yarn   //安装依赖
yarn dev  
  • vue-cli脚手架工具
vue create 项目名
  • webpack打包工具

主要功能打包JS,不再是任务运行器;

loader用于加载文件、plugin用于扩展功能;

提供webpack-dev-server

2. Vue3的Template支持多个根标签,Vue2不支持

3. Vue3有createApp(),而Vue2的是new Vue()

createApp(组件)接受的是组件;

new Vue({template, render})接受的是对象;

4. 升级到 Vue 3 后的两种API风格

Options API(传统 Vue 2)

用包含多个选项的对象来描述组件的逻辑,例如 datamethods 和 mounted。选项所定义的属性都会暴露在函数内部的 this 上,它会指向当前的组件实例

组合式 API (Composition API 借鉴React的Hooks)

用导入的 API 函数来描述组件逻辑,用<script setup>标记告诉Vue编译时处理

  • 使用setup()入口函数,在beforeCreate和created之间执行
beforeCreate // 组件刚被创建出来,组件中的data,methods还没有初始化好
setup
created // 组件刚被创建出来,组件中的data,methods已经初始化好了
// ref函数只能监听简单类型的变化,不能监听复杂类型的变化(数组,对象等)
import { ref } from 'vue'
export default{
  setup(){
    let count=ref(0)
    //定义了一个名字为count的变量,且初始值为0,此值发生变化时vue会自动更新UI
  function myFn(){
      console.log(count.value)
      count.value+=1
    }
    return { count,myFn }
    //需要注意的是在组合API中定义方法,变量时要想在外部使用,必须return暴露出去
  }
}

为什么要有组合式 API?

  • 弥补选项式 API 中逻辑复用 mixins机制的缺陷
  • 逻辑集中:将一个逻辑关注点抽取重构到一个可复用的工具函数中
  • 更好的类型推导:支持TS

与选项式 API 的关系

  • 组合式 API 能够覆盖所有状态逻辑方面的需求。除此之外,只需要用到一小部分选项:propsemitsname 和 inheritAttrs
  • 组合式 API 更适用于大型的项目,选项式 API适用于中小型项目

5. 路由用于页面切换Vue Router 4

npm info vue-router versions  //查所有版本号
yarn add vue-router@4.0.0-beta.3    //安装vue-router
  • 初始化
import {createWebHashHistory, createRouter} from 'vue-router'
const history = createWebHashHistory()  //新建 history 对象
const router = createRouter({    //新建 router 对象
    history:history,
    routes:[
        {path:'', component:Frank},
        {path:'/xxx', component:Frank2}
    ]
})

const app = createApp(App)
app.use(router)
app.mount('#app')
//App.vue
//添加 <router-view><router-link> 
<template>
  <div>导航栏 | <router-link to="/">Frank</router-link>
  | <router-link to="/xxx">Frank 2</router-link>
  </div>
  <hr/>
  <router-view />
</template>

<script>

export default {
  name: 'App',
}
</script>

6. 编程模型:内部数据v.s.父子数据

  • 所有数据都在内部
setup(){
    const checked = ref(false)
    const toggle = ()=>{
        checked.value = !checked.value
    }
    return {checked, toggle}
}
  • 父子数据

值是从父组件拿到,该值需要通过input事件告诉父组件要改value,父组件改完之后,把最新的值再给子组件

setup(props, context){
    const toggle = ()=>{
        context.emit('input', !props.value)
    }
}

7. v-model用法

  • 简写效果
 <Switch :value="y" @input="y = $event" />
 <Switch v-model:value="y" />    //v-model简写
  • 要求 属性名任意,假设为x,事件名必须为'update:x'

  • Vue 2用的.sync修饰符也被弃用

8. 属性绑定

  • 默认所有属性都绑定到根元素
  • 取消绑定:inheritAttrs:false
  • 获取所有属性:$attrs或者context.attrs
  • 批量绑定属性:v-bind="$attrs"
  • 属性分开:const {size, ...rest}=context.attrs

9. Vue 3组件传值之props与attrs的区别

$attrs属性是props属性的加强版,用于简化vue组件传值,区别为:\

  1. props要先声明才能取值,attrs不用先声明
  2. props声明过的属性,attrs里不会再出现
  3. props不包含事件,attrs包含

10. 用ref()定义响应式变量

基于JS自身没有可以作用于所有值类型的"引用"机制,因此Vue提供了一个ref()方法来允许创建可以使用任何值类型的响应式ref

ref() 将传入参数的值包装为一个带 .value 属性的 ref 对象

const count = ref(0)
console.log(count)         // { value: 0 }
console.log(count.value)   // 0

count.value++
console.log(count.value)   // 1

ref() 让我们能创造一种对任意值的 “引用”,并能够在不丢失响应性的前提下传递这些引用。这个功能很重要,因为它经常用于将逻辑提取到组合函数中。

为 ref() 标注类型

  • 在调用 ref() 时传入一个泛型参数,来覆盖默认的推导行为
// 得到的类型:Ref<string | number>
const year = ref<string | number>('2020') 
year.value = 2020 // 成功!

// 推导得到的类型:Ref<number | undefined>
const n = ref<number>()