【vue3】关于watch与computed的用法看这个就ok
😉博主:初映CY的前说(前端领域) ,📒本文核心:watch()与computed的使用【vue2中watch|computed概念详解】,本文将介绍在vue3中怎么使用这两者技能
【前言】vue2当中有这两个技能,那么vue3中的watch与computed是怎么用呢?
目录
- ⭐一、watch
- 1.检测reactive内部数据
- 2.监听 ref 数据
- ⭐二、computed
⭐一、watch
1.检测reactive内部数据
<template>
<p>{{ obj.hobby.eat }}</p>
<button @click="obj.hobby.eat = '面条'">click</button>
</template>
<script>
import { watch, reactive } from 'vue'
export default {
name: 'App',
setup() {
const obj = reactive({
name: 'ifer',
hobby: {
eat: '西瓜',
},
})
watch(obj, (newValue, oldValue) => {
// 注意1:监听对象的时候,新旧值是相等的
// 注意2:强制开启深度监听,配置无效
console.log('触发监听');
console.log(newValue === oldValue) // true
})
return { obj }
},
}
</script>
注意点:对 reactive 自身的修改则不会触发监听。
<template>
<p>{{ obj.hobby.eat }}</p>
<button @click="obj.hobby = { eat: '面条' }">click</button>
</template>
<script>
import { watch, reactive } from 'vue'
export default {
name: 'App',
setup() {
const obj = reactive({
name: 'ifer',
hobby: {
eat: '西瓜',
},
})
watch(obj.hobby, (newValue, oldValue) => {
// obj.hobby = { eat: '面条' }
console.log('对 reactive 自身的修改不会触发监听')
})
return { obj }
},
}
</script>
一定得注意不能修改reactive本身,修改本身不触发
2.监听 ref 数据
- 2.1监听一个 ref 数据
<template>
<p>{{ age }}</p>
<button @click="age++">click</button>
</template>
<script>
import { watch, ref } from 'vue'
export default {
name: 'App',
setup() {
const age = ref(18)
// 监听 ref 数据 age,会触发后面的回调,不需要 .value
watch(age, (newValue, oldValue) => {
console.log(newValue, oldValue)
})
return { age }
},
}
</script>
- 2.2监听多个 ref 数据
可以通过数组的形式,同时监听 age 和 num 的变化。
<template>
<p>age: {{ age }} num: {{ num }}</p>
<button @click="handleClick">click</button>
</template>
<script>
import { watch, ref } from 'vue'
export default {
name: 'App',
setup() {
const age = ref(18)
const num = ref(0)
const handleClick = () => {
age.value++
num.value++
}
// 数组里面是 ref 数据
watch([age, num], (newValue, oldValue) => {
console.log(newValue, oldValue)
})
return { age, num, handleClick }
},
}
</script>
立即触发监听属性:
{
immediate: true,
}
<template>
<p>{{ age }}</p>
<button @click="handleClick">click</button>
</template>
<script>
import { watch, ref } from 'vue'
export default {
name: 'App',
setup() {
const age = ref(18)
const handleClick = () => {
age.value++
}
watch(
age,
(newValue, oldValue) => {
console.log(newValue, oldValue) // 18 undefined
},
{
immediate: true,
}
)
return { age, handleClick }
},
}
</script>
开启深度监听 ref 数据
📝 问题:修改 ref 对象里面的数据并不会触发监听,说明 ref 并不是默认开启 deep 的。见下
<template>
<p>{{ obj.hobby.eat }}</p>
<button @click="obj.hobby.eat = '面条'">修改 obj.hobby.eat</button>
</template>
<script>
import { watch, ref } from 'vue'
export default {
name: 'App',
setup() {
const obj = ref({
hobby: {
eat: '西瓜',
},
})
// 注意:ref 监听对象,默认监听的是这个对象地址的变化
watch(obj, (newValue, oldValue) => {
console.log(newValue === oldValue)
})
return { obj }
},
}
</script>
面对这样的没有触发watch我们解决办法有三个:
- 解决 1:当然直接修改整个对象的话肯定是会被监听到的(注意模板中对 obj 的修改,相当于修改的是 obj.value)。
-`{{ obj.hobby.eat }}
- 解决 2:开启深度监听 ref 数据。
watch(
obj,
(newValue, oldValue) => {
console.log(newValue, oldValue)
console.log(newValue === oldValue)
},
{
deep: true,
}
)
就加上一句话,故此没有截图
- 解决 3:还可以通过监听 ref.value 来实现同样的效果。
因为 ref 内部如果包裹对象的话,其实还是借助 reactive 实现的,可以通过 isReactive 方法来证明。
<template>
<p>{{ obj.hobby.eat }}</p>
<button @click="obj.hobby.eat = '面条'">修改 obj</button>
</template>
<script>
import { watch, ref } from 'vue'
export default {
name: 'App',
setup() {
const obj = ref({
hobby: {
eat: '西瓜',
},
})
watch(obj.value, (newValue, oldValue) => {
console.log(newValue, oldValue)
console.log(newValue === oldValue)
})
return { obj }
},
}
</script>
- 监听普通数据
监听响应式对象中的某一个普通属性值,要通过函数返回的方式进行(如果返回的是对象/响应式对象,修改内部的数据需要开启深度监听)。
<template>
<p>{{ obj.hobby.eat }}</p>
<button @click="obj.hobby.eat = '面条'">修改 obj</button>
</template>
<script>
import { watch, reactive } from 'vue'
export default {
name: 'App',
setup() {
const obj = reactive({
hobby: {
eat: '西瓜',
},
})
// 把 obj.hobby 作为普通值去进行监听,只能监听到 obj.hobby 自身的变化
/* watch(
() => obj.hobby,
(newValue, oldValue) => {
console.log(newValue, oldValue)
console.log(newValue === oldValue)
}
) */
// 如果开启了深度监听,则能监听到 obj.hobby 和内部数据的所有变化
/* watch(
() => obj.hobby,
(newValue, oldValue) => {
console.log(newValue, oldValue)
console.log(newValue === oldValue)
},
{
deep: true,
}
) */
// 能监听影响到 obj.hobby.eat 变化的操作,例如 obj.hobby = { eat: '面条' } 或 obj.hobby.eat = '面条',如果是 reactive 直接对 obj 的修改则不会被监听到(ref 可以)
watch(
() => obj.hobby.eat,
(newValue, oldValue) => {
console.log(newValue, oldValue)
console.log(newValue === oldValue)
}
)
return { obj }
},
}
</script>
⭐二、computed
作用:computed 函数用来定义计算属性,上述的基础概念都是同vue2一样的,关于vue2中这两个知识点的定义大家可以移步:【vue2】计算与侦听的用法。
<template>
<p>firstName: {{ person.firstName }}</p>
<p>lastName: {{ person.lastName }}</p>
<input type="text" v-model="person.fullName" />
</template>
<script>
import { computed, reactive } from 'vue'
export default {
name: 'App',
setup() {
const person = reactive({
firstName: '初',
lastName: '映',
})
// 也可以传入对象,目前和上面等价
person.fullName = computed({
get() {
return person.firstName + '*' + person.lastName
},
set(value) {
console.log(value,'value');//为上述get的返回值
const newArr = value.split('*')
person.firstName = newArr[0]
person.lastName = newArr[1]
},
})
return {
person,
}
},
}
</script>
至此本文结束,愿你有所收获!
期待大家的关注与支持! 你的肯定是我更新的最大动力!!!