Vue3的监听属性watch和计算属性computed

监听属性watch
计算属性computed

一、监听属性watch
watch 的第一个参数可以是不同形式的“数据源,watch 可以监听以下几种数据:

一个 ref (包括计算属性)、 一个响应式对象、 一个 getter 函数、
或多个数据源组成的数组

watch 的参数:监视的回调,配置对象(deep:深度监听、immediate:立即执行…)
1、监听单个ref对象

<script setup>
  import { ref ,reactive, watch } from 'vue';
  const num = ref(0);
  //watch参数被监视的数据,监视的回调,配置对象(deep:深度监听、immediate:立即执行.....)
  const stopWatch = watch(num,(newValue,oldValue)=>{
    console.log('num新数据:'+newValue,'num旧数据:'+oldValue)
  })

  const onNumAdd = ()=>{
    num.value++;
  }

</script>

<template>
  <div>
    <div>监听属性watch:{{num}}</div>
    <button @click="onNumAdd()">num+1</button>

  </div>
</template>

在这里插入图片描述
2、监听单个 ref 对象类型 数据
如果我们直接像监听单个ref基础数据类型写,是监听不到数据的,此时我们需要手动加上deep深度监听

<script setup>
  import { ref ,reactive, watch } from 'vue';
  const user = ref({
    name:'zhangsan'
  });
  const stopWatch = watch(user,(newValue,oldValue)=>{
    console.log('user新数据:'+newValue.name,'user旧数据:'+oldValue.name)
  },{deep:true})

  const onchangeName = ()=>{
    user.value.name = 'lisi';
  }

</script>

<template>
  <div>
    <div>监听属性watch:{{user.name}}</div>
    <button @click="onchangeName()">修改名字</button>

  </div>
</template>

在这里插入图片描述
可以看出若修改的是ref定义的对象中的属性,newValue 和 oldValue 都是对应的新值,因为它们是同一个对象;若修改整个ref定义的对象,newValue 是新值, oldValue 是旧值,因为不是同一个对象了
3、监听 reactive 对象类型数据

<script setup>
  import { ref ,reactive, watch } from 'vue';
  const user = reactive({
    name:'zhangsan',
    age:20
  });
  const stopWatch = watch(user,(newValue,oldValue)=>{
    console.log('新数据:'+newValue.name,'-----旧数据:'+oldValue.name)
  })

  const onchangeName = ()=>{
    user.name = 'lisi';
  }

  const onchangeAge = ()=>{
    user.age = '22';
  }

</script>

<template>
  <div>
    <div>监听属性watch----{{user.name}}-----{{user.age}},</div>
    <button @click="onchangeName()">监听名字</button>
    <button @click="onchangeAge()">监听年龄</button>
  </div>
</template>

我们发现不需要像ref对象类型添加deep,因为默认开启深度监听
在这里插入图片描述

4、监听多个数据
监视多个数据,直接把所有数据放到数组中

<script setup>
  import { ref ,reactive, watch } from 'vue';
  const num = ref(0);
  const user = reactive({
    name:'zhangsan',
    age:20
  });
  const stopWatch = watch([num,()=>user.name,()=>user.age],(newValue,oldValue)=>{
    console.log('新数据:'+newValue,'-----旧数据:'+oldValue) //newValue[0]对应监听的第一个数据源
  })

  const onchange = ()=>{
    num.value ++;
    user.name = 'zhangsan修改';
    user.age = '20';
  }

</script>

<template>
  <div>
    <div>监听属性watch--{{num}}--{{user.name}}-----{{user.age}},</div>
    <button @click="onchange()">监听多值</button>

  </div>
</template>

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b15e70499a054ec89951575812f274ea.png
5、监听对象的某个属性
监听ref或者reactive定义的对象类型数据中的某个属性时,如果该属性值不是对象类型,需要写成函数的形式,如果是对象类型,可以直接写,也可以写成函数的形式

<script setup>
  import { ref ,reactive, watch } from 'vue';
  const user = reactive({
    name:'zhangsan',
    age:20
  });
  const stopWatch = watch(()=>user.name,(newValue,oldValue)=>{
    console.log('新数据:'+newValue,'-----旧数据:'+oldValue)
  })

  const onchangeName = ()=>{
    user.name = 'lisi';
  }

  const onchangeAge = ()=>{
    user.age = '22';
  }

</script>

<template>
  <div>
    <div>监听属性watch----{{user.name}}-----{{user.age}},</div>
    <button @click="onchangeName()">监听名字</button>
    <button @click="onchangeAge()">监听年龄</button>
  </div>
</template>

在这里插入图片描述
6、 watchEffect()
watchEffect也是用来监听数据的,刚进页面就会立即执行一次,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数。
watch要明确指出监听的数据,watchEffect不用明确指定监视的数据,用到哪些属性,就会监听哪些属性。

<script setup>
  import { ref ,reactive, watch ,watchEffect } from 'vue';
  const num = ref(0);
  const user = reactive({
    name:'zhangsan',
    age:20
  });
  const stopWatch = watchEffect(()=>{
    console.log('数据发生变化:'+num.value,user.name)
  })

  const onchange = ()=>{
    num.value ++;
    user.name = 'zhangsan修改';
  }

</script>

<template>
  <div>
    <div>监听属性watch--{{num}}--{{user.name}}-----{{user.age}},</div>
    <button @click="onchange()">改变</button>

  </div>
</template>

在这里插入图片描述
7、停止监听
有的时候,我们可能只需要监听一次。在监听之后,我们就需要取消对watch的监听。此时我们可以这样做,将watch监听器赋值给一个变量,在取消监听的时候调用此变量即可。
要手动停止一个侦听器,请调用 watch 或 watchEffect 返回的函数:

<script setup>
  import { ref ,reactive, watch ,watchEffect } from 'vue';
  const num = ref(0);
  const stopWatch = watch(num,(newValue,oldValue)=>{
    console.log('新数据:'+newValue,'旧数据:'+oldValue)
    //停止监听
    if(newValue == 5)
      stopWatch()
  })

  const onchange = ()=>{
    num.value ++;
  }

</script>

在这里插入图片描述

二、计算属性computed
计算属性computed作用是根据已有数据计算出新数据。它需要返回一个值,返回的值就是该计算属性的值。
1、只读取

<script setup>
import { reactive, computed } from 'vue'

const author = reactive({
  name: 'zhangsan',
  books: [
    'Vue 2',
    'Vue 3',
    'Vue 4'
  ]
})

// 一个计算属性 ref
const BooksMessage = computed(() => {
  return author.books.length > 0 ? 'Yes' : 'No'
})
</script>

<template>
  <p>计算属性:</p>
  <span>{{ BooksMessage }}</span>
</template>

在这里插入图片描述
2、可写计算属性
计算属性默认是只读的。当你尝试修改一个计算属性时,你会收到一个运行时警告。只在某些特殊场景中你可能才需要用到“可写”的属性,你可以通过同时提供 getter 和 setter 来创建

<script setup>
  import { ref, computed } from 'vue'
  const age = ref(16)
  const newAge = computed({
    // get函数,获取计算属性的值
    get(){
      return age.value + 2
    },
    // set函数,当你给计算属性设置值的时候触发
    set (value) {
      age.value = value - 2
    }
  })
</script>

<template>
  <p>计算属性:</p>
  <div class="container">
    <div>今年:{{age}}</div>
    <div>后年:{{newAge}}</div>
    <input type="text" v-model="newAge">
  </div>
</template>

在这里插入图片描述
总结:
给computed传入函数,返回值就是计算属性的值
给computed传入对象,get获取计算属性的值,set监听计算属性改变。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值