这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
前言
本文旨在帮助有vue2基础的同学,能够快速的入门vue3,所以前提条件就是需要会vue2。vue3已结发布有一段时间了,作为一个开发者自然是需要了解的,至于目前的项目中是否使用最新的vue3,根据目前的情况我是不太建议的,当然啦,自己作为练手的随意。不太建议的理由呢有以下几点:
- 大部分项目都是以前的老旧项目的不建议升级vue3,祖传代码动了就不得了。
- 新项目目前不建议使用vue3,等vue3稳定和生态健全后可以考虑。
- 人员的原因,毕竟vue3才出来,还是有有大部分人是没有去熟悉vue3的,一旦采用vue3各种成本增加,特别人力成本。
- 目前的生态大部分处于beta版本阶段。
当然今天我们就是来看看vue3相较于vue2有哪些改变,以及如何快速的入门vue3.想要快速入门vue3,最好的方法就是看vue2的升级指南,这里会告诉我们哪些是新增的、哪些是删除、哪些是修改的。
迁移指南
这部分呢在vue3官方网站上有很清楚的描述。这里截图给大家看看:
新增特性
非兼容的变更
了解了上面的变化,那么我们只需要找重点去看看具体的细节,如果知道了这些细节,那么vue3也就能够入门了。
组合式API
组合式API其实从字面上能够看出一些端倪,说白了就是把各种方式组合起来,像搭积木那样的。组合式API我们需要知道以下几个知识点:
setup组件选项
setup就是组合式API的入口,和之前的vue2中data、computed、watch、methods一样,定义了一个组合式API的入口。大致的setup组合式API如下:
<script>
import HelloWorld from '@/components/HelloWorld.vue'
export default {
name: 'Home',
components: {
HelloWorld
},
setup(props,context){
console.log(props,context)
}
}
</script>
复制代码
上面的setup里面就是组合式API。既然叫组合式,那么包括以前vue2中的data中的变量、生命周期函数、watch监听、computed计算属性、methods等都可以全部放到setup中。相信到这里大部分人应该都明白了,其实就是把之前分散到data、生命周期、watch、computed、methods中的部分现在全部整合到一起,这样的好处就是我们可以把一些业务或者逻辑抽离出来,然后那个地方需要就直接引入,比vue2中的方便了一些。那么接下来就来具体看看每一个部分到底怎么做就ok了。
带ref的响应式变量
这一部分说白了就是将之前放到data里面的变量整合到setup中,当然既然是响应式的变量,肯定不会是像js那样直接用var、let等定义了,所以呢就引入一个ref函数来声明响应式变量。具体用法如下:
import { ref } from 'vue'
const counter = ref(0)
console.log(counter) // { value: 0 }
console.log(counter.value) // 0
counter.value++
console.log(counter.value) // 1
复制代码
注意两点:1、ref必须在vue中引入;2、ref函数使任何响应式变量在任何地方起作用;3、获取值时需获取属性value
其实这里官方也说明了本质就是使用了值传递中的引用传递,ref函数中是定义时的默认值,这里可以定义为字符串、数组、对象、布尔等类型数据。
在setup内注册生命周期钩子
我们知道vue2中还有各种生命周期的各种钩子函数,那么作为vue3肯定也会包含在setup中,如下:
setup(props,context){
console.log(props,context)
onMounted(()=>{
console.log('666')
})
}
复制代码
这里只是列举了一个常用的生命周期钩子函数,大部分生命周期钩子函数都是类似的,如下图:
watch响应式更改
同样的watch也是可以放到setup中,在setup中watch作为一个函数接受三个参数:监听的值、回调、可选的配置。实例如下:
import { ref, watch } from 'vue'
setup(){
const counter = ref(0)
watch(counter, (newValue, oldValue) => {
console.log(counter.value)
})
}
复制代码
独立的computed属性
当然,计算属性也是一样的,实例如下:
import { ref, computed } from 'vue'
setup(){
const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)
counter.value++
console.log(counter.value) // 1
console.log(twiceTheCounter.value) // 2
}
复制代码
到次整个组合式API大致就这些内容,可能还要其他的一些东西没说到,比如响应式API中的reactive、toRef、toRefs等。
片段
片段这个其实就更加简单了,只是大家都被这个名字给搞糊涂了,片段就是vue2中template中必须且仅有一个子节点,那么在vue3中就不需要了,可以包含多个子节点了,如下:
<template>
<header />
<main />
<footer />
</template>
复制代码
全局API
全局API就是之前vue2中在main.js中定义的一些全局的API如:component全局组件、directive全局指令、mixin全局混入、use全局插件使用、config全局配置等。这些全局API在vue3中发生了很大改变,首先要说的就是vue的实例了,vue2中我们是通过new来获得vue的实例,现在vue3中有一个新的全局API来获取vue的实例:createApp。所以main.js文件中就发生了变化,如下:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(router).mount('#app')
复制代码
那么其他的全局API也是类似的,所以下面给出一个大部分的全局API使用:
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
const app = createApp(App)
app.component('my-component', {}) // 全局组件注册
app.directive('my-directive', {}) // 全局指令
app.mixin({}) // 全局混入
app.use(store).use(router).mount('#app')
复制代码
这里呢重点说说之前在vue2中挂载到vue原型上的一些工具等到了vue3中如何使用,之前在vue2中是这样的:
Vue.prototype.$http = () => {}
复制代码
那么到了vue3中就变了,如下:
const app = createApp({})
app.config.globalProperties.$http = () => {}
// 使用
const { proxy } = getCurrentInstance()
console.log(proxy.$http)
复制代码
模板指令
模板指令就是一些指令的变化,这里重点说几个常用的template、同一元素上使用v-if和v-for的优先级。
template列表渲染
template在列表渲染中在vue2都知道需要设置key到template中的子节点,如果存在分支的话,每个分支都需要,到了vue3中只需要将key设置到template上即可,如下:
<template v-for="item in list" :key="item.id">
<div>111</div>
<span>222</span>
</template>
复制代码
在vue3中如果是条件判断的话,也不需要给每个分支设置key了。
v-if/v-for优先级
我们知道在vue2中如果一个元素上同时存在v-if和v-for的话,那么v-for的优先级更高,而在vue3中则反过来了,v-if的优先级更高了,所以建议最好不要在同一元素上同时使用v-if和v-for。
组件
异步组件
在vue2中异步组件定义很简单,只需要定义为返回 Promise 的函数即:const asyncModal = () => import(‘./Modal.vue’),到了vue3中就稍微复杂一点了需要使用defineAsyncComponent来包裹。实例如下:
import { defineAsyncComponent } from 'vue'
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))
复制代码
注意路由中的懒加载和这里是不同的,所以路由中的懒加载还是使用vue-router的方案。
组件事件emits
在vue2中组件是无法声明哪些事件的,只能声明属性,在vue3新增了一个emits和props类似的指定声明事件,如下:
<template>
<div>
<p>{{ text }}</p>
<button v-on:click="$emit('accepted')">OK</button>
</div>
</template>
<script>
export default {
props: ['text'],
emits: ['accepted']
}
</script>
复制代码
其他
生命周期函数更改
- destroyed 生命周期选项被重命名为 unmounted
- beforeDestroy 生命周期选项被重命名为 beforeUnmount
过度class重命名
过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from
template没有特殊指令标记渲染原生
没有特殊指令的标记 (v-if/else-if/else、v-for 或 v-slot) 的