当前位置: 首页 > news >正文

杭州专业建设网站哪里好themegallery模板网

杭州专业建设网站哪里好,themegallery模板网,wordpress用户登录显示请求失败,网站幻灯片js代码通过上一篇文章已经初始化项目#xff0c;集成了ts和jest。本篇实现Vue3中响应式模块里的reactive方法。 前置知识要求 如果你熟练掌握Map, Set, Proxy, Reflect#xff0c;可直接跳过这部分。 Map Map是一种用于存储键值对的集合#xff0c;并且能够记住键的原始插入顺…通过上一篇文章已经初始化项目集成了ts和jest。本篇实现Vue3中响应式模块里的reactive方法。 前置知识要求 如果你熟练掌握Map, Set, Proxy, Reflect可直接跳过这部分。 Map Map是一种用于存储键值对的集合并且能够记住键的原始插入顺序。 其中键和值可以是任意类型的数据。 初始化添加获取 let myMap new Map()myMap.set(name, wendZzoo) myMap.set(age, 18)myMap.get(name) myMap.get(age)Map 中的一个键只能出现一次它在 Map 的集合中是独一无二的重复设置的会被覆盖 myMap.set(name, jack)Map 的键和值可以是任意类型的数据 myMap.set({name: wendZzoo}, [{age: 18}])删除 let myMap new Map() myMap.set(name, Tom) myMap.delete(name)key数据类型是对象时需要使用对应的引用来删除键值对 let myMap new Map() let key [{name: Tom}] myMap.set(key, Hello) myMap.delete(key)// 如果使用不同的引用来尝试删除键值对 // 它将无法正常工作 // 因为Map无法识别这两个引用是相同的键 myMap.set([{name: Tom}], Hello) myMap.delete([{name: Tom}])Set Set是一种集合数据结构它允许存储唯一的值无重复项。Set对象可以存储任何类型的值包括基本类型和对象引用。 let mySet new Set()mySet.add(wendZzoo) mySet.add(18) mySet.add({province: jiangsu, city: suzhou})可迭代 for (let key of mySet) {console.log(key) }Proxy Proxy 对象用于创建一个对象的代理从而实现基本操作的拦截和自定义如属性查找、赋值、枚举、函数调用等。 Vue 响应式的前提就是需要数据劫持在 JS 中有两种劫持 property 访问的方式getter / setters 和 Proxies。Vue 2 使用 getter / setters 完全是出于支持旧版本浏览器的限制而在 Vue 3 中则使用了 Proxy 来创建响应式对象。 创建 Proxy 对象时需要提供两个参数目标对象 target被代理的对象和一个处理程序对象 handler用于定义拦截行为的方法。 其中 handler 常用的有 getset 方法。 handler.get() 方法用于拦截对象的读取属性操作完整使用可以参考MDN 它接收三个参数 target目标对象property被获取的属性名receiverProxy 或者继承 Proxy 的对象 const obj {name: wendZzoo, age: 18} let myProxy new Proxy(obj, {get: (target, property, receiver) {console.log(收集依赖)return target[property]} })// 执行 myProxy.name // 执行 myProxy.agehandler.set() 方法是设置属性值操作的捕获器完整使用参考MDN 它接收四个参数 target目标对象property将被设置的属性名或 Symbol、value新属性值receiver最初被调用的对象。通常是 proxy 本身但 handler 的 set 方法也有可能在原型链上或以其他方式被间接地调用因此不一定是 proxy 本身 const obj {name: wendZzoo, age: 18} let myProxy new Proxy(obj, {get: (target, property, receiver) {console.log(收集依赖)return target[property]},set: (target, property, value, receiver) {console.log(触发依赖)target[property] valuereturn true} }) myProxy.name Jack myProxy.age 20Proxy 提供了一种机制通过拦截和修改目标对象的操作来实现自定义行为在 get 和 set 方法打印日志的地方也就是 Vue3 实现依赖收集和触发依赖的地方。 Reflect Reflect 是一个内置的对象它提供拦截 JS 操作的方法。这让它可以完美的和 Proxy 配合Proxy 提供了对对象拦截的时机位置Reflect 提供拦截方法。 Reflect 不是一个构造函数因此不能 new 进行调用更像 Math 对象作为一个函数来调用它所有的属性和方法都是静态的。 常用的方法有 getset。 Reflect.get方法允许你从一个对象中取属性值完整使用参考MDN 它接收三个参数 target需要取值的目标对象propertyKey需要获取的值的键值receiver如果 target 对象中指定了getterreceiver 则为 getter 调用时的this值 let obj {name: wendZzoo, age: 18} Reflect.get(obj, name) Reflect.get(obj, age)Reflect.set 方法允许在对象上设置属性完整使用参考MDN 它接收三个参数 target设置属性的目标对象propertyKey设置的属性的名称value设置的值receiver如果遇到 setterreceiver则为setter调用时的this值 let obj {} Reflect.set(obj, name, wendZzoo)let arr [name, address] Reflect.set(arr, 1, age) Reflect.set(arr, length, 1)更改目录 src下新建文件夹reactivity新建effect.ts和reactive.ts。 tests文件夹下删除上一篇文章中用于验证jest安装的index.spec.ts新建effect.spec.ts和reactive.spec.ts。 reactive 先写单测明确需要的成果再根据这个需求来实现函数。Vue3的reactive方法返回一个对象的响应式代理那代理的对象和源对象是不同的但是又能和源对象一样的嵌套结构。 那单测可以这样写reactive.spec.ts import { reactive } from ../reactivity/reactive;describe(reactive, () {it(happy path, () {let original { foo: 1 };let data reactive(original);expect(data).not.toBe(original);expect(data.foo).toBe(1);}); });根据这两个断言来实现现阶段的reactive方法。Vue3中是使用Proxy实现。 reactive.ts export function reactive(raw) {return new Proxy(raw, {get: (target, key) {let res Reflect.get(target, key);// TODO 依赖收集return res;},set: (target, key, value) {let res Reflect.set(target, key, value);// TODO 触发依赖return res;},}); }运行reactive单测来验证该方法实现是否正确执行yarn test reactive effect 在官网上是没有单独提到这个 API 的可以在进阶主题的深入响应式系统一篇中找到它的身影。 effect直接翻译为作用意思是使其发生作用这个使其的其就是我们传入的函数所以effect的作用就是让我们传入的函数发生作用也就是执行这个函数。 使用示例 import { reactive, effect } from vue;let user reactive({age: 10, });let nextAge;function setAge() {effect(() {nextAge user.age 1;});console.log(nextAge); }function updateAge() {user.age;console.log(nextAge); }在没有使用effect作用于nextAge时直接触发updateAge方法输出的nextAge就是undefined 调用setAgeeffect中函数执行给nextAge赋值响应式数据user中age变化nextAge也在继续执行effect中函数。 单测 那effect的单测可以写成这样 import { effect } from ../reactivity/effect; import { reactive } from ../reactivity/reactive;describe(effect, () {it(happy path, () {let user reactive({age: 10,});let nextAge;effect(() {nextAge user.age 1;});expect(nextAge).toBe(11);}); });effect方法就是接收一个方法并执行它。 effect.ts class ReactiveEffect {private _fn: any;constructor(fn) {this._fn fn;}run() {this._fn();} }export function effect(fn) {let _effect new ReactiveEffect(fn);_effect.run(); }通过抽离成一个Class类去执行传入的 fn 参数。 再来执行所有的单测验证是否成功执行yarn test 依赖收集 修改effect单测增加一个断言来判断当age变化时nextAge是否也更新了 import { effect } from ../reactivity/effect; import { reactive } from ../reactivity/reactive;describe(effect, () {it(happy path, () {let user reactive({age: 10,});let nextAge;effect(() {nextAge user.age 1;});expect(nextAge).toBe(11);// updateruser.age;expect(nextAge).toBe(12);}); });执行单测发现无法通过是因为Proxy代理时候并没有实现依赖收集和触发依赖也就是reactive.ts中还有两个 TODO。 但是首先得清楚什么叫依赖 引用官方的例子 let A0 1 let A1 2 let A2 A0 A1console.log(A2) // 3A0 2 console.log(A2) // 仍然是 3当我们更改 A0 后A2 不会自动更新。 那么我们如何在 JavaScript 中做到这一点呢首先为了能重新运行计算的代码来更新 A2我们需要将其包装为一个函数 let A2function update() {A2 A0 A1 }然后我们需要定义几个术语 这个 update() 函数会产生一个副作用或者就简称为作用 (effect)因为它会更改程序里的状态。A0 和 A1 被视为这个作用的依赖 (dependency)因为它们的值被用来执行这个作用。因此这次作用也可以说是一个它依赖的订阅者 (subscriber)。 因此我们可以大胆通俗的讲依赖就是指的是观察者通常是视图或副作用函数对数据的依赖关系。当观察者需要访问特定数据时它就成为该数据的依赖。 那依赖收集呢 依赖收集是用于追踪和管理数据依赖关系。常用于实现响应式系统其中数据的变化会自动触发相关的更新操作。 当数据发生改变时相关的视图或操作也能够自动更新以保持数据和界面的同步。依赖收集可以帮助我们建立起数据和视图之间的关联确保数据的变化能够自动反映在视图上。 从代码层面讲读取对象的时候也就是get操作时进行依赖收集将目标对象target对象中keyDep实例做关联映射。 在effect.ts中定义依赖收集的方法track。 class ReactiveEffect {private _fn: any;constructor(fn) {this._fn fn;}run() {reactiveEffect this;this._fn();} }let targetMap new Map(); export function track(target, key) {// target - key - deplet depMap targetMap.get(target);if (!depMap) { // initdepMap new Map();targetMap.set(target, depMap);}let dep depMap.get(key);if (!dep) { // initdep new Set();depMap.set(key, dep);}dep.add(reactiveEffect); }let reactiveEffect; export function effect(fn) {let _effect new ReactiveEffect(fn);_effect.run(); }触发依赖 在设置对象属性时也就是进行set操作时触发依赖。将每个属性上挂载的dep的Set结构中的所有作用函数执行。 export function trigger(target, key) {let depMap targetMap.get(target);let dep depMap.get(key);for (const effect of dep) {effect.run();} }至此再次执行所有单测yarn test 总结 先通过单测入手明确需要实现的函数方法的功能分布实现功能点即拆分功能点先初步实现了reactive方法简单版只要求原数据和代理之后的数据不同但是数据结构又要一样像深拷贝一样。通过Class类实现effect方法可以自执行其传入的函数参数依赖收集通过两个Map结构和一个Set结构来映射数据关系将所有的fn存放到dep中。通过一个全局变量reactiveEffect来获取到effct实例为后续触发依赖时直接拿dep中每一项去执行。触发依赖通过映射关系获取到dep因为dep是Set结构可迭代循环每项执行。
http://www.w-s-a.com/news/396294/

