一、vue3 中 computed 计算属性
- 通过 computed() 组合 API 定义计算属性
- 传入箭头函数只定义 getter 方法,传入对象定义 getter setter 方法
- computed() 监听的是响应式数据的原始值的变化
<template>
<div>
<h1>computed getter ref</h1>
<input type="text" v-model="a" />
<input type="text" v-model="suffixValueA" />
<hr />
<h1>computed getter reactive</h1>
<input type="text" v-model="count1.originalValue" />
<input type="text" v-model="count1.suffixValue" />
<input type="text" v-model="computedValue" />
<hr />
<h1>computed getter setter</h1>
<input type="text" v-model="count2.originalValue" />
<input type="text" v-model="count2.suffixValue" />
</div>
</template>
<script setup>
import { computed, reactive, ref } from 'vue'
/* computed getter ref */
const a = ref(1)
const suffixValueA = computed(() => a.value + '元')
console.log(a.value)
/* computed getter reactive */
const count1 = reactive({
originalValue: 100,
suffixValue: computed(() => count1.originalValue + '元')
})
const computedValue = computed(() => count1.originalValue + '元')
/* computed getter setter */
const count2 = reactive({
originalValue: 100,
suffixValue: computed({
get() {
return count2.originalValue + '元'
},
set(v) {
count2.originalValue = v.split('元')[0]
}
})
})
</script>
二、vue3 中 watch 监听器
1. 监听响应式对象的属性
- 通过 watch() 定义监听器,watch() 作为组合 api 可以同时定义多个
- 当侦听一个响应式对象的属性时,watch 的第一个参数必须是函数返回值的方式
- watch()函数接受三个参数
第一个参数是监听的目标对象:可以是函数返回值,可以是单个响应式数据,可以是多个响应式数据组成的数组
第二个参数是发生变化时要调用的回调函数:接受三个参数分别为新值、旧值、一个用于注册副作用清理的回调函数
第三个参数: 组件初始化时是否执行一次和是否进行深度监听:{ immediate: true, deep: true }
<template>
<div>书名:《{{ books.name }}》</div>
<div>单价:¥{{ books.price }}</div>
<div>数量:{{ books.num }}本</div>
<div>合计:{{ books.total }}</div>
<hr />
<button @click="handleNumSubstract">num --</button>
<button @click="handlePriceSubstract">price --</button>
</template>
<script setup>
import { reactive, toRefs, computed, watch } from "vue";
const state = reactive({
books: {
name: "三国演义",
price: 50,
num: 5,
total: computed(() => books.value.price * books.value.num + "元"),
},
});
const handleNumSubstract = () => {
state.books.num -= 1;
};
watch(
() => state.books.num,
(num, prevNum) => {
console.log(num, prevNum);
num < 0 && (state.books.num = 0);
}
);
const handlePriceSubstract = () => {
state.books.price -= 10;
};
watch(
() => state.books.price,
(num, prevNum) => {
console.log(num, prevNum);
num < 0 && (state.books.price = 0);
}
);
const { books } = toRefs(state);
</script>
2. 监听响应式对象本身
当侦听一个响应式对象时,watch() 的第一个参数可以是函数返回值的方式,也可以是响应式对象本身
<template>
<div>书名:《{{ books.name }}》</div>
<div>单价:¥{{ books.price }}</div>
<div>数量:{{ books.num }}本</div>
<hr />
<button @click="handleNumSubstract">num --</button>
</template>
<script setup>
import { reactive, toRefs, watch } from "vue";
const state = reactive({
books: {
name: "三国演义",
price: 50,
num: 5,
},
});
const handleNumSubstract = () => {
state.books.num -= 1;
};
watch(
// state, // 当直接侦听一个响应式对象时,侦听器会自动启用深层模式
() => state,
(state, prevState) => {
console.log(state);
console.log(prevState);
state.books.num < 0 && (state.books.num = 0);
},
{ immediate: true, deep: true }
);
const { books } = toRefs(state);
</script>
3. 终止侦听器
const stop = watch(source, callback) // 当已不再需要该侦听器时: stop()
三、vue3 中 watchEffect 监听器
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行
- 通过 watchEffect() 定义监听器,watchEffect() 作为组合 api 可以同时定义多个
- 组件初始化时 watchEffect() 默认执行一次(非惰性)
- 无需指定监听的对象,默认监听所有出现在 watchEffect 内部的响应式数据和响应式数据的属性(所以可以将 setup 中的所有 watchEffect 合并成一个)
<template>
<div>书名:《{{ books.name }}》</div>
<div>单价:¥{{ books.price }}</div>
<div>数量:{{ books.num }}本</div>
<div>合计:{{ books.total }}</div>
<hr />
<button @click="handleNumSubstract">num --</button>
<button @click="handlePriceSubstract">price --</button>
</template>
<script setup>
import { reactive, toRefs, computed, watchEffect } from "vue";
const state = reactive({
books: {
name: "三国演义",
price: 50,
num: 5,
total: computed(() => books.value.price * books.value.num + "元"),
},
});
const handleNumSubstract = () => {
state.books.num -= 1;
};
watchEffect(() => {
state.books.num < 0 && (state.books.num = 0);
console.log(state.books.price); // 可监听到
console.log(state.books); // 可监听到
});
const handlePriceSubstract = () => {
state.books.price -= 10;
};
watchEffect(() => {
state.books.price < 0 && (state.books.price = 0);
});
const { books } = toRefs(state);
</script>
- 终止监听器
const stop = watchEffect(source, callback) // 当已不再需要该侦听器时: stop()
网友评论