vue3数据绑定ref、reactive、customRef、triggerRef详细用法

3,000 阅读1分钟

前言:vue3重写了数据绑定,v2基于Object.defineProperty()实现;v3 基于Proxy实现。v3的优势有:可以监听数组变化;可以监听动态新增的属性;可以监听删除的属性;可以监听数组的索引和length属性。

所以我们在使用vue3数据绑定的时候也需要加入新的api:

  • ref绑定基本数据类型为proxy响应对象、isRef判断是否为ref对象
<template>
  <!-- ref基础用法 -->
  <input type="text" v-model="msg.name" />
  <div @click="cahngeMsg">{{ msg.name }}</div>
</template>

<script setup lang="ts">
import { ref, isRef } from 'vue';
// ref 将msg变量变成一个’双向绑定‘变量
const msg: {} = ref({ name: 'name' });
const cahngeMsg = () => {
  // 在给ref对象赋值的时候需要加.value
  msg.value.name = '点击后的信息';
  // isRef判断变量 是不是’双向绑定‘变量
  console.log(isRef(msg, 'msg')); //true
};
</script>
  • reactive绑定引用数据类型为proxy响应对象

注:上面用ref去绑定对象、数组等复杂的数据类型,源码里面其实也是去调用reactive绑定。

<template>
  <!-- 属性框 -->
  <input type="text" v-model="msgFrom.name" />
  <div>姓名:{{ msgFrom.name }}</div>
  <input type="text" v-model="msgFrom.age" />
  <div>年龄:{{ msgFrom.age }}</div>
  <input type="text" v-model="msgFrom.gender" />
  <div>性别:{{ msgFrom.gender }}</div>
  <div @click="cahngeMsg">提交From</div>
</template>

<script setup lang="ts">
import { reactive, ref } from 'vue';
// reactive对比ref用法
// 只能绑定引用类型
// 取值、赋值、改变 不需要加.value
// 定位为数组的时候不能直接赋值,会破坏Proxy响应对象
const msgFrom = reactive({
  name: '姓名',
  age: '年龄',
  gender: '性别',
});

const cahngeMsg = (value: string) => {
  msgFrom.name = '1111';
  // 注意:一定要在ref对象后面加value获取值
  console.log(msgFrom);
};
</script>
  • ref其他用法:获取dom对象
<template>
  <!-- ref获取dom基础用法 -->
  <div ref="msgRef" @click="cahngeMsg">获取dom</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

const msgRef = ref<HTMLDivElement>();

const cahngeMsg = (value: string) => {
  // 注意:一定要在ref对象后面加value获取值
  console.log(msgRef.value.innerHTML, 'msgRef');
};
</script>
  • shallowReftriggerRef基础用法
<template>
  <!-- ref基础用法 -->
  <input type="text" v-model="msg.name" />
  <div @click="cahngeMsg">{{ msg.name }}</div>
</template>

<script setup lang="ts">
import { shallowRef, triggerRef } from 'vue';
// shallowRef对比ref是比较浅层次的响应(使用方法如下)
const msg: {} = shallowRef({ name: 'name' });
const cahngeMsg = () => {
  // 错误的使用方法 value对象的name值会改变但是视图上不会
  msg.value.name = '点击后的信息';
  // 正确的使用方法 注意:不能在shallowRef更新变量的时候,用ref更新变量
  msg.value = { name: '点击后的信息' };
  // triggerRef强制跟新ref绑定数据(包括shallowRef) 注意:使用ref会自动调用triggerRef
  triggerRef(msg);
};
</script>
  • customRef用法(工厂函数实现get和set适合去做防抖之类的)
<template>
  <!-- customRef基础用法 -->
  <input type="text" v-model="msg" />
  <div @click="cahngeMsg">{{ msg }}</div>
</template>

<script setup lang="ts">
import { customRef } from 'vue';
// 定义自定义的函数响应函数
const myCustom = (value: any) => {
  return customRef((track, trigger) => {
    return {
      get() {
        console.log(value, 'get');
        track();
        return value;
      },
      set(newVal) {
        console.log(value, newVal, 'set');
        value = newVal + '---';
        trigger();
      },
    };
  });
};
// myCustom实例使用
var msg: string = myCustom('install');
// 手动更新数据
const cahngeMsg = (value: string) => {
    msg.value = '111';
};
</script>
  • readonly 拷贝一份proxy对象将其设置为只读
  • shallowReactive 只能对浅层的数据 如果是深层的数据只会改变值 不会改变视图
  • toRef 将普通对象变成ref对象,如果原始对象是响应式的是会更新视图并且改变数据的,如果原始对象是非响应式的就不会更新视图数据是会变的。
  • toRefs 原理和 toRef 一样,多个对象可直接结构赋值 reactive 内的对象;
  • toRaw 将响应式对象变成普通对象

原文链接:blog.csdn.net/qq119556631…