首页 > 其他分享 >《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结

《Vue.js 设计与实现》读书笔记 - 第6章、原始值的响应式方案 & 响应式总结

时间:2023-01-31 14:23:00浏览次数:39  
标签:Vue obj target 读书笔记 value return 响应 key const

第6章、原始值的响应式方案

6.1 引入 ref 的概念

既然原始值无法使用 Proxy 我们就只能把原始值包裹起来。

function ref(val) {
  const wrapper = {
    value: val,
  };
  Object.defineProperty(wrapper, '__v_isref', {
    value: true,
  });
  return reactive(wrapper);
}

为了判断一个对象是否是原始值的包裹对象,添加一个不可写不可枚举属性来判断。

6.2 响应丢失问题

响应丢失问题就是我们在通过扩展运算符获取响应式对象的值后,我们得到的值变成了普通对象。

const obj = reactive({ foo: 1, bar: 2 })
const newObj = {
  ...obj,
}
effect(() => {
  console.log(newObj.foo)
})
obj.foo = 100

可以在新建对象,然后把对应属性的get访问器设置为读取之前对象的值,这样就可以出发响应了。

function toRef(obj, key) {
  const wrapper = {
    get value() {
      return obj[key]
    },
    set(val) {
      obj[key] = val
    }
  }
  Object.defineProperty(wrapper, '__v_isref', {
    value: true,
  })
  return wrapper
}

const newObj = {
  foo: toRef(obj, 'foo'),
  bar: toRef(obj, 'bar'),
}

如果属性多的时候,需要进行批量转换

function toRefs(obj) {
  const ret = {}
  for (let key in obj) {
    ret[key] = toRef(obj, key)
  }
  return ret
}
const newObj = { ...toRefs(obj) }

自动脱 ref

我们在模板中使用 ref 对象值的时候,不需要用户再添加 .value 去使用,所以需要有一个自动脱 ref 的功能。思路就是通过一个 Proxy 代理对象,在读取的值为 ref 时,再读取对象的 .value 值,同时设置值也应该有自动设置到 value 属性的功能。

function proxyRefs(target) {
  return new Proxy(target, {
    get(target, key, receiver) {
      const value = Reflect.get(target, key, receiver)
      return value.__v_isRef ? value.value : value
    },
    set(target, key, newValue, receiver) {
      const value = target[key]
      if (value.__v_isRef) {
        value.value = newValue
        return true
      }
      Reflect.set(target, key, newValue, receiver)
    },
  })
}

响应式总结

image

标签:Vue,obj,target,读书笔记,value,return,响应,key,const
From: https://www.cnblogs.com/wenruo/p/17078823.html

相关文章

  • vue.js客服系统实时聊天项目开发(十四)点击加载展示历史消息列表
    当访客一进去聊天界面以后,需要获取一下历史消息展示到界面,并且需要能分页的原理展示  在顶部有一个加载更多记录的按钮,点击就能按分页获取数据//展示......
  • coc.nvim 中 coc-tsserver 和 coc-volar 在 vue 项目打开 ts 后缀文件冲突解决方案
    Ifyouareusing"TakeOverMode"forthefirsttimeinyourprojectTobegin,openthe*.vue,*.ts,*.js,*.tsx,*.jsxfile.Thenrun:CocCommandvolar.initi......
  • 谈谈Vue3中的ref和reactive
    一、是什么?ref和reactive是Vue3中用来实现数据响应式的API一般情况下,ref定义基本数据类型,reactive定义引用数据类型(我喜欢用它来定义对象,不用它定义数组,原因后面讲)我......
  • 前端VUE+后端springboot实现导入返回excel校验结果demo
    vue代码<!--菜单导入对话框--><el-dialog:title="upload.title":visible.sync="upload.open":close-on-click-modal="false"width="400px"append-to-body>......
  • vue3 之 ref
    vue3之ref vue2中的ref获取一个dom元素和实例对象 vue3中ref是用来定义数据响应式特别注意:ref可以接收基本数据类型,也可以是对象类型1、基本数据类型......
  • nginx部署vue history模式项目页面刷新报404问题
    nginx部署vuehistory模式项目页面刷新报404问题解决方案:在nginx配置种添加以下代码:try_files$uri$uri//index.html示例:location/{rootdist;......
  • 解决webstorm不能识别vue的@路径引用
    方式1: webstorm无法识别@符号问题[ctrl+左键无法跳转]解决:创建vue项目,打开项目后,再进入webstorm配置页面[否则没有webpack选项]ctrl+alt+s[进入设置页面]->langua......
  • 响应系统的设计与实现
    //存储副作用函数的桶constbucket=newWeakMap()//原始数据exportconstlistenInit=(data)=>{returnnewProxy(data,{//拦截读取操作get(......
  • 使用 vue-pdf 踩坑记录
    嵌入小程序里的h5里有一个查看pdf的功能,在h5里可以正常打开pdf,但是在小程序的webview里却打不开。为了解决这个问题踩了好多坑......
  • VUEX 使用学习六 : modules
    转载请注明出处:当Store中存放了非常多非常大的共享数据对象时,应用会变的非常的复杂,Store对象也会非常臃肿,所以Vuex提供了一个Module模块来分隔Store。通过对Vuex中的S......