1
1126605465
V1
2023/04/10阅读:33主题:自定义主题1
vue3基础入门系列--③计算属性和侦听器
计算属性 computed
作用:通常用来修饰已有的数据,或者根据已有的数据判断返回一个结果.例如在一组价格的数据后添加单位
1.1 只读计算属性
<template>
<div>商品:{{obj.name}}</div>
<div>价格:{{price}}</div>
</template>
<script setup>
//引入 (按第一期配置,可省略此步骤)
import { reactive, computed } from 'vue'
//声明响应式数据
let obj = reactive({ name: '苹果', price: 18, })
//声明计算属性
const price = computed(() => {
return obj.price + 'RMB'
})
</script>
当在模板页面使用过多复杂的运算表达式时可以采用计算属性来减少页面逻辑,使代码更简练,逻辑更清晰.
1.2 可写计算属性
直接修改计算属性,控制台会报错
<template>
<div>姓氏:{{obj.firstName}}</div>
<div>名字:{{obj.lastName}}</div>
<div>全名:{{fullName}}</div>
<input type="text" v-model="fullName" />
</template>
<script setup>
import { reactive, computed } from 'vue'
let obj = reactive({ firstName: '蔡', lastName: '徐坤', })
const fullName = computed(() => {
return obj.firstName + obj.lastName
})
</script>

控制台警告:计算属性只读,这个时候要修改计算属性的声明方式
<script setup>
import { reactive, computed } from 'vue'
let obj = reactive({ firstName: '蔡', lastName: '徐坤', })
const fullName = computed({
get() {
return obj.firstName + obj.lastName
},
set(val) {
//以逗号为标识揭开姓氏和名字
let arr = val.split(',')
obj.firstName = arr[0] || ''
obj.lastName = arr[1] || ''
}
})
</script>
这里只是举例,并不建议实际开发中直接修改计算属性,计算属性只是为了更方便的展示我们想要的结果
1.3计算属性和方法的区别
计算属性和方法在功能上是相似的,都可以达到相同的效果,但是计算属性存在缓存,被依赖的数据没有发生变化时,计算属性不会重新计算.而方法每次调用都会执行.
1.4官方建议(vue官方)
-
避免直接修改计算属性 -
不要在计算属性中的getter中做计算以外的其他行为,例如异步请求
详见:https://cn.vuejs.org/guide/essentials/computed.html#writable-computed
侦听器 watch
和vue2监听区别不大,主要是写法有变化
2.1监听单个数据
<script setup>
//同样先引入,如何自动引入见第一期配置
//自动引入后可省略此行
import { ref, watch } from "vue";
let str = ref("Hello World");
watch(str, (newVal, oldVal) => {
console.log('新值:', newVal);
console.log('旧值:', oldVal);
});
</script>

2.2监听多个数据
<script setup>
//同样先引入,如何自动引入见第一期配置
//自动引入后可省略此行
import { ref, watch } from "vue";
let str = ref("Hello World");
let count = ref(0);
const change = () => {
count.value++;
str.value = "Hello Vue3";
}
//第一个参数可写成数组实现监听多个值
//第二个参数的回调形参也可以是数组
watch([str, count], (newVal, oldVal) => {
console.log('新值:', newVal);
console.log('旧值:', oldVal);
});
</script>

2.3监听响应式对象的某一个值
侦听器的第一个参数不能用 对象.xx
,而是用一个回调写法()=>对象.xx
<script setup>
//同样先引入,如何自动引入见第一期配置
//自动引入后可省略此行
import { reactive, ref, watch } from "vue";
let obj = reactive({ age: '两年半', name: '练习生', value: '只因' });
const change = () => {
obj.name = '坤坤'
}
//第一个参数不可以写成obj.name.要写成()=>obj.name
watch(() => obj.name, (newVal, oldVal) => {
console.log('新值:', newVal);
console.log('旧值:', oldVal);
});
</script>

2.4深度监听和立即执行监听
-
vue2中监听对象嵌套复杂时需要深度监听,配置参数deep,vue3默认自带深度监听 (前提是你的数据源是reactive声明的,ref的需要看己开启深度监听)
,无需配置即可深度监听,当然也可以配置第三个参数{deep: true}
谨慎配置深度监听

-
watch默认是懒执行,只有值发生变回才触发,如果需要立即执行,同样配置第三个参数即可 {immediate: true}
2.5终极监听 watchEffect
-
不需要设置监听源,自动收集依赖 -
非惰性,会立即执行一次
<script setup>
//同样先引入,如何自动引入见第一期配置
//自动引入后可省略此行
import { reactive, ref, watchEffect } from "vue";
let obj = reactive({
age: '两年半',
name: '练习生',
value: '只因',
num: 1
});
const change = () => {
obj.num++
}
watchEffect(() => {
console.log(obj.num)
})
</script>
刷新页面,会立即触发一次监听,每当obj.num变化都会触发监听

这里的运行逻辑是,组件加载完之后会立即执行一次watchEffect
,因为里面有一个打印操作,并且取值为obj.num,因此obj.num被自动收集为依赖,每当obj.num变化都会触发watchEffect. (不解:我尝试打印了整个obj,但是只有第一次会触发,之后并不会再打印,还没明白原因)
2.6 watch和watchEffect区别
二者都可以执行监听,并在数据变化时执行操作.
-
wacth明确监听数据源,不会再回调中追踪数据 -
watchEffect是在回调中自动追踪数据作为监听源 -
watch惰性 watchEffect非惰性
2.7停止侦听器
同步环境下创建的侦听器,会绑定字组件实例上,组件销毁,侦听器也会自动销毁,但是异步环境下,侦听器不会自动自动销毁.
只许调用一次侦听器的返回函数即可销毁
//wacth,watchEffect方法一样
const unwatch = watchEffect(() => {})
// ...当该侦听器不再需要时
unwatch()
作者介绍
1
1126605465
V1