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

品牌网站建设专家高端网站设计建设

品牌网站建设专家,高端网站设计建设,合肥制作网站单位有哪些,网页设计公司兴田德润实力强我们之前说道过Object.defineProperty方法有一关键特性,就是数据劫持,通过get/set 拦截属性的读取和修改操作。Vue主要是通过数据劫持结合发布-订阅模式来实现的,利用Object.defineProperty来劫持各个属性的setter和getter,在数据…

我们之前说道过Object.defineProperty方法有一关键特性,就是数据劫持,通过get/set 拦截属性的读取和修改操作。Vue主要是通过数据劫持结合发布-订阅模式来实现的,利用Object.defineProperty来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

1. Vue2 实现过程

我们来具体看一下Vue的实现过程吧

  1. 在Vue类中,接收一个options参数,里面包含data等选项,在构造函数里,我需要将data对象进行响应式处理。这一步应该是通过遍历data的所有属性,并用Object.defineProperty来重新定义它们,使得当属性被访问时收集依赖,被修改时触发更新。

  2. 对于每个属性,需要有一个Dep(依赖收集器)来管理所有的Watcher实例。每当属性被读取时,就将当前的Watcher添加到Dep中;当属性被修改时,Dep就会通知所有Watcher执行更新操作。

  3. 既然有Watcher实例,那么就有一个Watcher类,它负责订阅属性的变化,并在变化时执行回调函数,比如更新视图。在Watcher的构造函数中,需要将自己设置为全局的一个目标实例,然后触发属性的getter,从而将Watcher添加到Dep中。

  4. 还有,可能需要一个编译器(Compiler)来解析模板中的指令,比如v-model,然后初始化相应的数据绑定和事件监听。例如,对于v-model,需要将input元素的值与数据属性同步,并在输入时更新数据属性,从而触发数据的setter,进一步通知更新。

现在,我需要一步步构建这些类。首先是Vue类,它初始化数据,进行响应式处理。然后,每个数据属性都有一个对应的Dep实例。当数据被访问时,收集当前的Watcher;数据变化时,通知Dep里的所有Watcher更新。

然后,Watcher类的作用是连接数据属性和具体的更新函数,比如更新DOM。当数据变化时,Watcher会被触发,执行更新函数。

在这里插入图片描述

2. Vue2 组成结构

总体来说应有以下结构:

  1. Vue类:

作用:

  • 接收options,处理data。

  • 将data的属性转为getter/setter。

  • 调用observe函数进行响应式处理。

  1. Observer类:

作用:

  • 遍历对象的所有属性,转为响应式。

  • 每个属性有一个Dep实例。

  1. Dep类:

作用:

  • 收集Watcher实例(subs数组)。

  • 提供addSub方法添加Watcher。

  • 提供notify方法触发所有Watcher的update。

  1. Watcher类:

作用:

  • 在实例化时,将自身赋值给Dep.target。

  • 访问对应的数据属性,触发getter,从而将自身添加到Dep中。

  • 定义update方法,执行回调函数(比如更新DOM)。

接下来是具体的代码实现。可能还需要处理多个Watcher的情况,以及如何将它们正确地关联到对应的Dep。

然后,需要处理模板编译。比如,对于v-model,需要找到元素,添加事件监听,当输入时更新数据属性。同时,初始化input的值。对于{{}}文本,需要替换为对应的数据,并建立Watcher,当数据变化时更新文本内容。

不过,我们现在只是简单展示一下实现原理,直接操作DOM元素,而不是完整的编译器。例如,手动绑定一个input和显示元素,展示双向绑定的效果。

现在,我需要将上述思路转化为代码。可能先从Vue类开始:

