likes
comments
collection
share

vue3之组合式API--响应式核心篇

作者站长头像
站长
· 阅读数 50

前言

这篇文章,主要写一下部分组合API的核心。我们直接使用setup语法糖

<script setup>

</script>    

响应式(核心类)

vue2跟vue3响应式的实现

我们这里做一个粗略的概括:         vue2 中的 data 返回的是一个响应式对象,其原理是通过 Object.defineProperty()实现的,但是会有一些弊端,比如它对于对象上新增的属性无能为力;对于数组则需要拦截它的原型方法来实现响应式。         vue3 是使用 ES6 中的新特性 Proxy 来实现响应式。Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。

1. ref()--定义响应式数据

ref()接受一个基本数据类型的参数,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。

示例:
<script setup>
    import { ref } from 'vue'
    const count = ref(0)
    console.log(count.value) // 0
    count.value++
    console.log(count.value) // 1
</script>

2. reactive()--定义响应式数据

reactive()接受一个对象,包括json数据和数组都可以,返回一个对象的响应式代理。

示例:
<script setup>
    import { reactive } from 'vue'
    const obj = reactive({ count: 0 })
    obj.count++
    console.log(obj.value) // 1
</script>

3. computed()--计算属性

computed()接受一个 getter 函数,返回一个只读的响应式 ref对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。

示例:
<script setup>
    import { ref, computed } from 'vue'
    const count = ref(1)
    const p = computed(() => count.value + 1)
    console.log(p.value) // 2
    p.value = 3 //报错,因为默认是只读
    
    
    const countTwo = ref(1)
    const p2 = computed({
      get: () => countTwo.value + 1,
      set: (val) => {
        countTwo.value = val - 1
      }
    })
    console.log(p2.value) //2
    p2.value = 4
    console.log(p2.value) //4
    console.log(countTwo.value)//3
</script>

4.watch()--监听

watch()监听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。默认是懒监听,即源发生变化时才执行回调函数。函数接受三个参数:

  1. 监听器的源数据(一个函数,返回一个值。一个ref。一个响应式对象。或以上三种类型组成的数组)
  2. 第二个参数是在发生变化时要调用的回调函数。接受三个参数:新值、旧值,以及一个用于注册副作用清理的回调函数
  3. 第三个可选的参数是一个对象(对象属性支持 immediate,deep,flush,onTrack / onTrigger
示例:
<script setup>
     import { ref, watch , reactive } from 'vue'
  
      //监听一个函数
      const state = reactive({ count: 0 })
      watch(
        () => state.count,
        (count, prevCount) => {
           /* ... */
        },
        { deep:true }// 深度监听
      )
      
      //监听一个ref
      const count = ref(0)
      watch(count, (count, prevCount) => {
           /* ... */
      },{ immediate : true })// 默认执行
     
      //监听多个数据
      watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
         /* ... */
      })
    
</script>

5. watchEffect()

watchEffect()立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。 第一个参数就是要运行的副作用函数 第二个参数就是一个可选的对象,跟watch第三个参数一致

<script setup>
    import { ref, watchEffect } from 'vue'
    const count = ref(0)

    watchEffect(() => console.log(count.value))// -> 输出 0

    count.value++ // ->输出1
</script>

watch() 跟 watchEffect()区别

1. watch是惰性执行,也就是只有监听的值发生变化的时候才会执行,但是watchEffect不同,每次代码加载watchEffect都会执行。 2. watch 会明确监听某一个数据,而 watchEffect 则是监听回调函数中响应数据。 3. watch可以访问之前的值,而watchEffect不可以。

结语

本次尝试了一些组合api的核心(常用部分),其中主要参考官网,cn.vuejs.org/api/reactiv… 然后做了一些自己的尝试,自己总结一遍印象更深刻。