• 【Vue3 知识第六讲】ref、 shallowRef、unref、isRef 等系列知识应用


    一、ref()

    ref() 方法接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value

    ref 对象是可更改的,也就是说你可以为 .value 赋予新的值。它也是响应式的,即所有对 .value 的操作都将被追踪,并且写操作会触发与之相关的副作用。

    如果将一个对象赋值给 ref,那么这个对象将通过 reactive() 转为具有深层次响应式的对象。这也意味着如果对象中包含了嵌套的 ref,它们将被深层地解包。

    数字化管理平台
    Vue3+Vite+VueRouter+Pinia+Axios+ElementPlus
    权限系统-商城
    个人博客地址

    若要避免这种深层次的转换,请使用 shallowRef() 来替代。

    相较于reactive包裹对象完成响应式,ref更具优势,因为当改变reactive中保存的对象的内存地址时(也就是换一个全新的对象),由于vue3的响应式是通过创建代理对象,在代理对象的set方法中放入该实例的渲染函数的方法构建的,而替换整个对象,而不是修改对象内部的属性值,其并不会调用set方法,所以页面并不会响应式,但是如果使用ref包裹对象,那么此对象仅仅是ref对象的一个value属性,所以更改内存地址时,也仅仅是修改ref对象的value属性,依然会调用代理对象的set方法,完成响应式dom更新

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • ref 接受的数据类型
      基本类型,引用类型。
    • 作用
      把参数加工成一个响应式对象,全称为reference对象(简称为ref对象) 。
    • 核心原理
      如果参数是基本类型那么形成响应式依赖于Object.defineProperty( )的get( )和set( ),如果ref的参数是引用类型,底层ref会借助reactive的proxy 定义响应式变成这样:reactive({value:‘xiaxia’})。

    二、shallowRef()

    shallowRef() 方法是ref() 的浅层作用形式

    ref() 不同,浅层 ref 的内部值将会原样存储和暴露,并且不会被深层递归地转为响应式。只有对 .value 的访问是响应式的。

    shallowRef() 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。

    
    	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81

    需要注意得是,shallowRef 与 ref 不能一起使用,不然 ref 的变化会影响 shallowRef 造成视图的更新

    三、 triggerRef()

    triggerRef() 强制触发依赖于一个浅层 ref (shallowRef) 的副作用,这通常在对浅引用的内部值进行深度变更后使用。

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    四、customRef()

    customRef() 创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。

    customRef() 预期接收一个工厂函数作为参数,这个工厂函数接受 tracktrigger 两个函数作为参数,并返回一个带有 getset 方法的对象(手动收集依赖并派发更新)。

    一般来说,track() 应该在 get() 方法中调用,而 trigger() 应该在 set() 中调用。

    可以用于创建一个防抖 ref,即只在最近一次 set 调用后的一段固定间隔后再调用

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    五、isRef()

    isRef() 方法用于检查某个值是否为 ref

    import { ref, isRef, unref } from 'vue'
    
    const str = "Hello World!"
    const refStr = ref("Hello Ref Data!")
    
    // isRef() 方法用于检查某个值是否为 ref
    console.log("isRef检测:", isRef(str));//isRef检测: false
    console.log("isRef检测:", isRef(refStr));//isRef检测: true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    六、unref()

    unref() 如果参数是 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 计算的一个语法糖。

    import { ref, isRef, unref } from 'vue'
    
    const str = "Hello World!"
    const refStr = ref("Hello Ref Data!")
    
    // unref() 如果参数是 ref,则返回内部值,否则返回参数本身。这是 val = isRef(val) ? val.value : val 计算的一个语法糖。
    const strResult = unref(str);
    const refStrResult = unref(refStr);
    console.log("strResult:", strResult, "refStrResult:", refStrResult);//strResult: Hello World! refStrResult: Hello Ref Data!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    七、ref 用于获取 DOM 元素

    在普通的 js 操作中,一般都是直接操作 dom 元素,但是对于 Vue.js 框架来说,一般是不允许直接操作 dom 元素的。

    那么其实 Vue.js 框架提供了 ref 获取 dom 元素,以及组件引用。

    而 vue3.0 中没有 this和 r e f s ,所以在 v u e 2 中使用 refs,所以在vue2中使用 refs,所以在vue2中使用refs 来获取 dom 元素的方法在 vue3 行不通。

    在 vue3 中可以这样操作:

    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    补充:ref、toRef、toRefs 异同点

    • ref、toRef、toRefs 函数都可以将某个对象中的属性变成响应式数据

    • ref 函数的本质是拷贝,修改响应式数据,不会影响到原始数据(引用数据类型会有影响),视图会更新

    • toRef、toRefs 函数和传入的数据形成引用关系,修改 toRef 会影响这些数据,但是不会更新视图

      作用:把一个响应式对象转换成普通对象,该普通对象的每个属性都是一个 ref

      • toRef 函数一次仅能设置一个数据,接收两个参数,第一个参数是哪个对象,第二个参数是对象的哪个属性
      • toRefs 函数接收一个对象作为参数,它会遍历对象身上的所有属性,然后挨个调用 toRef 执行。用于批量设置多个数据为响应式
    • ref 数据会引起监听行为,而 toRef 不会

    
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    注:我们使用 reactive创建的对象,如果想在模板中使用,就必须得使用 xxx.xxx的形式;如果大量用到的话还是很麻烦的,但是使用 es6解构以后,会失去响应式。那么toRefs的作用就体现在这,利用toRefs可以将一个响应式 reactive 对象的所有原始属性转换为响应式的ref属性

  • 相关阅读:
    无胁科技-TVD每日漏洞情报-2022-10-26
    [附源码]计算机毕业设计基于Springboot在线教育系统
    MongoDB数据库
    和为S的两个数字
    基于java的企业办公自动化系统设计与实现【附源码+lun文】
    Codeforces Round #719 (Div. 3) E. Arranging The Sheep
    自定义注解实现分布式限流
    NDArrayPool源代码解析以及测试程序
    idea中jar包关联源码
    电商财务对账
  • 原文地址:https://blog.csdn.net/qq_39335404/article/details/132663417