Vue3——计算属性和监听

一、computed

作用:根据已有的数据计算出新数据,具有缓存性(如果依赖的计算数据不更新就只执行一次,更新再执行)

只读写法:

1
2
let fullName = computed(() => {
  return 计算结果;<br>})

可读可写:

1
2
3
4
5
6
7
8
9
let fullName = computed({
  get() {
     return 计算结果;
  },
  set(newVal) {
    // newVal是触发时传进来的参数
    ...修改数据以达到修改计算属性的效果
  }
})

二、watch

作用:监视数据的变化

特点:Vue3中的watch只能监视以下四种数据:

1.ref定义的数据

  情况一:监视【ref】定义的【基本类型】数据

1
2
3
4
5
let sum = ref(0);
// 监视 情况一:监视【ref】定义的【基本类型】数据
watch(sum, (newVal, oldVal) => {
  console.log('sum变化了',newVal, oldVal);
})

  情况二:监视【ref】定义的【对象类型】数据

1
2
3
4
5
6
7
8
9
10
11
12
13
let person = ref({
  name: '张三',
  age: 18,
})
 
// 监视 此时监视的是对象的地址值,只有对象地址改变时才会触发,如果想监听对象内部属性的变化,需要配置第三个参数对象:deep: true
// immediate: true  无论person是否变化,都先执行一次里面的回调函数(第二个参数)
watch(person, (newVal, oldVal) => {
  // 这里的newVal和oldVal值是否一致要看情况,他们指向的地址是person
  // 如果改变了地址,比如person.value = xxx,就会有不同的newVal和oldVal值,因为指向的地址不是一个
  // 如果只改变了里面的属性,那newVal和oldVal指向的地址是一个,所以改变后newVal和oldVal都只能查询到最新的值,看起来newVal和oldVal就是一样的
  console.log('person改变了', newVal, oldVal);
}, {deep: true, immediate: true})

  延伸:停止监视写法

1
2
3
4
5
6
const stopWatch = watch(sum, (newVal, oldVal) => {
  console.log('sum变化了',newVal, oldVal);
  if (newVal >= 10) {
    stopWatch();
  }
})

2.reactive定义的数据

  情况一:监视【reactive】定义的【对象类型】数据(默认开启深度监视,因为reactive的局限性,不能重新分配一个新对象)

1
2
3
4
5
6
7
8
let person = reactive({
  name: '张三',
  age: 18,
})
// 监视 reactive的响应式数据时默认开启深度监视,且不能通过deep:false来关闭
watch(person, (newVal, oldVal) => {
  console.log('person改变了', newVal, oldVal);
})

3.函数返回一个值

  扩展:若是要监听【对象中的某一属性】,可以将这个属性写成【getter函数】(即返回一个值的函数)

  例如:对以下person中的不同属性进行监听

1
2
3
4
5
6
7
8
let person = reactive({
  name: '张三',
  age: 18,
  car: {
    c1: '奔驰',
    c2: '宝马'
  }
}) 

  ①若该属性值不是【对象类型】,需要写成函数形式,如下:

1
2
3
watch(() => person.name, (newVal, oldVal) =>{
  console.log('person.name发生了变化', newVal, oldVal);
})  

  ②若该属性值是【对象类型】,可直接编,也可以写成函数,建议写成函数

    -直接编写,只能监视内部属性的变化,对整个car的修改无法监视,因为person.car指的就是当前的person.car,一旦更改就找不到了

1
2
3
watch(person.car, (newVal, oldVal) => {
  console.log('person.car发生了变化', newVal, oldVal);
})

    -函数式编写,只能监视person.car地址的变化,无法监视内部属性变化,可以通过配置deep:true解决(同ref监视对象类型一样)

1
2
3
watch(() => person.car, (newVal, oldVal) => {
  console.log('person.car发生了变化', newVal, oldVal);
}, {deep: true})  

4.一个包含上述内容的数组

  情况一:监听上述多个数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let person = reactive({
  name: '张三',
  age: 18,
  car: {
    c1: '奔驰',
    c2: '宝马'
  }
})
 
// 监视
watch([() => person.name, () => person.car.c1], (newVal, oldVal) => {
  // newVal和oldVal是name和c1的值
  console.log('person.car发生了变化', newVal, );
}, {deep: true})

三、watchEffect

介绍:立即运行的一个函数(启动即会执行一次),同时响应式地追踪其依赖(可以灵活监控用到的数据),并在依赖更改时重新执行该函数

watch和watchEffect的区别

1.都能监听响应式数据的变化,但是方式不同

2.watch:要明确指出监视的数据

3.watchEffect:不用明确指出监视的数据(函数中用到哪些属性,那就监视哪些属性)

watch和watchEffect分别实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let temp = ref(10);
 let height = ref(0);<br>
 // 通过watch监听实现
 watch([temp, height], (value) => {
   const [newTemp, newHeight] = value;
   if(newTemp >= 60 || newHeight >= 80) {
     console.log(value);
   }
})
 
 // 通过watchEffect监听实现(更方便)
 watchEffect(() => {
   /**
    * 有一个小Bug,一旦temp值大于60之后,再去点击height增加按钮无法输出条件语句内的内容,
    * 是因为||运算符一旦前面条件满足就不会再执行||后面的语句,因此无法在temp条件满足的情况下去监听height
    * 解决办法:在watchEffect再使用一下height.value即可监听,或者使用其他运算符
    */
   if (temp.value >= 60 || height.value >= 80) {
     console.log('达到要求');
   }
 })
posted @   nini-  阅读(284)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示