首页 > 其他分享 >《Vue进阶教程》第三十一课:ref的初步实现

《Vue进阶教程》第三十一课:ref的初步实现

时间:2024-12-30 11:29:23浏览次数:7  
标签:教程 Vue 进阶 value wrapper ref

 往期内容:

《Vue进阶教程》第二十课:lazy懒执行

《Vue进阶教程》第二十一课:支持缓存

《Vue进阶教程》第二十二课:自定义更新(调度器)

《Vue进阶教程》第二十三课:渲染计算属性的结果

《Vue进阶教程》第二十四课:优化

《Vue进阶教程》第二十五课:watch基本概念

《Vue进阶教程》第二十六课:实现侦听函数

《Vue进阶教程》第二十七课:实现侦听对象

《Vue进阶教程》第二十八课:实现新旧值

《Vue进阶教程》第二十九课:立即执行的回调

《Vue进阶教程》第三十课:watchEffect

1 为什么需要ref

由于proxy只能代理引用类型数据(如: 对象, 数组, Set, Map...), 需要一种方式代理普通类型数据(String, Number, Boolean...)

设计ref主要是为了处理普通类型数据, 使普通类型数据也具有响应式

除此之外, 通过reactive代理的对象可能会出现响应丢失的情况. 使用ref可以在一定程度上解决响应丢失问题

2 初步实现

1) 包裹对象

既然proxy不能代理普通类型数据, 我们可以在普通类型数据的外层包裹一个对象

proxy代理包裹的对象(wrapper). 为了统一, 给包裹对象定义value属性, 最后返回wrapper的代理对象

function ref(value) {
  const wrapper = {
    value: value,
  }

  return reactive(wrapper)
}

测试用例

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="./reactive.js"></script>
  </head>
  <body>
    <script>
      function ref(value) {
        const wrapper = {
          value: value,
        }

        return reactive(wrapper)
      }

      // count是一个proxy对象
      const count = ref(1)
      effect(() => {
        // 访问proxy对象的属性 触发 getter 收集依赖
        console.log(count.value)
      })

      setTimeout(() => {
        count.value = 2
      }, 1000)
    </script>
  </body>
</html>

2) 添加标识

按照上面的实现, 我们就无法区分一个代理对象是由ref创建, 还是由reactive创建, 比如下面的代码

ref(1)
reactive({value: 1})

为了后续能够对ref创建的代理对象自动脱ref处理, 即不用.value访问.

考虑给ref创建的代理对象添加一个标识

示例

function ref(value) {
  const wrapper = {
    value: value,
  }

  // 给wrapper添加一个不可枚举, 不可写的属性__v_isRef
  Object.defineProperty(wrapper, '__v_isRef', {
    value: true,
  })

  return reactive(wrapper)
}

在Vue3源码中, 虽然不是按上述方式实现的, 但是可以这样去理解

标签:教程,Vue,进阶,value,wrapper,ref
From: https://blog.csdn.net/2401_84715637/article/details/144819506

相关文章

  • 【开源免费】基于Vue和SpringBoot的共享汽车管理系统(附论文)
    本文项目编号T126,文末自助获取源码\color{red}{T126,文末自助获取源码}......
  • 【开源免费】基于Vue和SpringBoot的共享汽车管理系统(附论文)
    本文项目编号T125,文末自助获取源码\color{red}{T125,文末自助获取源码}......
  • Vue3最新Router带来哪些颠覆性变化?
    1前后端开发模式的演变jQuery时对大部分Web项目,前端不能控制路由,要依赖后端项目的路由系统。通常,前端项目也部署在后端项目的模板里,项目执行示意图:jQuery前端都要学会在后端模板如JSP里写代码。此时,前端工程师无需了解路由。对每次的页面跳转,都由后端负责重新渲染模板。前端......
  • vue3子组件与父组件双向数据绑定
    <scriptsetuplang="ts">import{ref}from'vue'importSearchBarfrom'@/components/SearchBar.vue'//搜索事件处理函数constonSearch=(params:{input1:string;input2:string})=>{console.log('搜索参数:',p......
  • wx.postMessageToReferrerPage
    wx.postMessageToReferrerPage(Objectobject)基础库3.7.2开始支持,低版本需做兼容处理。小程序插件:不支持微信鸿蒙OS版:支持功能描述向跳转的源页面发送消息。参数Objectobject属性类型默认值必填说明extraDataObject否需要返回的数据多次调......
  • 基于Springboot + vue实现的汽车资讯网站
    ......
  • 基于Vue.js的网上招聘系统设计与实现+vue源码+论文
    项目简介网上招聘系统是一个综合性的信息管理平台,旨在提高招聘信息处理的效率和准确性。系统通过计算机技术实现了现代化的信息管理,符合现代信息管理规范。系统的主要功能覆盖了行业管理、求职意向管理、测试管理、职位招聘管理、论坛管理、简历管理、试卷管理、面试经验管理......
  • 基于Springboot + vue实现的旅游网站
    ......
  • MCP(Model Context Protocol)模型上下文协议 进阶篇2 - 消息格式和功能
    在开发前,首先带大家熟悉一下MCP协议的消息格式,和所有可能需要进行协商的功能:MCP协议通过JSON-RPC2.0规范定义了请求、响应和通知三种消息类型,确保通信的标准化和一致性。能力协商机制使客户端和服务器能够动态确定支持的协议功能,提升协议的灵活性和扩展性。子能力的引入进一......
  • Refined Product Optimality
    前言看下能不能做出来这个\(\rm{D}\)思路转化题意,给定两个数组\(a,b\),\(q\)次修改,每次修改对\(a,b\)的某一位进行\(+1\)操作,求每次修改后,任意排列\(b\)的条件下,求\(\maxP=\prod\limits_{i=1}^n\min(a_i,b_i)\)首先先不管修改,考虑怎么做?显......