引言
从Vue2开始学习Vue,到如今已经出现Vue3啦,从Vue2跨入Vue3 我们一起来学习之间的不同
区别
一、工程结构的区别
对比两者入口写法的不同
* Vue2写法 *
import Vue from 'vue'
import App from './App.vue'
new Vue({
render: h => h(App),
router
}).$mount('#app')
vue2使用的还是构造函数
* vue3写法 *
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
vue3引入的不再是Vue构造函数了,引入的是一个名为createApp的工厂函数
Vue3使用工厂函数,可以直接将App组件放在createApp函数里直接注册,而且不再需要new,写法上更为简洁,且符合我们使用的逻辑
Vue3不支持Vue2的入口写法
模版结构不同
在Vue3里,template不再需要根标签,而vue2必须要根标签
二、Composition API
setup
setup是Vue3中新的配置项,组件中数据、方法都要放到setup里面最后一个对象的方式返回
setup() {
let name = 'suoshilei'
let age = 18
function sayHello() {
alert('hello')
}
return {
name,
age,
sayHello,
}
相比于vue2中的data,methods配置项,vue3所有数据方法写到setup里,数据,函数直接定义
- 虽然Vue3里也可以直接用Vue2 的写法,而且可以访问到setup中的值。但最好不要这么做,因为setup访问不到data,methods,computed...
- 如果有重名,setup优先
- setup不能用async,因为返回的是一个promise,模版看不到
vue2中的响应式只要是配置项里都是响应式的而vue3中要自己决定谁是响应式的
ref写法
在vue2中,ref作为标识符相当于id的作用; 而vue3中,ref则是创建一个响应式的引用对象,在里面的value属性里存在get,set实现了响应式
setup() {
let name = ref('suoshilei')
let age = ref(18)
let position = ref({
postMsg: '学生助理',
salary:250
})
function change() {
age.value = 19
name.value = 'suo'
position.value.postMsg = '助教'
position.value.salary = 200
}
return {
name,
age,
change,
position
}
}
原理上来说 对于基本类型 vue2、vue3依旧用的是defineProperty,但是在vue3中处理对象的响应则使用了reactive函数
reactive函数
vue3增加了reactive处理对象的响应
reactive函数不能处理基本类型的响应
import { reactive} from 'vue'
export default {
setup() {
let person = reactive({
name: 'suoshilei',
age: 18,
position: {
postMsg: '学生助理',
salary: 250
},
})
// 方法
function change() {
person.name = 'suo'
person.age = 20
person.position.postMsg = 'qwe'
person.position.salary=230
}
return {
person,change
}
}
}
reactive运用原理是es6的Proxy实现响应式
Proxy代理:拦截对象中任意属性变化,包括对象的读写,属性的增删等
运用Proxy的好处在于,如果想在对象中添加属性就不再像vue2需要$set、$delete.直接添加属性即可
setup注意事项
- setup在beforeCreate之前执行一次,this指向为undefined
- setup函数有两个参数,一个是props,另一个是context
props可以接收外部传来的,且组件内部声明的属性
context:上下文
- attrs:是一个对象,是外部传过来但没有声明的属性,相当于vue2中this.$attrs
- slots:收到的插槽内容,相当于this.$slots
- emit:分发自定义的函数 相当于this.$emit
computed计算属性
在vue3中computed变为函数式写法
import { reactive,computed} from 'vue'
export default {
setup() {
// data
let person = reactive({
firstName: '张',
lastName: '三',
})
//计算属性
person.fullName = computed(() => {
return person.firstName + '-' + person.lastName
})
return { person}
}
}
watch监听属性
在vue3中watch也是函数式写法
import { ref, watch} from 'vue'
export default {
setup() {
// data
let sum = ref(0)
let msg = ref('hello')
//监听属性
watch([sum,msg], (newvalue, oldvalue) => {
console.log('我检查到sum值改变',newvalue,oldvalue);
},{immediate:true})
return {sum,msg}
}
}
三个配置项,第一个配置项是要监视的目标,第二个配置项是一个函数类似于vue2中函数,第三个配置项是其他配置,包括immediate,deep
vue3中watch的坑
- 如果监听的是一个对象,那么不能获得oldvalue值,且deep值无效
- 如果监听的是对象里某一个值要用函数返回值写法
- 如果监听的是对象里某些值要用数组且必须用函数返回值写法