class Vue{constructor(options){this.$options = options;this._data = typeof options.data === 'function' ? options.data() : options.data;//调用Observer函数进行响应式处理new Observer(this._data);this.compile();}compile() {// 处理v-model绑定const inputs = document.querySelectorAll('[v-model]');inputs.forEach(input => {const key = input.getAttribute('v-model').trim();input.value = this._data[key];input.addEventListener('input', (e) => {this._data[key] = e.target.value;});});// 处理{{ }} 绑定const elements = document.querySelectorAll('p,span,div'); // 简化处理,实际应根据文本内容匹配elements.forEach(element => {const matches = element.innerHTML.match(/\{\{\s*(.*?)\s*\}\}/);if (matches) {const key = matches[1].trim();new Watcher(this._data, key, (newVal) => {element.innerHTML = newVal;});// 初始化显示element.innerHTML = this._data[key];}});}
}
 // Observer类:// 遍历对象的所有属性,转为响应式// 每个属性有一个Dep实例     class Observer{constructor(data){this.walk(data);}walk(data){Object.keys(data).forEach(key =>{this.defineReactive(data,key,data[key]);})console.log(Object.keys(data))}defineReactive(obj,key,val){const dep = new Dep();Object.defineProperty(obj,key,{enumberable:true,configurable:true,get(){if(Dep.target){dep.addSub(Dep.target)}return val;},set(newVal){if(newVal === val) return;val = newVal;dep.notify();}})}}
// 收集Watcher实例(subs数组)
// 提供addSub方法添加wathcer// 提供notify方法触发所有的Watcher 和 update。class Dep{constructor(){this.subs = [];}addSub(sub){this.subs.push(sub);}notify(){this.subs.forEach(sub => sub.update())}}Dep.target = null;
// 在实例化时,将自身赋值给Dep.target
// 访问对应的数据属性,触发getter,从而将自身添加到Dep中。// 定义update方法,执行回调函数(比如更新Dom)class Watcher{constructor(data,key,cb){this.data = data;this.key = key;this.cb= cb;this.value = this.get();}get(){Dep.target = this; // 将当前Watcher实例赋值给Dep.targetconst value = this.data[this.key]; // 触发getter,从而将Watcher添加到Dep中Dep.target = null;//收集完清空return value;}update(){const newVal = this.data[this.key];if (newVal !== this.value) {this.value = newVal;this.cb(newVal);}}}

以下是完成的可运行代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>vue2数据的双向绑定</title>
</head>
<body><input type="text" v-model="message"><div id="app"><p>{{ message }}</p></div><script>// 收集Watcher实例(subs数组)// 提供addSub方法添加wathcer// 提供notify方法触发所有的Watcher 和 update。class Dep{constructor(){this.subs = [];}addSub(sub){this.subs.push(sub);}notify(){this.subs.forEach(sub => sub.update())}}Dep.target = null;// 在实例化时,将自身赋值给Dep.target// 访问对应的数据属性,触发getter,从而将自身添加到Dep中。// 定义update方法,执行回调函数(比如更新Dom)class Watcher{constructor(data,key,cb){this.data = data;this.key = key;this.cb= cb;this.value = this.get();}get(){Dep.target = this; // 将当前Watcher实例赋值给Dep.targetconst value = this.data[this.key]; // 触发getter,从而将Watcher添加到Dep中Dep.target = null;//收集完清空return value;}update(){const newVal = this.data[this.key];if (newVal !== this.value) {this.value = newVal;this.cb(newVal);}}}class Vue{constructor(options){this.$options = options;this._data = typeof options.data === 'function' ? options.data() : options.data;//调用Observer函数进行响应式处理new Observer(this._data);this.compile();}compile() {// 处理v-model绑定const inputs = document.querySelectorAll('[v-model]');inputs.forEach(input => {const key = input.getAttribute('v-model').trim();input.value = this._data[key];input.addEventListener('input', (e) => {this._data[key] = e.target.value;});});// 处理{{ }} 绑定const elements = document.querySelectorAll('p,span,div'); // 简化处理,实际应根据文本内容匹配elements.forEach(element => {const matches = element.innerHTML.match(/\{\{\s*(.*?)\s*\}\}/);if (matches) {const key = matches[1].trim();new Watcher(this._data, key, (newVal) => {element.innerHTML = newVal;});// 初始化显示element.innerHTML = this._data[key];}});}}// Observer类:// 遍历对象的所有属性,转为响应式// 每个属性有一个Dep实例     class Observer{constructor(data){this.walk(data);}walk(data){Object.keys(data).forEach(key =>{this.defineReactive(data,key,data[key]);})console.log(Object.keys(data))}defineReactive(obj,key,val){const dep = new Dep();Object.defineProperty(obj,key,{enumberable:true,configurable:true,get(){if(Dep.target){dep.addSub(Dep.target)}return val;},set(newVal){if(newVal === val) return;val = newVal;dep.notify();}})}}new Vue({data: () => ({message: "hello world"})});</script>
</body>
</html>

看完了此篇文章,您是不是对Vue2实现原理有了更深刻的理解呢,如果觉得对您有帮助,还请一键三连哦!非常感谢!


文章转载自:

http://NkO1TnbD.tytLy.cn
http://DjM53JK4.tytLy.cn
http://goAy8B8r.tytLy.cn
http://FuvzyiGD.tytLy.cn
http://NCVDPR6B.tytLy.cn
http://uFnffea7.tytLy.cn
http://tIgInyNy.tytLy.cn
http://lv68ERts.tytLy.cn
http://0ann5k56.tytLy.cn
http://paC5Upyc.tytLy.cn
http://Y6dyGnCB.tytLy.cn
http://pqnbPY8L.tytLy.cn
http://4MWTm4sB.tytLy.cn
http://U9klRdPA.tytLy.cn
http://WJUWlJ4u.tytLy.cn
http://SywEFCqa.tytLy.cn
http://D56YOfzL.tytLy.cn
http://pKmkI2EU.tytLy.cn
http://AkKXsOxw.tytLy.cn
http://pDphKBVK.tytLy.cn
http://wbo0zTka.tytLy.cn
http://4ejt4eA8.tytLy.cn
http://Ndd7XJGV.tytLy.cn
http://qdZlBolR.tytLy.cn
http://JNTaV7Ev.tytLy.cn
http://seZzEFWi.tytLy.cn
http://GSKNe0rt.tytLy.cn
http://IKGTFSxE.tytLy.cn
http://pSiAgU62.tytLy.cn
http://MwjYJO3x.tytLy.cn
http://www.dtcms.com/wzjs/770716.html

相关文章:

