vue3中computed和watch的使用

一 computd计算属性

computed 是 Vue 3 中用于创建计算属性的功能。它允许你定义基于响应式数据的动态值,这些值会在其依赖的数据发生变化时自动更新。

  1. 使用场景
  • 依赖于其他响应式数据的计算结果:你可以创建一个计算属性,其值依赖于其他响应式数据,并在这些数据变化时自动更新。
  • 性能优化:computed 属性会进行缓存,只有当其依赖的数据发生变化时,才会重新计算,从而提高性能。

只读计算属性

<template>
  <div>
    <p>名称: {{ name }}</p>
    <p>全名: {{ fullName }}</p>
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const firstName = ref('John');
    const lastName = ref('Doe');

    const fullName = computed(() => `${firstName.value} ${lastName.value}`);

    return {
      firstName,
      lastName,
      fullName
    };
  }
}
</script>

关键点
定义:使用 computed 来创建计算属性。例如:

const fullName = computed(() => firstName.value{lastName.value});

访问:计算属性的值可以直接使用,如 {{ fullName }},不需要 .value。
缓存:计算属性会缓存计算结果,只有在依赖的响应式数据变化时才会重新计算。

在 Vue 3 中,computed 属性默认是只读的,但你可以使用一个带有 getter 和 setter 的 computed 属性来实现读写功能。这种方式允许你定义一个计算属性,并同时为它指定一个 setter 函数来处理值的设置。

使用读写计算属性

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Doubled: {{ doubled }}</p>
    <input v-model="doubled" />
  </div>
</template>

<script>
import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);

    const doubled = computed({
      get: () => count.value * 2,
      set: (value) => {
        count.value = value / 2;
      }
    });

    return {
      count,
      doubled
    };
  }
}
</script>

在这个模板中,doubled 计算属性可以通过输入框进行双向绑定,因为它同时有 getter 和 setter 函数。这样,当输入框的值改变时,count 也会相应地更新。

二 watch

watch 是 Vue 3 中用于观察响应式数据变化并执行相应逻辑的功能。它允许你监控一个或多个响应式数据的变化,并在这些数据发生变化时执行回调函数。

  • 作用:监视数据的变化(和Vue2中的watch作用一致)
  • 特点:Vue3中的watch只能监视以下四种数据
  1. ref定义的数据。
  2. reactive定义的数据。
  3. 函数返回一个值(getter函数)。
  4. 一个包含上述内容的数组。
  1. 监视 ref 数据
  • 监视ref定义的【基本类型】数据:直接写数据名即可,监视的是其value值的改变。
import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);

    watch(count, (newValue, oldValue) => {
      console.log(`Count changed from ${oldValue} to ${newValue}`);
    });

    return { count };
  }
}
  • 监视ref定义的【对象类型】数据:直接写数据名,监视的是对象的【地址值】,若想监视对象内部的数据,要手动开启深度监视。
```vue
<template>
  <div class="person">
    <h1>情况二:监视【ref】定义的【对象类型】数据</h1>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
    <button @click="changeName">修改名字</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>
  </div>
</template>

<script lang="ts" setup name="Person">
  import {ref,watch} from 'vue'
  // 数据
  let person = ref({
    name:'张三',
    age:18
  })
  // 方法
  function changeName(){
    person.value.name += '~'
  }
  function changeAge(){
    person.value.age += 1
  }
  function changePerson(){
    person.value = {name:'李四',age:90}
  }
  watch(person,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
  },{deep:true})
  
</script>
  • 监视ref定义的【对象类型】数据中的某个属性
  1. 若该属性值不是【对象类型】,需要写成函数形式。
  2. 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。

结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。

  let person = ref({
    name:'张三',
    age:18,
    car:{
      c1:'奔驰',
      c2:'宝马'
    }
  })

 watch(()=> person.name,(newValue,oldValue)=>{
    console.log('person.name变化了',newValue,oldValue)
  }) 

  watch(()=>person.car,(newValue,oldValue)=>{
    console.log('person.car变化了',newValue,oldValue)
  },{deep:true})

2- 监视 reactive 数据

  • 监视reactive定义的【对象类型】数据,且默认开启了深度监视。

  let person = reactive({
    name:'张三',
    age:18
  })
  watch(person,(newValue,oldValue)=>{
    console.log('person变化了',newValue,oldValue)
  })
  • 监视reactive定义的【对象类型】数据中的某个属性
  1. 若该属性值不是【对象类型】,需要写成函数形式。
  2. 若该属性值是依然是【对象类型】,可直接编,也可写成函数,建议写成函数。

结论:监视的要是对象里的属性,那么最好写函数式,注意点:若是对象监视的是地址值,需要关注对象内部,需要手动开启深度监视。

  let person = ref({
    name:'张三',
    age:18,
    car:{
      c1:'奔驰',
      c2:'宝马'
    }
  })

 watch(()=> person.name,(newValue,oldValue)=>{
    console.log('person.name变化了',newValue,oldValue)
  }) 

  watch(()=>person.car,(newValue,oldValue)=>{
    console.log('person.car变化了',newValue,oldValue)
  },{deep:true})
  1. 监视函数返回值(getter 函数)
import { ref, computed, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const doubled = computed(() => count.value * 2);

    watch(doubled, (newValue, oldValue) => {
      console.log(`Doubled value changed from ${oldValue} to ${newValue}`);
    });

    return { count, doubled };
  }
}
  1. 监视多个数据源(数组)
import { ref, reactive, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const state = reactive({ name: 'Vue' });

    watch([count, () => state.name], ([newCount, newName], [oldCount, oldName]) => {
      console.log(`Count changed from ${oldCount} to ${newCount}`);
      console.log(`Name changed from ${oldName} to ${newName}`);
    });

    return { count, state };
  }
}

三 watchEffect

watchEffect 是 Vue 3 中用于自动执行副作用的功能,它会根据内部使用的响应式数据自动追踪和重新运行。与 watch 不同,watchEffect 不需要指定数据源,它会在副作用函数中自动追踪所有使用的响应式数据。

watch对比watchEffect

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

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

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

使用场景

  • 简单的副作用:当你只需要执行副作用而不需要控制特定的数据源时。
  • 自动追踪:当你希望副作用函数自动追踪其内部引用的所有响应式数据时。
import { ref, watchEffect } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const name = ref('Vue');

    watchEffect(() => {
      console.log(`Count is ${count.value}, Name is ${name.value}`);
    });

    return { count, name };
  }
}

  • 61
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值