第三十二节——组合式API计算属性+watch

一、计算属性

接受一个 getter 函数,并根据 getter 的返回值返回一个不可变的响应式 ref 对象。也就是说,如果我们观察的是

ref或者reactive数据,返回后的数据不能在修改

<template>
  <div>{{ plusOne }}</div>
</template>
<script setup>
import { computed } from "vue";

// 定义一个计算属性
const count = ref(1)
const plusOne = computed(() => count.value + 1)

// 但是注意computed返回的数据是不可变数据
// plusOne.value++ // 错误
</script>

如果我们想后面在修改则可以传入 getset 函数的对象可用来创建可写的 ref 对象

<template>
  <div>{{ plusOne }}</div>
</template>
<script setup>
import { computed, ref } from "vue";
const count = ref(1)
const plusOne = computed({
  /**
   * 劫持数据,每次获取的时候,都会自动给数据+1
   * 比如 现在template里面的plusOne就是1000
   * 注意要有返回值,返回的值就是我们拿到的结果
   * 如果说对get不想做操作那么就直接把我们要返回的值返回
   */
  get: () => {
    return 1000
  },
  /**
   * 每次修改的时候数据-1
   * 不需要返回值 这个val就是我们plusOne的值
   * 如果说不想劫持则可以直接默认赋值
   */
  set: val => {
    count.value = val - 1
  }
})
plusOne.value += 1
/**
 * 这个值是1000,以为我们在劫持了他的数据修改
 * 所以我们+1 然后 数据再去件-1,所以相当于没变
 */
console.log(plusOne.value)
</script>

二、watchEffect

为了根据响应式状态自动应用重新应用副作用,我们可以使用 watchEffect 函数。它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数,简单来说,我们写的函数,会立即执行一次,然后每次里面的数据发生变化后再出发该函数

<template>
  <div>{{ count }}</div>
</template>
<script setup>
import { watchEffect, ref, reactive } from "vue";
const count = ref(1)
const info = reactive({ name: '张三' })
/**
 * 创建后会立即执行,然后每次里面使用的响应式数据发生改变的时候
 * 注意是响应式数据
 * 该函数会再再次执行
 */
watchEffect(() => {
  console.log(count.value)
  console.log(info.name)
})

setTimeout(() => {
  count.value += 1
}, 100)

setTimeout(() => {
  info.name = '李四'
}, 2000)

</script>

三、watch

watch用来监听特定的数据源,并在回调函数中执行。

<template>
  <div>{{ count }}</div>
</template>
<script setup>
import { watch, ref, reactive } from "vue";
const count = ref(1)
const count2 = ref(2)
const info = reactive({ name: '张三' })

/**
 * 监听原始数据类型变化时,可以直接传入
 * 数据里面可以跟多个值,有一个值变化就会触发这个方法
 * 对应的返回值可以使用数据解构出来
 */
watch([count, count2], ([newVal, newVal2], [oldVal, oldVal2]) => {
  console.log(newVal, oldVal)
  console.log(newVal2, oldVal2)
})

setTimeout(() => {
  count.value += 1
  count2.value += 2
}, 1000)


</script>

监听对象类型的数据,并且可以传入第三个参数,是个对象deep 是否深度观察immediate立即执行一次

<template>
  <div>哈哈哈</div>
</template>
<script setup>
import { watch, ref, reactive } from "vue";

const info = reactive({ name: '张三' })
const info2 = reactive({ name: '李四' })

/**
 * 观察一个或者多个对象的变化,要使用函数的方式返回那个对象
 * 如果对象中有属性发生变化就会触发方法
 * 注意:watch默认是惰性的,如果观察对象需要手动在第三个参数加{deep: true}
 */
const stop = watch([() => info, () => info2],
  ([newVal, oldVal], [newVal2, oldVal2]) => {
    console.log(newVal, oldVal)
    console.log(newVal2, oldVal2)
  }, {
  deep: true,
  immediate: true
})

setTimeout(() => {
  info.name = '王五'
  info2.name = '王五2'
}, 1000)

// 如果想移除监听则可以拿到watch的返回,并在合适的时候调用它
stop()

</script>

四、watch和watchEffect的区别

1、watchEffect不需要指定监听的属性,自动收集依赖;watch需要指定监听的属性

2、watchEffect拿不到旧值;watch可以拿到旧值

3、watchEffect在组件第一次就会收集依赖,然后收集到的依赖发生了变化,回调才会再次执行;watch就不是了。一开始就指定了依赖。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值