VUE2进阶至VUE3 一(Ref())

2,043 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情

说起来vue3已经更新多时,由于本人初入职场一年半(普通二本,普通职员),较多时间都写vue2的业务逻辑代码以及看js原生(真是给前端团体拖后腿),所以一直没能抽空来学习。今天,终于下定决心来从头学习vue3,因为有vue2的基础所以比较基础的东西不会赘述。

下面来进行一个简单的点击事件来修改视图中的值

// 下面这种情况并不能达到修改值的效果,原因是并没有实现双向数据绑定
<template>
  <div>
    <button @click="handleClick">点击</button>
    <p>{{mesg}}</p>
  </div>
</template>
<script setup lang="ts">
  let mesg: string = 'jxx
  const handleClick = () => {
    mesg  'hh';
  }
</script>
// 那么就需要ref来帮忙了(下方便可以正常修改了)
<template>
  <div>
    <button @click="handleClick">点击</button>
    <p>{{mesg}}</p>
  </div>
</template>
<script setup lang="ts">
  import { ref, Ref } from 'vue'
  // 这其中的Ref为TS对应的接口, interface可以接首泛型
  let mesg: Ref<string> = ref('jxx');
  const handleClick = () => {
    mesg.value= 'hh';
  }
</script>

Ref()的一些特性以及官方介绍

介绍

简单来说它就是一个可以获取内部值并返回一个可以响应式的ref对象,value为响应值。

方法

  • isRef(): 判断是否为ref对象

  • shallowRef(): 使用这个属性后。其中的值是不具有响应式的

     let msg = shallowRef({
        name: 'jxx'
      })
      const handleClick = () => {
        msg.value.name= 'hh'; // 此时无法修改
      }
      // 当然,只需要对值进行修改是可以修改的 如下
      msg.value = {name: 'hh'};

需要值得注意的是:当同时引入并使用ref,那么也会一同将shallowRef中的值修改掉,如下例子所示:

      let data = ref('xixi')
      let msg = shallowRef({
        name: 'jxx'
      })
      const handleClick = () => {
        data.value = 'haha'
        msg.value.name= 'hh'; // 此时是可以修改的
      }

出现上述问题的原因:ref中有个dep属性,其中有一个ReactiveEffect,这个其实就是shallowRef()收集的依赖,所以就一并进行更新了。简单来说就是ref中会触发一个视图的强制更新,也就是源码中triggerRefValue,所以当使用ref时,shallowRef的值也会一并更新,所以根据业务场景需要谨慎联合使用这几个方法。

  • triggerRef(): 强制更新DOM,可以配合shallowRef()来使用,当上述例子中属性无法更改时还可以使用以下方法:
      const handleClick = () => {
        msg.value.name= 'hh';
        triggerRef(msg)
      }
  • customRef(): 自定义Ref,通过依赖关系获取跟踪并触发更新视图来达到响应式。
<script setup lang="ts">
  import { customRef } from 'vue'
  function JxxRef<T>(value: T) { // 将value定义为一个泛型
    // customRef 其中接收一个工厂函数,并且返回一个对象,这个对象包含set以及get方法
    return customRef((track, trigger) => {
      return {
        get() {
          track(); // 收集依赖使用
          return value;
        },
        // 更新值
        set(newVal: T) {
            value = newVal;
            trigger(); // 使用trigger来帮忙更新
        }
      }
    })
  }
  // 使用
  let mesg = JxxRef<string>('jxx')
  const handleClick =() => {
    mesg.value = 'hh';
  }
</script>
    ```