Vue3.0 和 Vue2.0对比
Vue2和Vue3主函数不同
Vue2通过new Vue(),而且Vue3通过createApp来创建实例
//一些细节上的差异:
//vue2中vue实例中的响应式数据可以以对象的方式写入,vue3只能以函数的方式写
var vue = new Vue({
el:"#app",
data:{
name:'maple'
}
})
// vue3
let app = Vue.createApp({
//这样写会报错
//dataOptions.call is not a function
data: {
name: "张三",
age: 20,
},
});
app.mount('#app')
挂载
// vue3中并没有el选项,必须通过mount实现组件的挂载(地址:jsbin.com/koqeteqini/…)
// vue2可以通过el和$mount挂载组件,如果两者出现el的优先级更高
//vue3
let app = Vue.createApp({
el:"#app", //页面渲染的name并不会生效
});
app.mount('#app')
响应式
- Vue2.0没有在定义的时候添加响应式,那么那面想要响应式的话,需要通过
Vue.set来添加响应式数据 链接,通过Vue.delete来删除响应式数据
var vue = new Vue({
el: "#app",
data() {
return {
obj: {},
};
},
created() {
// 给数据添加响应式
Vue.set(this.obj, "age", 11);
},
methods: {
add() {
this.obj.age++;
},
},
});
如果是数组,那么通过数组的7个API也可以更改响应式数据。push、pop、reverse、shift、unshift、sort、splice。
- vue3响应式处理:
消除了当前 Vue 2 系列中基于 Object.defineProperty 所存在的一些局限,这些局限包括:1 对属性的添加、删除动作的监测; 2 对数组基于下标的修改、对于 .length 修改的监测; 3 对 Map、Set、WeakMap 和 WeakSet 的支持
ref和reactive的使用
ref在事件处理函数中要加上.value来修改对象上的属性,在模板中使用不需要
ref一般用于简单数据类型,ref在复杂数据类型上不太好用。reactive一般用于复杂数据类型数据
let person = ref({
name:'小王',
age:11
})
let updateAge = ()=>{
person.value.age ++
}
}
{{person.name}}
Vue3写法 computed、watch
区别:
- computed是通过多个值得到一个结果,watch不会得到值,并且可以得到新值和旧值
- computed是有缓存的,watch没有缓存
let stu = reactive({
name:"laowang",
age:11
})
//监听对象,默认开启深度监听(设置deep不起作用)
watch(stu,(newVal,oldVal)=>{
console.log(111)
if(newVal.age>20){
alert("年龄太大")
}
},{
//
deep:true,
immediate:true
})
//如果监听对象的一个属性,建议使用下面这种
watch(()=>stu.age,(newVal,oldVal)=>{
console.log(111)
if(newVal>20){
alert("年龄太大")
}
},{
deep:false,
immediate:true
})
computed写法
let firstName = 'wang'
let lastName = ' feng'
//定义不可读的写法
let fullName = computed(()=>firstName+lastName)
//定义可读的计算属性
let fullName = computed({
get(){
return firstName+' ' +lastName
},
set(val){
firstName = val.split(' ')
console.log(firstName[2])
return firstName[0] + firstName[2]
}
})
watchEffect
watchEffect默认会执行一次,当值变化时会再次执行
let addAge = () =>{
stu.age ++
}
let changeName = ()=>{
stu.name = 'xiaowang'
}
//默认会打印一次`woshi`
//当name或者age任意值发生变化时会打印`woshi`
watchEffect(()=>{
let name = stu.name
let age = stu.age
console.log('woshi')
})
模块化
生命周期钩子函数
组合式生命周期钩子函数:onBeforeMount、onMounted、onbeforeUpdated、onUpdate、onWillUnMount、onUnMounted
toRef
用法:将一个reactive里面的成员转化成ref对象 toRef(reactiveObject,key)
let person = reactive({
name:'laowang',
age:11
})
let personRef = toRef(person,'name')
toRefs
用法:将一个reactive转化成ref对象
let person = reactive({
name:'laowang',
age:11
})
let personRef = toRefs(person)
//通常在返回的时候使用
...toRefs(person)
readOnly
传入一个对象(响应式对象或者普通)或者ref,对象的任意嵌套属性都是只读的
const car = readonly({
name:"大众",
color:'white',
price:"3000",
children:{
age:111
}
})
console.log(isReadonly(car))
car.children.age = 2 //警告
验证式api
- isRef():判断是否是ref对象
- isReactive():判断是否是reactive对象
- isReadonly():判断是否是readonly对象
- isProxy() :判断是否是proxy对象 (readonly和reactive都是)
shallowRef
let person = shallowRef({
name: "xiaowang",
age: 11,
});
let updateName = () => {
//通过这种方式可以更新视图
person.value = {
name: "laowang",
};
};
let updateAge = () => {
//通过这种方式不行
person.value.age = 22;
};
shallowRef shallowReactive shallowReadonly
shallowRef:只能通过value修改数据
let p1 = shallowRef({
name:'laowang',
age:11
})
let updateAge = ()=>{
p1.value = {
name:"xiaowang",
age:6
}
}
这种方式并不能修改数据
let p1 = shallowRef({
name:'laowang',
age:11
})
let updateAge = ()=>{
p1.value.age ++
}
shallowReactive:只能修改第一层的数据,深层的对象不能更改
let stu2 = shallowReactive({
name:"往前",
age:11,
friend:{
name:"BY2",
age:20,
car:{
name:"奔驰",
color:'red'
}
}
})
let updateAge = ()=>{
stu2.age++
}
let updateFriend = ()=>{
//数据已经发生变化,但是视图不更新
stu2.friend.age++
console.log(stu2)
}
shallowReadonly:不能修改第一层属性,当时修改深层的属性,但是不会更新视图
let p1 = shallowReadonly({
name:"laowang",
age:11,
children:{
name:"xiaowang",
age:12
}
})
let updateAge = ()=>{
p1.name = "111"
console.log(p1) //会有警告,第一层的name输出的依然是laowang
}
深层修改
let updateAge = ()=>{
p1.children.age ++
console.log(p1) //第二层的age会发生变化,但是并不会更新视图
}
toRaw
将一个代理对象转化成普通对象,这个普通对象就是原来的对象
let p1 = {
name:"laowang",
age:11
}
let p2 = reactive(p1)
let p = toRaw(p2)
console.log(p1 === p)
markRaw
会给对象添加一个属性__v_skip: true,添加后的该属性不能转化成响应式对象
let p1 = {
name:"laowang",
age:11
}
let p2 = markRaw(p1)
let p3 = reactive(p2)
console.log(p3)