当前位置: 首页> 文旅> 艺术 > 商业网名_网站的日常维护主要包括_搜索关键词的网站_cnzz统计

商业网名_网站的日常维护主要包括_搜索关键词的网站_cnzz统计

时间:2025/7/11 7:45:06来源:https://blog.csdn.net/2301_76603086/article/details/147143181 浏览次数:0次
商业网名_网站的日常维护主要包括_搜索关键词的网站_cnzz统计

双向数据绑定原理

  1. Vue实现数据双向绑定核心原理是MVVM模式
    • Model(数据层):Vue中的数据模型,用来存储数据
    • View(视图层):Vue中的视图界面,由HTML模板和Vue指令组成
    • ViewModel(业务逻辑层):核心,是一个Vue实例,充当Model和View的桥梁
      • 数据变化时,通过监听器(Observer)触发依赖通知,更新视图层。
      • 用户操作视图时,解析器(Compiler)捕获事件(如v-model输入),更新数据层。

双向绑定的实现

  1. 监听器
    • 用于监听数据变化,方式有数据劫持、发布-订阅模式

    • 数据劫持

      • Vue2:使用Object.defineProperty来拦截对象属性的gettersetter,在getter中收集依赖,在数据变化时通知视图更新,在setter中,通过触发依赖收集中的更新函数,实现视图更新。(Object.defineProperty() - JavaScript | MDN)

        //示例
        const o = {};
        let bValue = 38;
        Object.defineProperty(o, "b", {get() {//收集依赖return bValue;},set(newValue) {bValue = newValue;// 触发视图更新},
        });
        
      • Vue3:使用Proxy代替Object.defineProperty,用于创建一个对象的代理,从而实现基本操作的拦截和自定义,调用get方法时,会进行依赖收集,调用set方法时,会进行依赖更新(Proxy - JavaScript | MDN)

        • 语法:const p = new Proxy(target, handler)

        • 参数:

          • target

            要使用 Proxy 包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。

          • handler

            一个通常以函数作为属性的对象,各属性中的函数分别定义了在执行各种操作时代理 p 的行为。

        //示例
        let products = new Proxy({browsers: ["Internet Explorer", "Netscape"],},{get: function (obj, prop) {// 收集依赖return obj[prop];},set: function (obj, prop, value) {obj[prop] = value;// 触发视图更新,表示成功return true;},},
        );
        
    • 发布-订阅模式

      • Vue.js 通过这个模式来管理组件和数据之间的依赖关系。每当数据变化时,依赖于这些数据的视图(或者是观察者)会被通知并更新

        // 1. 发布者类
        class Dep {constructor() {this.subscribers = [];}// 依赖收集depend() {if (Dep.target && !this.subscribers.includes(Dep.target)) {this.subscribers.push(Dep.target);}}// 通知更新notify() {this.subscribers.forEach(sub => sub());}
        }// 2. 
        // ①数据劫持 Vue2-Start
        function defineReactive(obj, key, val) {const dep = new Dep();Object.defineProperty(obj, key, {get() {dep.depend();      // 收集依赖return val;},set(newVal) {val = newVal;dep.notify();      // 触发更新}});
        }
        // Vue2-End// ②响应式代理 Vue3-Start
        function reactive(obj) {const deps = new Map(); // 存储每个属性的依赖return new Proxy(obj, {get(target, key) {let dep = deps.get(key);if (!dep) {dep = new Dep();deps.set(key, dep);}if (Dep.currentEffect) {dep.depend(Dep.currentEffect); // 收集依赖}return target[key];},set(target, key, value) {target[key] = value;deps.get(key)?.notify(); // 触发更新return true;}});
        }
        // Vue3-End// 3. 观察者函数
        function watch(effect) {Dep.target = effect;   // 标记当前依赖effect();              // 首次执行以触发getterDep.target = null;     // 重置
        }// 使用示例
        const data = {};
        defineReactive(data, 'count', 0);// 订阅数据变化
        watch(() => {console.log('Count updated:', data.count);
        });// 触发更新
        data.count = 1; // 输出: "Count updated: 1"
        
  2. Compile 模板解析

    • 实现视图到数据的绑定

    • 解析阶段

      • 遍历DOM树,识别指令(如v-model{{}}插值)。
      • 为每个指令创建对应的更新函数,绑定到数据依赖。
    • 绑定示例

      function compileInput(node, data, key) {node.value = data[key]; // 初始化值node.addEventListener('input', (e) => {data[key] = e.target.value; // View → Model});// 订阅数据变化,更新视图watch(key, (value) => node.value = value); // Model → View
      }
      
    • 虚拟DOM优化

      • 将模板转换为轻量级的虚拟DOM树。
      • 数据变化时,生成新虚拟DOM,通过Diff算法比对差异,仅更新真实DOM的必要部分。

参考资料
https://juejin.cn/post/6844903942254510087#heading-9
https://zhuanlan.zhihu.com/p/685914161

在这里插入图片描述

关键字:商业网名_网站的日常维护主要包括_搜索关键词的网站_cnzz统计

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: