vue3-computed-watch

81 阅读2分钟

computed

当我们的某些属性是依赖其他状态时,我们可以使用计算属性来处理

在Composition API中,我们可以在setup函数中使用computed方法来编写一个计算属性;

方式一:接收一个getter函数,并为 getter 函数返回的值,返回一个不变的 ref 对象;

方式二:接收一个具有 get 和 set 的对象,返回一个可变的(可读写)ref 对象;

<script>
import { computed, ref } from 'vue'
export default {
  setup() {
    const fristName = ref('kobe')
    const lastName = ref('Bryant')
    //计算属性
    // 返回的是ref对象,
    // 用法一:getter函数
    const fullName = computed(() => {
      return fristName.value + '-' + lastName.value
    })
    //用法二:传入一个对象,包含getter/setter
    const fullName2 = computed({
      get: () => fristName.value + '-' + lastName.value,
      set(newValue) {
        //数组拼接成字符串
        const names = newValue.split('')
        fristName.value = names[0]
        lastName.value = names[1]
      }
    })
    const change = () => {
      fristName.value = '111'
      lastName.value = '222'
    }
    return {
      fullName,
      fullName2,
      change
    }
  }
}
</script>

侦听器

在Composition API中,我们可以使用watchEffectwatch来完成响应式数据的侦听;

1 .watchEffect用于 自动 收集响应式数据的依赖;

首先,watchEffect传入的函数会被立即执行一次,并且在执行的过程中会收集依赖;

其次,只有收集的依赖发生变化时,watchEffect传入的函数才会再次执行

<script>
import { watchEffect, ref } from 'vue'
export default {
  setup() {
    const name = ref('why')
    const age = ref(18)

    //监听:自动监听 刚开始就执行一次,默认第一次调用
    //可以自动进行依赖搜索
    watchEffect(() => {
      console.log('name', name.value)
    })

    const change = () => {
      name.value = '111'
      age.value = 58
    }
    return {
      name,
      age,
      change
    }
  }
}
</script>
  • stop():停止监听

  • watchEffect清除副作用

什么是清除副作用呢?

比如在开发中我们需要在侦听函数中执行网络请求,但是在网络请求还没有达到的时候,我们停止了侦听器, 或者侦听器侦听函数被再次执行了。那么上一次的网络请求应该被取消掉,这个时候我们就可以清除上一次的副作用;

在我们给watchEffect传入的函数被回调时,其实可以获取到一个参数:onInvalidate

当副作用即将重新执行 或者 侦听器被停止 时会执行该函数传入的回调函数;

我们可以在传入的回调函数中,执行一些清楚工作;

image.png

  • 执行时机

它的默认值是pre,它会在元素 挂载 或者 更新 之前执行;

    watchEffect(
      () => {
        console.log(title.value)
      },
      {
        // 提前执行 
        flush: 'pre'
        //挂载完成执行
        flush: 'post'
      }
    )
  1. watch需要手动指定侦听的数据源;

watch需要侦听特定的数据源,并在回调函数中执行副作用;

默认情况下它是惰性的,只有当被侦听的源发生变化时才会执行回调;

  • watchEffect的比较,watch允许我们:

懒执行副作用(第一次不会直接执行);

更具体的说明当哪些状态发生变化时,触发侦听器的执行;

访问侦听状态变化前后的值

监听单个数据源

watch侦听函数的数据源有两种类型:

  • 一个getter函数:但是该getter函数必须引用可响应式的对象(比如reactive或者ref);

  • 直接写入一个可响应式的对象,reactive或者ref(比较常用的是ref);

<script>
import { watch, reactive, ref } from 'vue'
export default {
  setup() {
    const info = reactive({ name: 'why', age: 18 })

    //1.传入getter函数,监听某个具体属性
     watch(
      () => info.name,
       (newValue, oldValue) => {
        console.log(newValue, oldValue)
         //hhhhh,why
       }
     )

    //2.传入可响应的对象:reactive对象/ref对象
    // reactive对象获取到的也是reactive对象
     watch(info, (newValue, oldValue) => {
         console.log(newValue, oldValue)
        //Proxy{name: 'hhhhhh', age: 18}
     })
    const change = () => {
      info.name = 'hhhhhh'
    }
    return {
      change,
      info,
    }
  }
}
</script>

侦听多个数据源

采用数组的形式

    const name = ref('why')
    const age = ref(18)
    watch([name, age], (newValue, oldValue) => {
      console.log(newValue, oldValue)
      //['what', 20]['why', 18]
    },
    //深度监听 and 立即执行
      { deep: true, immediate: true }
    )