解析vue中observer数据双向绑定原理(代码分享)
时间:2021-09-03 来源:互联网
今天PHP爱好者给大家带来vue中observer数据双向绑定原理的介绍,之前的文章《浅析JS中Array对象一些操作方法(附代码)》中,给大家了解了JS中Array对象一些操作方法。下面本篇文章给大家了解vue中observer数据双向绑定原理,伙伴们来看看一下。希望对大家有所帮助。

vue数据双向绑定原理和简单的实现

1)vue数据双向绑定原理-observer
2)vue数据双向绑定原理-wather
3)vue数据双向绑定原理-解析器 Complie
vue数据双向绑定原理, 和简单的实现
去他喵的底层原理,框架内核,老夫写代码只用Jquery 。
个人觉得,不论是否是长期与之交集,还是应该看下核心的东西。多多了解高人是如何实现的,这样才能学到更多的知识,才能成长进步。倘若某天被人问起,某种框架内裤,其实现原理,那么只能是一脸懵逼了。
实现数据绑定的做法有大致如下几种:
发布者-订阅者模式(
backbone.js)脏值检查(
angular.js)数据劫持(
vue.js)
vue.js则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
假如写过C#winform自定义控件的,我想更好理解之后的逻辑和实现原理
在C#中当控件的某个属性发生了变化,就刷新视图
priveate int a ;
public int A
{
get { return a; }
set { if(a!=value){a = value; Invalidate(); } }
}
# 当a的值发生变化, 就重绘视图
再来看看Object.defineProperty(obj, prop, descriptor) 方法
地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。
obj需要被操作的目标对象prop目标对象需要定义或修改的属性的名称。descriptor将被定义或修改的属性的描述符
descriptor
configurable当且仅当该属性的configurable为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false。enumerable当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为false。数据描述符同时具有以下可选键值:value该属性对应的值。可以是任何有效的JavaScript值(数值,对象,函数等)。默认为undefined。writable当且仅当该属性的writable为true时,该属性才能被赋值运算符改变。默认为false。 存取描述符同时具有以下可选键值:get一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefined。set一个给属性提供
setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined。
先来实现一个简单数据劫持
var A = {};
var a = "";
Object.defineProperty(A, "a", {
set: function (value) {
a = value;
},
get: function () {
return "My name is " + a;
},
});
A.a = "chuchur";
console.log(A.a); // My name is chuchur
不光是这么简单,来看下vue的代码
<p id="app">
<input type="text" v-model="word" />
<p>{{word}}</p>
<button v-on:click="sayHi">change model</button>
</p>
<script>
var vm = new Vue({
el: "#app",
data: {
word: "Hello World!",
},
methods: {
sayHi: function () {
this.word = "Hi, everybody!";
},
},
});
</script>
已经实现的简单的数据劫持,那么有多个属性,就要实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,还需要一个订阅器Dep来收集这些属性的变动来通知订阅者
元素节点的v-model,v-on:click,就需要实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
最后实现一个订阅者Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
大概的流程图如下:

实现Observer
将需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上setter和getter这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
// observe
function observe(data) {
if (data && typeof data === "object") {
// 取出所有属性遍历
Object.keys(data).forEach(function (key) {
defineReactive(data, key, data[key]);
});
}
return;
}
function defineReactive(data, key, val) {
observe(val); // 监听子属性
Object.defineProperty(data, key, {
enumerable: true, // 可枚举
configurable: false, // 不能再define
get: function () {
return val;
},
set: function (value) {
console.log("监听到值变化了: ", val, "==>", value);
val = value;
},
});
}
var A = {
fristName: "chuchur",
age: 29,
};
observe(A);
A.fristName = "nana"; //监听到值变化了: chuchur ==> nana
A.age = 30; //监听到值变化了: 29 ==> 30
这样就实现了多个属性的监听,接下来就是实现订阅器Dep,当这些属性变化的时候,触发通知notify,告诉执行订阅者执行更新函数
//Dep
function Dep() {
this.subs = [];
}
Dep.prototype = {
addSub: function (sub) {
this.subs.push(sub);
},
notify: function () {
this.subs.forEach(function (sub) {
sub.update();
});
},
};
把订阅器植入到监听器里
function defineReactive(data, key, val) {
var dep = new Dep()
observe(val); //监听子属性
Object.defineProperty(data, key, {
set: function(value) {
dep.notify() //发出通知, 我被改变了
}
});
}
至此,简陋的监听器就实现完成了,接下来继续完成Watcher。
以上就是解析vue中observer数据双向绑定原理(代码分享)的详细内容,更多请关注php爱好者其它相关文章!
-
二重螺旋第3章怎么过-调停副本通关方法 2025-10-24 -
币安与欧易App市场事件推送及时性对比分析 2025-10-24 -
无限暖暖1.11新版本更新爆料-家园烹饪玩法即将上线 2025-10-24 -
arcaea体力怎么用-体力使用方法详解 2025-10-24 -
洛克王国世界电脑配置要求-洛克王国世界配置解析 2025-10-24 -
荒原曙光抓石头人怎么抓-安塔厄斯捕捉方法详解 2025-10-24