vue3,computed,watch,watchEffect以及总结,生命周期
computed
背景
一个姓输入框、一个名输入框、最后一个姓名输入框相加
v.0
<template>
<div>
姓:<input type="text" v-model="name.firstName" /><br />
&nprn;<input type="text" v-model="name.middleName" /><br />
名:<input type="text" v-model="name.lastName" /><br /><br />
姓名:<input type="text" v-model="name.names" />
</div>
</template>
<script setup>
import { reactive, computed } from "vue";
const name = reactive({
firstName: "张",
middleName: "",
lastName: "冷",
});
name.names=name.firstName+'.'+name.middleName+'.'+name.lastName
</script>
<style scoped></style>
发现不丝滑,也不是我想要的
改了一下代码~
v.1
name.names = computed(() => {
return name.firstName + "." + name.middleName + "." + name.lastName;
});
丝滑了;可是,不能改姓名最后的那个框框内容;报错
![Snipaste_2023-07-19_10-58-31.png](https://img1.imgtp.com/2023/07/19/v6nlsjwr.png)
代理上的“设置”:陷阱返回属性“名称”的伪造类型错误:代理上的“设置”:陷阱返回属性“名称”的伪造
就是说只是一个只读的属性
so需要使用set函数
v.2
<template>
<div>
姓:<input type="text" v-model="name.firstName" /><br />
&nprn;<input type="text" v-model="name.middleName" /><br />
名:<input type="text" v-model="name.lastName" /><br /><br />
姓名:<input type="text" v-model="name.names" />
</div>
</template>
<script setup>
import { reactive, computed } from "vue";
const name = reactive({
firstName: "张",
middleName: "",
lastName: "冷",
});
name.names = computed( {
get(){
return name.firstName + "." + name.middleName + "." + name.lastName;
},
set(value){
let nameList=value.split('.')
name.firstName=nameList[0]
name.middleName=nameList[1]
name.lastName=nameList[2]
}
});
</script>
<style scoped></style>
注意点
- 使用get和set的时候computed是函数
- 分割的是set里面的参数
- get没有参数;只有set函数
自己去尝试一下吧;以为会了,结果一敲还是漏洞百出~
结果很丝滑
watch
背景
一个展示的;一个按钮;点击按钮加加加。
![Snipaste_2023-07-19_14-59-08.png](https://img1.imgtp.com/2023/07/19/9Bze2y2H.png)
监听ref
<template>
<div cLass="home">
<h1>当前数字为:{{ num }}</h1>
<button @click="num++">点击数字加一</button>
</div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
let num = ref("0");
watch(
num,
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
},
{ deep: false }
);
//这种只能监听ref定义,绑定的;
//下面是监听reactive的
// watch(
// () => info.num,
// (newValue, oldValue) => {
// console.log(`names改变了`, newValue, oldValue);
// }
// );
</script>
监听reactive
<template>
<div cLass="home">
<h1>当前数字为:{{ info.num }}</h1>
<button @click="info.num++">点击数字加一</button>
</div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
const info = reactive({
num: 20,
msg: "msg",
});
watch(
info.num,
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
},
{ deep: true }
);
</script>
[Vue warn]: Invalid watch source: 20 A watch source can only be a getter/effect function, a ref, a reactive object, or an array of these types.
*Vue3 Watch 的source 接受的参数不符合要求,只能接受一个getter, efefct, ref,reactive或者元素是这几个类型的数组。*
watch(
() => info.num,
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
}
);
使用这个返回一个函数。
watch(
() => {
return info.num;
},
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
}
);
多个使用数组
<template>
<div cLass="home">
<h1>当前数字为:{{ info.num }}</h1>
<button @click="info.num++">点击数字加一</button>
<h1>当前数字为:{{ info.msg }}</h1>
<button @click="info.msg += '!'">点击数字加一</button>
</div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
const info = reactive({
num: 20,
msg: "啧啧啧",
});
watch([() => info.num, () => info.msg], (newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
});
深度监听
- 写到底
<template>
<div cLass="home">
<h1>当前数字为:{{ info.num }}</h1>
<button @click="info.num++">点击数字加一</button>
<h1>当前数字为:{{ info.msg }}</h1>
<button @click="info.msg += '!'">点击数字加一</button>
<h1>当前年龄为:{{ info.oneInfo.age }}</h1>
<button @click="info.oneInfo.age++">点击功德加一</button>
</div>
</template>
<script setup>
import { ref, watch, reactive } from "vue";
const info = reactive({
num: 20,
msg: "啧啧啧",
oneInfo: {
age: 55,
},
});
watch(
[() => info.num, () => info.msg, () => info.oneInfo.age],
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
}
);
</script>
这样写的话—-就监听不到最里面、深层次的。
watch([() => info.num, () => info.msg, () => info], (newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
});
![333.png](https://img1.imgtp.com/2023/07/19/37AqFNUK.png)
![5555.png](https://img1.imgtp.com/2023/07/19/xj1MG8Hv.png)
watch(
[info],
(newValue, oldValue) => {
console.log(`names改变了`, newValue, oldValue);
},
{ deep: true }
);
![888.png](https://img1.imgtp.com/2023/07/19/eEeWWB5i.png)
watchEffect
跟watch很像
- 自动默认开启了
immediate:true
(当 watch 一个变量的时候,初始化时并不会执行你需要在created的时候手动调用一次。添加immediate属性,这样初始化的时候也会触发) - 用到了谁就监视谁
<template>
<div cLass="home">
<h1>当前数字为:{{ num }}</h1>
<button @click="num++">点击数字加一</button>
<h1>当前年龄为:{{ person.age }}</h1>
<button @click="person.age++">点击功德加一</button>
</div>
</template>
<script setup>
import { ref, watch, reactive, watchEffect } from "vue";
let num = ref(2);
const person = reactive({
age: 22,
});
watchEffect(() => {
const one = num.value;
const two = person.age;
console.log("watchEffect执行了--");
});
</script>
总结
computed有缓存需要返回(用于表单),watch没有缓存,watchEffect有缓存不需要返回
生命周期
vue2 | vue3 | vue3.2(setup) |
---|---|---|
beforeCreate | beforeCreate | setup |
created | created | setup |
beforeMount | beforeMount | onBeforeMount |
mounted | mounted | onMounted |
beforeUpdate | beforeUpdate | onBeforeUpdate |
updated | updated | onUpdated |
beforeDestory | beforeUnmount | onBeforeUnmount |
beforeDestoryed | unmounted | onUnmounted |