相关文章:

  • 兼职做问卷调查的网站wordpress mysql设置
  • 怎么在百度上能搜到自己的网站山西seo谷歌关键词优化工具
  • 网站搭建免费模板飞鱼crm下载
  • 网站开发竞品分析app制作公司深圳
  • 网站建设ssc源码修复设计班级网站建设
  • 网站重定向凡科做网站不要钱
  • 佛山html5网站建设微信营销软件破解版
  • 网站单页做301南京百度推广
  • 私人做网站要多少钱展芒设计网页
  • 怎样网站制作设计如何在网上推广农产品
  • 做关键词排名卖网站聚名网
  • 吉林省住房城乡建设厅网站首页体育器材网站建设方案
  • 网站建设及维护专业手机金融界网站
  • 常州网站建设工作室建立网站有怎么用途
  • 如何盗取网站推广策划书模板
  • 游戏网站建设计划书网络开发需要学什么
  • 手机网站维护费网站开发包括网站过程
  • 懂做游戏钓鱼网站的网站建设技术的发展
  • 网站被百度收录百度一下你就知道 官网
  • 雅客网站建设做网站用什么做
  • 做宣传海报网站专业网站设计速寻亿企邦
  • 秦皇岛市住房和城乡建设局网站有关网站开发的参考文献
  • 晋城城乡建设局网站深圳外贸业务员工资
  • 招聘网站开发的公司销售运营主要做什么
  • 徐州网站无障碍建设wordpress证书
  • c语言可以做网站吗请人做网站收费多少
  • 中英双语网站怎么做网站为什么做静态
  • 毕业设计做音乐网站可以吗网站运营方案
  • windos 下做网站工具网站右侧返回顶部
  • 点餐网站怎么做济源网站建设济源