手拉手带你了解Vue3的 ref 和相关函数以及计算属性(二)

简介: 前不久的一篇文章:手拉手带你了解Vue3的reactive和相关函数 已经对reactive以及相关的几个函数,做了一个综合介绍,今天继续和大家深入学习。

06/ isRef

通过 __v_isRef 属性 判断是否是 ref 的实例。这个没啥好说的。vue.global.js 源码:


function isRef(r) {
     return Boolean(r && r.__v_isRef === true);
 }


07/unref

  • 使用.value的语法糖 unref 是一个语法糖,判断是不是 ref 的,如果是则取.value,不是的话取原型。vue.global.js 源码:
  function unref(ref) {
      return isRef(ref) ? ref.value : ref;
  }


  • unref 的用途 普通对象直接.属性即可使用,但是 ref 却需要.value才可以,混合使用的时候容易晕头,尤其在函数内部接收参数的时候,无法确定传入的是 reactive 还是 ref,如果每次都用 isReactive 或者 isRef 来判断类型,然后决定是否用.value,那就太麻烦了。于是有了这个语法糖。

08/ toRef 和 toRefs

toRef 可以用来为源响应式对象上的 property 性创建一个 ref。然后可以将 ref 传递出去,从而保持对其源 property 的响应式连接。toRefs 将响应式对象转换为普通对象,其中结果对象的每个 property 都是指向原始对象相应 property 的ref

话说,官网的解释为啥总是这么令人费解呢?我们还是先看看例子


 setup () {
    /**
     * 定义 reactive
     * 直接解构属性,看响应性
     * 使用toRef解构,看响应性
     * 使用toRefs解构,看响应性
     * 按钮只修改reactive
     */
    const person = reactive({
      name: 'jyk',
      age: 18
    })
    console.log('person ', person )
    // 直接获取属性
    const name = person.name
    console.log('name ', name )
    const refName = toRef(person, 'name')
    console.log('refName ', refName )
    const personToRefs = toRefs(person)
    console.log('personToRefs ', personToRefs )
    const update = () => {
      // 修改原型
      person.name = new Date()
    }
    return {
      person, // reactive
      name, // 获取属性
      refName, // 使用toRef
      personToRefs,
      update // 修改属性
    }
  }


当我们修改person的属性值的时候,toRef 和 toRefs 的实例也会自动变化。而直接获取的name属性并不会变化。

toRef 就是想实现直接使用对象的属性名,并且仍然享有响应性的目的。toRef 就是对reactive 进行解构,然后仍然享有响应性的目的。

其实,说是变成了ref,但是我们看看打印结果就会发现,其实并不完全是ref。


40.png

toRef

41.png


toRefs

看类名和属性,toRef 和 ref 也是有区别的。

09/ toRef 为啥可以响应

toRef 也是一个语法糖。

如果使用常规的方式对 reactive 进行解构的话就会发现,虽然解构成功了,但是也失去响应性(仅限于基础类型的属性,嵌套对象除外)。

那么如何实现解构后还具有响应性呢?这时候就需要使用 toRef 了。

看上面那个例子,使用 refName 的时候,相当于使用 person['name'],这样就具有响应性了。

你可能会问,就这?对就是这么简单,不信的话,我们来看看源码:


  function toRef(object, key) {
      return isRef(object[key])
          ? object[key]
          : new ObjectRefImpl(object, key);
  }
  class ObjectRefImpl {
      constructor(_object, _key) {
          this._object = _object;
          this._key = _key;
          this.__v_isRef = true;
      }
      get value() {
          return this._object[this._key];  // 相当于 person['name']
      }
      set value(newVal) {
          this._object[this._key] = newVal;
      }
  }


看 get 部分,是不是 相当于 person['name'] ?

另外,虽然 toRef 看起来好像是变成了 ref,但是其实只是变成了 ref (RefImpl)的双胞胎兄弟(ObjectRefImpl),并没有变成 ref(RefImpl)。ref 是 RefImpl, 而 toRef 是 ObjectRefImpl,这是两个不同的class 。toRef 可以看做是 ref 同系列的 class,后面还有一个同系列的。

10/ toRefs

了解 toRef 之后,toRefs 就好理解了,从表面上看,可以把 reactive 的所有属性都解构出来,从内部代码来看,就是把多个 toRef 放在了数组(或者对象)里面。

function toRefs(object) {
      if ( !isProxy(object)) {
          console.warn(`toRefs() expects a reactive object but received a plain one.`);
      }
      const ret = isArray(object) ? new Array(object.length) : {};
      for (const key in object) {
          ret[key] = toRef(object, key);
      }
      return ret;
  }


相关文章
|
19天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
45 7
|
20天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
40 3
|
19天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
39 1
|
19天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
41 1
|
9天前
|
JavaScript 前端开发
如何在 Vue 项目中配置 Tree Shaking?
通过以上针对 Webpack 或 Rollup 的配置方法,就可以在 Vue 项目中有效地启用 Tree Shaking,从而优化项目的打包体积,提高项目的性能和加载速度。在实际配置过程中,需要根据项目的具体情况和需求,对配置进行适当的调整和优化。
|
10天前
|
存储 缓存 JavaScript
在 Vue 中使用 computed 和 watch 时,性能问题探讨
本文探讨了在 Vue.js 中使用 computed 计算属性和 watch 监听器时可能遇到的性能问题,并提供了优化建议,帮助开发者提高应用性能。
|
10天前
|
存储 缓存 JavaScript
如何在大型 Vue 应用中有效地管理计算属性和侦听器
在大型 Vue 应用中,合理管理计算属性和侦听器是优化性能和维护性的关键。本文介绍了如何通过模块化、状态管理和避免冗余计算等方法,有效提升应用的响应性和可维护性。
|
10天前
|
存储 缓存 JavaScript
Vue 中 computed 和 watch 的差异
Vue 中的 `computed` 和 `watch` 都用于处理数据变化,但使用场景不同。`computed` 用于计算属性,依赖于其他数据自动更新;`watch` 用于监听数据变化,执行异步或复杂操作。
|
9天前
|
JavaScript 前端开发 UED
vue学习第二章
欢迎来到我的博客!我是一名自学了2年半前端的大一学生,熟悉JavaScript与Vue,目前正在向全栈方向发展。如果你从我的博客中有所收获,欢迎关注我,我将持续更新更多优质文章。你的支持是我最大的动力!🎉🎉🎉
|
11天前
|
存储 JavaScript 开发者
Vue 组件间通信的最佳实践
本文总结了 Vue.js 中组件间通信的多种方法,包括 props、事件、Vuex 状态管理等,帮助开发者选择最适合项目需求的通信方式,提高开发效率和代码可维护性。
下一篇
无影云桌面