  • 随州建设网站seo商学院
  • 游戏网站模板下载多个网站优化怎么做
  • 学校门户网站流程建设方案深圳建筑业网站建设
  • 兼职网站推广如何做外包公司网站开发
  • 家庭清洁东莞网站建设技术支持市场营销策略概念
  • 学校网站开发系统的背景网页设计难学吗有技术含量吗
  • 韩国网站源码下载wordpress词典插件下载
  • 农村电商扶贫网站建设phpcms中英文网站模板
  • 沧州网站推广优化安徽网站建设详细策划
  • 基本型电子商务网站wordpress轻拟物主题
  • 嘉兴网站seo外包帮人建网站价格赚钱吗
  • 网页模板下载后怎么用优化大师app下载安装
  • 珠宝首饰网站建设外链下载
  • 南昌手机模板建站吉林长春最新消息
  • 网站建设公司怎么做业务企业公司网站
  • 杭州网站建设招聘wordpress改网页电话
  • 织梦网站做seo优化做仿牌网站被封
  • 外贸长尾关键词挖掘网站电子类工程师报考入口
  • 企业网站制作设计网站建建设
  • 郑州o2o网站建设汉狮logo图案设计
  • 单页式网站 seo小白测评做网站
  • 十大不收费看盘网站自适应网站建设价格
  • 广东湛江怎么做网站教程怎样用ps做网站首页图片
  • frontpage制作个人网站 技巧阿里云虚拟机搭建wordpress
  • 网站开发公司会在最后面加上公司wordpress导航栏透明
  • 手机定制网站建设用搬瓦工做网站
  • 有趣的网站网址成都旅游公司
  • 重庆整合营销网站建设电商网站建设的步骤
  • 投资公司网站建设建设网站功能
  • 免费行情软件网站mnw西宁网站开发多少钱