• 技术文章 >web前端 >Vue.js

    详解Vue3响应式的两大利器:ref与reactive

    青灯夜游青灯夜游2023-01-10 20:28:55转载151

    相对于Vue2的defineProperty实现的数据响应式,Vue3对数据响应的处理分工更加明确,通过组合式api中ref与reactive两个暴露给开发者的函数对数据进行包装,从而实现了数据响应式,那么它们有什么区别?下面我们一起来根据例子来学习!

    ref定义基本数据类型、引用数据类型的响应式。也就是说ref(value),这个value类型可以是基本数据类型,也可以是引用数据类型,但是在js中使用时必须以属性.value格式使用,在template中可以直接调用数据。

    <template>
      <div>
        <div><button @click="changeValue">修改</button></div>
        <div>
          <p>当前strRef:{{ strRef }}</p>
          <p>当前objRef:姓名:{{ objRef.name }} 爱好:{{ objRef.hobboy }}</p>
          <p>当前arrRef:{{ arrRef }}</p>
        </div>
      </div>
    </template>
    <script>
    import { defineComponent, ref, shallowRef } from 'vue'
    export default defineComponent({
      setup () {
        const strRef = ref('sapper');// 基本数据类型
        const arrRef = ref([1, 3, 2]);// 数组类型
        const objRef = ref({  // 对象类型
          name: 'sapper',
          hobboy: ['吉他', '原神']
        })
        const changeValue = () => {
          strRef.value = '工兵';
          arrRef.value[1] = 4;
          objRef.value.hobboy[1] = '滑冰';
        }
        return {strRef,objRef,arrRef,changeValue}
      }
    })
    </script>

    reactive定义引用类型数据的响应式,不支持基本数据类型,如果需要写基本数据类型只能是放在对象中,也就是说reactive(value),这个value类型必须是引用类型。【相关推荐:vuejs视频教程web前端开发

    <template>
      <div>
        <div><button @click="changeValue">修改</button></div>
        <div>
          <div>当前objReactive:
            <br/>
            姓名:{{ objReactive.name }}<br/> 
            爱好:{{ objReactive.hobboy }}
          </div>
          <div>当前arrReactive:{{ arrReactive }}</div>
        </div>
      </div>
    </template>
    <script>
    import { defineComponent, reactive } from 'vue'
    export default defineComponent({
      setup () {
        const arrReactive = reactive([1, 3, 2]);// 数组类型
        const objReactive = reactive({  // 对象类型
          name: 'sapper',
          hobboy: ['吉他', '原神']
        })
        const changeValue = () => {
          arrReactive[1] = 4;
          objReactive.name = '工兵';
          objReactive.hobboy[1] = '滑冰';
        }
        return {objReactive,arrReactive,changeValue}
      }
    })
    </script>

    从上面两个例子中我们可以看出不管什么类型数据,ref都需要以.value来调用ref定义的数据,对于引用数据类型来看,我们可以看出代码不美观,所以一般对于引用类型数据,都推荐使用reactive来定义对于基本数据类型,可以使用ref也可以使用reactive来定义。既然到了这里我们都了解了ref和reactive的运用区别了,那么我们继续来一起探讨一下它们的响应原理又有什么区别?

    揭秘ref

    从上面的例子,我们先打印看一下基本数据类型(strRef)、引用数据类型(arrRef、ObjRef)的ref内部封装结构是什么样的?如下三图所示

    image.png

    image.png

    image.png从上面图片可以看出,不管是什么类型的数据,对于ref封装数据都是一个RefImpl对象reference implement的简写,是引用实现的意思,每个RefImpl对象都有6个属性:

    image.png

    既然我们清楚了ref给数据封装了什么属性,接下来开始探讨源码究竟给怎么给上面6个属性进行赋值的:

    image.png

    其实,RefImpl实例关键就在于trackRefValue(this)triggerRefValue(this, newVal)的两个函数的处理,我们大概也知道它们就是依赖收集、依赖更新。这里就不一一探讨。

    揭秘Reactive

    上面也说了reactive封装数据的用法,它只支持传入引用类型数据(数组、对象),如果需要在reactive中使用基础类型只能放在对象中。既然这样我们来探讨一下reactive函数究竟做了什么?

    const arrReactive = reactive([1, 3, 2]);// 数组类型
    const objReactive = reactive({  // 对象类型
      name: 'sapper',
      hobboy: ['吉他', '原神']
    })
    const changeValue = () => {
      arrReactive[1] = 4;
      objReactive.name = '工兵';
      objReactive.hobboy[1] = '滑冰';
      console.log('arrReactive',arrReactive);
      console.log('objReactive',objReactive);
    }

    image.png从上图可以看出,使用reactive封装的数据返回的都是一个proxy对象,proxy就是代理,如把一个对象代理到另一个对象,好比如房子所有者,代理房子给二手房东销售,二手房东就可以拥有房子销售权利。从上图我们可以看到Proxy对象有三个属性:

    从这个例子,可以看出Proxy对象的第二个参数给代理目标带上相关属性:set方法、get方法,再回到reactive封装的数据中,数据的Handler属性给数据带上了五个属性:deletePropertygetsethasownKeys。这五个属性怎么来的?我们一起探讨一下Vue3的源码实现:

    // 源码位置:core-main/packages/reactivity/src/reactive.ts
    // Vue3中暴露给开发者的是reactive方法
    export function reactive(target: object) {
      // 判断target是否只读,是就不做处理
      if (isReadonly(target)) {
        return target
      }
      return createReactiveObject(
        target,
        false,
        mutableHandlers,
        mutableCollectionHandlers,
        reactiveMap
      )
    }

    createReactiveObject函数主要为了创建Proxy实例对象,参数传了五个属性: target(目标数据)、isReadonly(target是否只读)、mutableHandlers(ProxyHandler)、mutableCollectionHandlers(ProxyHandler类型)、proxyMap(数据集合)。我们先了解一波createReactiveObject函数:

    image.png

    总结

    (学习视频分享:vuejs入门教程编程基础视频

    以上就是详解Vue3响应式的两大利器:ref与reactive的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除
    专题推荐:reactive ref 响应式 Vue.js
    上一篇:一文详解vue指令及其过滤器(附代码示例) 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • 一文详解项目中怎么根据vue版本进行差异化处理• Vue3这样写列表页,让性能更好更高效!• 【由浅入深】vue组件库实战开发总结分享• 聊聊Vue3+hook怎么写弹窗组件更快更高效• 【整理汇总】45+个Vue面试题,带你巩固知识点!• 一文详解vue怎么实现v-model(附代码示例)
    1/1

    PHP中文网