英雄联盟Akari工具包如何用智能模块化架构提升你的游戏体验【免费下载链接】League-ToolkitAn all-in-one toolkit for LeagueClient. Gathering power .项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit在英雄联盟的竞技场中每一秒的操作都可能决定胜负。你是否曾因为手速不够快而错失抢英雄的机会是否在紧张的符文配置中感到手忙脚乱今天我要为你介绍一款革命性的游戏辅助工具——英雄联盟Akari工具包它通过创新的模块化设计为不同水平的玩家提供个性化的智能辅助解决方案。 为什么Akari工具包与众不同与传统的单一功能辅助工具不同Akari工具包采用了模块化架构设计每个功能都是一个独立的“碎片”Shard可以根据你的需求灵活组合。这种设计理念让工具包具备了以下核心优势1. 前言在上一篇文章中我们实现了响应式数据并且当数据发生变化时能够通知到所有依赖该数据的依赖者那么我们如何收集依赖该数据的依赖者呢在Vue中数据发生变化后会通知到组件的render watcher然后render watcher再去执行render函数更新视图。那么我们如何知道是谁依赖了该数据呢换句话说我们如何收集依赖该数据的依赖者呢在Vue中是通过Watcher来收集依赖的Watcher是一个中介角色数据发生变化时通知它然后它再通知其他地方。Watcher是连接数据和视图的桥梁它会在初始化时收集依赖当数据发生变化时会通知Watcher然后Watcher再去通知依赖该数据的依赖者。接下来我们就来实现Watcher类。2. 思路分析我们之前已经实现了响应式数据并且当数据发生变化时能够通知到所有依赖该数据的依赖者那么我们如何收集依赖该数据的依赖者呢在Vue中数据发生变化后会通知到组件的render watcher然后render watcher再去执行render函数更新视图。那么我们如何知道是谁依赖了该数据呢换句话说我们如何收集依赖该数据的依赖者呢在Vue中是通过Watcher来收集依赖的Watcher是一个中介角色数据发生变化时通知它然后它再通知其他地方。Watcher是连接数据和视图的桥梁它会在初始化时收集依赖当数据发生变化时会通知Watcher然后Watcher再去通知依赖该数据的依赖者。接下来我们就来实现Watcher类。3. 实现Watcher类3.1 创建Watcher类首先我们在src/core/observer/watcher.js中创建Watcher类export default class Watcher { constructor(vm, expOrFn, cb) { this.vm vm; this.getter parsePath(expOrFn); this.cb cb; this.value this.get(); } get() { window.target this; let value this.getter.call(this.vm, this.vm); window.target undefined; return value; } update() { const oldValue this.value; this.value this.get(); this.cb.call(this.vm, this.value, oldValue); } }我们首先来看一下Watcher类的构造函数它接收三个参数vmVue实例expOrFn表达式或函数cb回调函数在构造函数中我们首先将vm实例保存到this.vm中然后将expOrFn解析成函数保存到this.getter中接着将回调函数保存到this.cb中最后调用this.get()方法获取表达式的值。get方法中我们首先将window.target设置为this也就是当前的Watcher实例然后调用this.getter方法获取表达式的值最后将window.target设置为undefined。这里为什么要将window.target设置为this呢这是因为我们在get方法中读取了数据会触发数据的getter在getter中我们会将window.target添加到依赖中这样我们就可以收集到依赖了。update方法中我们首先获取旧值然后调用get方法获取新值最后调用回调函数将新值和旧值传递给回调函数。3.2 解析路径在上面的代码中我们使用了parsePath函数来解析路径这个函数的作用是将路径解析成一个函数这个函数接收一个对象作为参数返回对象中对应路径的值。例如我们有一个对象obj它的值是{a: {b: {c: 1}}}我们想要获取obj.a.b.c的值我们可以这样写const getter parsePath(a.b.c); const value getter(obj); // 1parsePath函数的实现如下const bailRE /[^\w.$]/; export function parsePath(path) { if (bailRE.test(path)) { return; } const segments path.split(.); return function (obj) { for (let i 0; i segments.length; i) { if (!obj) return; obj obj[segments[i]]; } return obj; }; }首先我们使用正则表达式bailRE来检查路径是否合法如果路径中包含非字母、数字、下划线、点号的字符则返回undefined。然后我们将路径按照.分割成数组然后返回一个函数这个函数接收一个对象作为参数然后遍历数组依次获取对象中对应属性的值最后返回这个值。3.3 收集依赖在上面的代码中我们已经实现了Watcher类但是我们还不能收集依赖因为我们还没有在getter中添加依赖。接下来我们需要修改defineReactive函数在getter中添加依赖在setter中通知依赖。export function defineReactive(obj, key, val) { const dep new Dep(); const property Object.getOwnPropertyDescriptor(obj, key); if (property property.configurable false) { return; } const getter property property.get; const setter property property.set; if ((!getter || setter) arguments.length 2) { val obj[key]; } let childOb observe(val); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); if (childOb) { childOb.dep.depend(); } } return value; }, set: function reactiveSetter(newVal) { const value getter ? getter.call(obj) : val; if (newVal value || (newVal ! newVal value ! value)) { return; } if (setter) { setter.call(obj, newVal); } else { val newVal; } childOb observe(newVal); dep.notify(); }, }); }我们首先在defineReactive函数中创建了一个Dep实例然后在getter中我们判断Dep.target是否存在如果存在则调用dep.depend()方法收集依赖。同时如果childOb存在则调用childOb.dep.depend()方法收集依赖。这样我们就完成了依赖的收集。在setter中我们首先获取旧值然后判断新值和旧值是否相等如果相等则直接返回。如果不相等则更新值然后调用dep.notify()方法通知依赖。3.4 测试接下来我们来测试一下我们的代码。我们创建一个index.html文件引入我们打包好的vue.js文件然后编写如下代码!DOCTYPE html html langen head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / titleDocument/title /head body div idapp/div script src./dist/vue.js/script script const vm new Vue({ el: #app, data: { message: Hello Vue!, }, render(h) { return h(div, this.message); }, }); vm.$watch(message, function (newVal, oldVal) { console.log(message changed:, newVal, oldVal); }); setTimeout(() { vm.message Hello World!; }, 1000); /script /body /html我们在index.html中创建了一个Vue实例然后监听message属性的变化当message属性发生变化时会触发回调函数打印出新值和旧值。然后我们在1秒后修改message属性的值我们可以看到控制台输出了message changed: Hello World! Hello Vue!说明我们的代码可以正常工作。4. 总结在本篇文章中我们实现了Watcher类它负责收集依赖当数据发生变化时会通知依赖。我们通过parsePath函数将路径解析成一个函数然后在getter中收集依赖在setter中通知依赖。这样我们就完成了响应式系统的核心功能。在下一篇文章中我们将实现computed和watch等功能。【免费下载链接】League-ToolkitAn all-in-one toolkit for LeagueClient. Gathering power .项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
英雄联盟Akari工具包:如何用智能模块化架构提升你的游戏体验
英雄联盟Akari工具包如何用智能模块化架构提升你的游戏体验【免费下载链接】League-ToolkitAn all-in-one toolkit for LeagueClient. Gathering power .项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit在英雄联盟的竞技场中每一秒的操作都可能决定胜负。你是否曾因为手速不够快而错失抢英雄的机会是否在紧张的符文配置中感到手忙脚乱今天我要为你介绍一款革命性的游戏辅助工具——英雄联盟Akari工具包它通过创新的模块化设计为不同水平的玩家提供个性化的智能辅助解决方案。 为什么Akari工具包与众不同与传统的单一功能辅助工具不同Akari工具包采用了模块化架构设计每个功能都是一个独立的“碎片”Shard可以根据你的需求灵活组合。这种设计理念让工具包具备了以下核心优势1. 前言在上一篇文章中我们实现了响应式数据并且当数据发生变化时能够通知到所有依赖该数据的依赖者那么我们如何收集依赖该数据的依赖者呢在Vue中数据发生变化后会通知到组件的render watcher然后render watcher再去执行render函数更新视图。那么我们如何知道是谁依赖了该数据呢换句话说我们如何收集依赖该数据的依赖者呢在Vue中是通过Watcher来收集依赖的Watcher是一个中介角色数据发生变化时通知它然后它再通知其他地方。Watcher是连接数据和视图的桥梁它会在初始化时收集依赖当数据发生变化时会通知Watcher然后Watcher再去通知依赖该数据的依赖者。接下来我们就来实现Watcher类。2. 思路分析我们之前已经实现了响应式数据并且当数据发生变化时能够通知到所有依赖该数据的依赖者那么我们如何收集依赖该数据的依赖者呢在Vue中数据发生变化后会通知到组件的render watcher然后render watcher再去执行render函数更新视图。那么我们如何知道是谁依赖了该数据呢换句话说我们如何收集依赖该数据的依赖者呢在Vue中是通过Watcher来收集依赖的Watcher是一个中介角色数据发生变化时通知它然后它再通知其他地方。Watcher是连接数据和视图的桥梁它会在初始化时收集依赖当数据发生变化时会通知Watcher然后Watcher再去通知依赖该数据的依赖者。接下来我们就来实现Watcher类。3. 实现Watcher类3.1 创建Watcher类首先我们在src/core/observer/watcher.js中创建Watcher类export default class Watcher { constructor(vm, expOrFn, cb) { this.vm vm; this.getter parsePath(expOrFn); this.cb cb; this.value this.get(); } get() { window.target this; let value this.getter.call(this.vm, this.vm); window.target undefined; return value; } update() { const oldValue this.value; this.value this.get(); this.cb.call(this.vm, this.value, oldValue); } }我们首先来看一下Watcher类的构造函数它接收三个参数vmVue实例expOrFn表达式或函数cb回调函数在构造函数中我们首先将vm实例保存到this.vm中然后将expOrFn解析成函数保存到this.getter中接着将回调函数保存到this.cb中最后调用this.get()方法获取表达式的值。get方法中我们首先将window.target设置为this也就是当前的Watcher实例然后调用this.getter方法获取表达式的值最后将window.target设置为undefined。这里为什么要将window.target设置为this呢这是因为我们在get方法中读取了数据会触发数据的getter在getter中我们会将window.target添加到依赖中这样我们就可以收集到依赖了。update方法中我们首先获取旧值然后调用get方法获取新值最后调用回调函数将新值和旧值传递给回调函数。3.2 解析路径在上面的代码中我们使用了parsePath函数来解析路径这个函数的作用是将路径解析成一个函数这个函数接收一个对象作为参数返回对象中对应路径的值。例如我们有一个对象obj它的值是{a: {b: {c: 1}}}我们想要获取obj.a.b.c的值我们可以这样写const getter parsePath(a.b.c); const value getter(obj); // 1parsePath函数的实现如下const bailRE /[^\w.$]/; export function parsePath(path) { if (bailRE.test(path)) { return; } const segments path.split(.); return function (obj) { for (let i 0; i segments.length; i) { if (!obj) return; obj obj[segments[i]]; } return obj; }; }首先我们使用正则表达式bailRE来检查路径是否合法如果路径中包含非字母、数字、下划线、点号的字符则返回undefined。然后我们将路径按照.分割成数组然后返回一个函数这个函数接收一个对象作为参数然后遍历数组依次获取对象中对应属性的值最后返回这个值。3.3 收集依赖在上面的代码中我们已经实现了Watcher类但是我们还不能收集依赖因为我们还没有在getter中添加依赖。接下来我们需要修改defineReactive函数在getter中添加依赖在setter中通知依赖。export function defineReactive(obj, key, val) { const dep new Dep(); const property Object.getOwnPropertyDescriptor(obj, key); if (property property.configurable false) { return; } const getter property property.get; const setter property property.set; if ((!getter || setter) arguments.length 2) { val obj[key]; } let childOb observe(val); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter() { const value getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); if (childOb) { childOb.dep.depend(); } } return value; }, set: function reactiveSetter(newVal) { const value getter ? getter.call(obj) : val; if (newVal value || (newVal ! newVal value ! value)) { return; } if (setter) { setter.call(obj, newVal); } else { val newVal; } childOb observe(newVal); dep.notify(); }, }); }我们首先在defineReactive函数中创建了一个Dep实例然后在getter中我们判断Dep.target是否存在如果存在则调用dep.depend()方法收集依赖。同时如果childOb存在则调用childOb.dep.depend()方法收集依赖。这样我们就完成了依赖的收集。在setter中我们首先获取旧值然后判断新值和旧值是否相等如果相等则直接返回。如果不相等则更新值然后调用dep.notify()方法通知依赖。3.4 测试接下来我们来测试一下我们的代码。我们创建一个index.html文件引入我们打包好的vue.js文件然后编写如下代码!DOCTYPE html html langen head meta charsetUTF-8 / meta nameviewport contentwidthdevice-width, initial-scale1.0 / titleDocument/title /head body div idapp/div script src./dist/vue.js/script script const vm new Vue({ el: #app, data: { message: Hello Vue!, }, render(h) { return h(div, this.message); }, }); vm.$watch(message, function (newVal, oldVal) { console.log(message changed:, newVal, oldVal); }); setTimeout(() { vm.message Hello World!; }, 1000); /script /body /html我们在index.html中创建了一个Vue实例然后监听message属性的变化当message属性发生变化时会触发回调函数打印出新值和旧值。然后我们在1秒后修改message属性的值我们可以看到控制台输出了message changed: Hello World! Hello Vue!说明我们的代码可以正常工作。4. 总结在本篇文章中我们实现了Watcher类它负责收集依赖当数据发生变化时会通知依赖。我们通过parsePath函数将路径解析成一个函数然后在getter中收集依赖在setter中通知依赖。这样我们就完成了响应式系统的核心功能。在下一篇文章中我们将实现computed和watch等功能。【免费下载链接】League-ToolkitAn all-in-one toolkit for LeagueClient. Gathering power .项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考