一、Vue3
与 Vue2
的区别
- 新加了组件:
Fragment
、Teleport
、Suspense
。 - 语法
v-on
的.native
修饰符被移除,不在支持。 Vue3
的template
中,不再需要唯一的根元素,如果这么使用报错可能是ESLint
没有配置好或版本太低不支持这种写法。
<template> <div>123</div> <div>456</div> </template>
- 全局导入方式调整
// vue - main.js import { createApp } from 'vue' createApp(App).use(store).use(router).mount('#app') // vuex import { createStore } from 'vuex' export default createStore({ ... }) // vue-router import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router' const routes: Array<RouteRecordRaw> = [] export default createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) ...
Vue3
支持Vue2
生命周期的使用- 生命周期对比
Vue2 | Vue3 | 含义 | 区别 |
beforeCreate() | setup() | 创建前,data 和 el 并未初始化 |
Vue3 中被 setup() 替代 |
created() | setup() | 创建完毕,data 数据完成初始化,el 没有 |
Vue3 中被 setup() 替代 |
beforeMount() | onBeforeMount() | 挂载前,data 和 el 完成初始化 |
|
mounted() | onMounted() | 挂载结束,完成挂载,渲染页面 | |
beforeUpdate() | onBeforeUpdate() | 更新前 | |
updated() | onUpdated() | 更新完成 | |
beforeDestroy() | onBeforeUnmount() | 销毁前 | Vue3 中被改名 |
destroyed() | onUnmounted() | 销毁完成 | Vue3 中被改名 |
errorCaptured() | onErrorCaptured() | 异常捕获 | |
onRenderTracked() | 虚拟 dom 重新渲染 |
Vue3 新增,只有在调试的时候有用,生产环境会忽略 |
|
onRenderTriggered() | 虚拟 dom 重新渲染,输出更详细准确的数据 |
Vue3 新增,只有在调试的时候有用,生产环境会忽略 |
- 以前自带的方法可以直接使用,现在需要通过
import
引入之后才可以进行使用
import { ref, reactive, onMounted, onUpdated, onUnmounted, onBeforeMount, onBeforeUpdate, onBeforeUnmount ... } from 'vue'
二、setup
函数
setup
函数中,不能使用this
,this
指向的是undefined
。setup
只会在组件初始化的时候执行一次,执行顺便对比:
beforeCreate () { console.log('---- beforeCreate') }, created () { console.log('---- created') }, setup () { console.log('---- setup') } // 输出顺序: // ---- setup // ---- beforeCreate // ---- created
- 参数分析
setup(props ,context) { }
props
为一个对象,内部包含了父组件传递过来的所有prop
数据。context
对象包含了attrs
、slots
、emit
属性。
- 属性、函数的优先级、生命周期的调用先后
- 一样的属性与函数,
Vue3
的会覆盖Vue2
的。 - 同一个生命周期函数
Vue3
的先调用,Vue2
的后调用,不会覆盖Vue2
的。
<template> <div @click="touchButton">{{ sex }}</div> </template> <script> import { defineComponent, ref, onMounted } from 'vue' export default defineComponent({ // vue2 data() { return { sex:'男' } }, // vue2 mounted () { console.log('mounted - vue2') }, // vue3 setup() { // 比 vue2 优先调用 onMounted(() => { console.log('onMounted - vue3') }) // 优先使用这个,会覆盖 vue2 中的 touchButton 方法 function touchButton () { console.log('touchButton - vue3') } // 优先使用这个,会覆盖 vue2 中的 sex 值 const sex = ref('女') return { sex, touchButton } }, // vue2 methods: { touchButton () { console.log('touchButton - vue2') } } }) </script>
三、ref
函数(响应式数据 方式一)
- 在
setup
中使用时,要加.value
,模板中使用的时候不需要加.value
- 包装简单数据类型
<template> <!-- 模板中使用 --> <div @click="touchButton">{{ sex }}</div> </template> <script> import { defineComponent, ref } from 'vue' export default defineComponent({ setup () { // 定义响应式属性 const sex = ref('女') // 点击按钮 function touchButton () { // 修改值时,需要加上 .value sex.value = '男' } // 定义的属性或函数需要 return 出去才会生效 return { sex, touchButton } } }) </script>
- 包装复杂数据类型
<template> <!-- 模板中使用 --> <div @click="touchButton">{{ user.job.salary }}</div> </template> <script> import { defineComponent, ref } from 'vue' export default defineComponent({ setup () { // 定义响应式属性 const user = ref({ id: 1, name: 'dzm' }) // 中途添加字段 user.value.job = { salary: 10 } // 点击按钮 function touchButton () { // 修改值时,需要加上 .value user.value.job.salary += 1 } // 定义的属性或函数需要 return 出去才会生效 return { user, touchButton } } }) </script>
四、reactive
函数(响应式数据 方式二)
ref
和reactive
都是用来定义响应式数据的,reactive
推荐去定义复杂数据类型,ref
推荐定义基本类型。
ref
包装的简单数据(例如:number
),可以被监听,可以被修改。reactive
包装简单数据(例如:number
),会报警告,且不能直接被修改。ref
包装的复杂数据(例如:json
),不可以被监听,可以新增、修改字段。reactive
包装的复杂数据(例如:json
),可以被监听,可以新增、修改字段。
- 下面
十一、
中有介绍reactive
与shallowReactive
函数的使用区别。
<template> <!-- 模板中使用 --> <div @click="touchButton">{{ user.name }}</div> </template> <script> import { defineComponent, reactive } from 'vue' export default defineComponent({ setup () { // 定义响应式属性 const user = reactive({ id: 1, name: 'dzm' }) // 点击按钮 function touchButton () { // 修改值 user.name = 'xyq' } // 返回 return { user, touchButton } } }) </script>