vue3.x
Vue3.x与Vue2.x的区别
生命周期不同
Vue2.x | Vue3.x |
---|---|
beforeCreate | setup() |
create | setup() |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeUnmount | onBeforeUnmount |
unmounted | onUnmounted |
errorCaptured | onErrorCaptured |
renderTracked | onRenderTracked |
renderTriggered | onRenderTriggered |
使用setup代替了之前的beforeCreate和created,其他生命周期名字有些变化,功能都是没有变化的。
因为 setup 是围绕 beforeCreate 和 created
生命周期钩子运行的,所以不需要显式地定义它们。换句话说,在这些钩子中编写的任何代码都应该直接在 setup 函数中编写。
在setup函数中的生命周期钩子函数接受一个回调函数,当钩子被组件调用时将会被执行
export default {
setup() {
// mounted
onMounted(() => {
console.log('Component is mounted!')
})
}
}
template模板支持多个根标签
vscode 提示 The template root requires exactly one element解决方法
响应式对象函数
ref
接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象具有指向内部值的单个 property .value。
import { ref } from "vue";
export default({
setup() {
const num = ref("1")
const age = ref("18")
console.log(num.value++) //2
console.log(age.value++) //19
return {
num,
age
};
},
});
reactive
若使用ref函数,每次改变和读取一个值的时候,还要加上value,return的时候也要一个一个retun出去,这种感觉很繁琐。
这种代码一定是可以优化的,需要引入一个新的 API reactive。它也是一个函数(方法),只不过里边接受的参数是一个 Object(对象)
import { reactive } from "vue";
export default({
setup() {
const data = reactive({
num:1,
age:18
})
console.log(data.num++) //2
console.log(data.age++) //19
return {
data
};
},
});
这种在模版中使用时,因为返回的是个data对象,所以模板部分的字面量前要加入data
toRefs
现在template中,每次输出变量前面都要加一个data,这是可以优化的。本以为…扩展运算符就可以解决这个问题了。
可是使用后发现不可以,因为结构后就变成了普通变量,不再具有响应式的能力。所以要解决这个问题,需要使用 Vue3 的一个新函数toRefs()。
import { reactive,toRefs } from "vue";
export default({
setup() {
const data = reactive({
num:1,
age:18
})
console.log(data.num++) //2
console.log(data.age++) //19
const refData = toRefs(data)
return {
...refData
};
},
});
监听属性watch和watchEffect的区别
- watch需要指定监听的属性(参数), vue3.x中新增watchEffect,不需要指定监听的属性(参数),自动收集响应式属性
- watch可以获取到新值与旧值(更新前的值),而 watchEffect 是拿不到的
- watch起初就指定了依赖,初始化时不会执行,依赖发生变化时才会执行
而watchEffect 在初始化时就会执行一次,用来收集依赖,当依赖变化后,watchEffect 还会再次执行 - watch 和 watchEffect 都无法监听未被双向绑定的属性
- watch 可以直接监听 ref 和 reactive 绑定的对象,watchEffect 不可以(ref的值要.value,reactive的值要具体到内部属性),只会执行第一次
watch
import { reactive, toRefs, watch } from "vue";
export default({
setup() {
const data = reactive({
count: 10,
inc: () => data.count++,
});
const refData = toRefs(data);
//第一个参数为要监听的变量,第二个参数为监听到变量改变后的回调函数
watch(refData.count, (newValue, oldValue) => {
console.log(refData.count);
console.log(newValue);
console.log(oldValue);
});
return {
...refData,
};
},
});
同时监听多个参数
1、可以使用多个watch
watch(value,()=>{});
watch(value,()=>{});
watch(value,()=>{});
2、使用一个watch
watch([value1,value2], (newValue, oldValue) => {
console.log(newValue); //返回的是个数组
console.log(oldValue);
});
watchEffect
watchEffect(()=>{
console.log(refData.count,"111")
})
总结:
通过比较两属性的不同点根据具体需求合理的使用
1.如果需要组件初始化时执行,则用watchEffect
2.如果需要获取新值旧值,则使用watch
父子组件传参
父传子
- vue2.x
exprot default {
props: {
title: String
},
mounted() {
console.log(this.title);
}
}
- vue3.x
1、props
//通过setup中的内置参数进行调用,舍弃了之前的this调用方式
exprot default {
props: {
title: String
},
//props 组件传入的属性
setup(props,context) {
console.log(props.title)
}
}
2、
provide 父组件向子组件传参
inject 子组件接收父组件传来的参数
//父组件
import { provide } from "vue";
exprot default {
setup(props,context) {
provide("menuClick",value)
}
}
子组件
import { inject } from "vue";
exprot default {
setup(props,context) {
const v = inject("menuClick")
return {
v
}
}
}
子传父
- vue2.x
this.$emit("menuClick",value)
- vue3.x
exprot default {
emits: ["menuClick"], //declare it using the "emits" option 解决调试器警告
setup(props,context) {
const menuClick = (value)=>{
context.emit("menuClick",value)
}
}
}