前言: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…