《Vue3中的计算属性computed和watch监听器》

computed

计算属性就是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值,不发生变化的时候,使用的是缓存中的属性值。

  1. 函数形式
1
2
3
4
5
6
7
8
9
import { computed, reactive, ref } from "vue";
let price = ref(0); //$0
let m =
computed <
string >
(() => {
return `$` + price.value;
});
price.value = 500;
  1. 对象形式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div>{{ mul }}</div>
<div @click="mul = 100">click</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
let price = ref<number | string>(1)//$0
let mul = computed({
get: () => {
return price.value
},
set: (value) => {
price.value = 'set' + value
}
})
</script>
<style>
</style>

购物车案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<template>
<div>
<table style="width:800px" border>
<thead>
<tr>
<th>名称</th>
<th>数量</th>
<th>价格</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr :key="index" v-for="(item, index) in data">
<td align="center">{{ item.name }}</td>
<td align="center">
<button @click="AddAnbSub(item, false)">-</button>
{{ item.num }}
<button @click="AddAnbSub(item, true)">+</button>
</td>
<td align="center">{{ item.num * item.price }}</td>
<td align="center">
<button @click="del(index)">删除</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td></td>
<td align="center">总价:{{ $total }}</td>
</tr>
</tfoot>
</table>
</div>
</template>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
type Shop = {
name: string,
num: number,
price: number
}
let $total = ref<number>(0)
const data = reactive<Shop[]>([
{
name: "袜子",
num: 1,
price: 100
},
{
name: "裤子",
num: 1,
price: 200
},
{
name: "衣服",
num: 1,
price: 300
},
{
name: "毛巾",
num: 1,
price: 400
}
])
const AddAnbSub = (item: Shop, type: boolean = false): void => {
if (item.num > 1 && !type) {
item.num--
}
if (item.num <= 99 && type) {
item.num++
}
}
const del = (index: number) => {
data.splice(index, 1)
}
$total = computed<number>(() => {
return data.reduce((prev, next) => {
return prev + (next.num * next.price)
}, 0)
})
</script>
<style>
</style>

watch

watch 需要侦听特定的数据源,并在单独的回调函数中执行副作用
watch 第一个参数监听源
watch 第二个参数回调函数 cb(newVal,oldVal)
watch 第三个参数一个 options 配置项是一个对象{
immediate:true //是否立即调用一次
deep:true //是否开启深度监听

监听 Ref 案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { ref, watch } from "vue";
let message = ref({
nav: {
bar: {
name: "",
},
},
});
watch(
message,
(newVal, oldVal) => {
console.log("新的值----", newVal);
console.log("旧的值----", oldVal);
},
{
immediate: true,
deep: true,
}
);

监听多个 ref 注意变成数组

1
2
3
4
5
6
7
import { ref, watch, reactive } from "vue";
let message = ref("");
let message2 = ref("");
watch([message, message2], (newVal, oldVal) => {
console.log("新的值----", newVal);
console.log("旧的值----", oldVal);
});

监听 Reactive
使用 reactive 监听深层对象开启和不开启 deep 效果一样

1
2
3
4
5
6
7
8
9
10
11
12
import { ref, watch, reactive } from "vue";
let message = reactive({
nav: {
bar: {
name: "",
},
},
});
watch(message, (newVal, oldVal) => {
console.log("新的值----", newVal);
console.log("旧的值----", oldVal);
});

监听 reactive 单一值

1
2
3
4
5
6
7
8
9
10
11
12
import { ref, watch, reactive } from "vue";
let message = reactive({
name: "",
name2: "",
});
watch(
() => message.name,
(newVal, oldVal) => {
console.log("新的值----", newVal);
console.log("旧的值----", oldVal);
}
);