深圳小程序开发_详解VueJS 数据驱动和依赖追踪分析

  • 栏目:公司新闻 时间:2021-01-11 15:52 分享新闻到:
<返回列表

详解VueJS 数据驱动和依赖追踪分析       这篇文章主要介绍了详解VueJS 数据驱动和依赖追踪分析,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

之前关于 Vue 数据绑定原理的一点分析,最近需要回顾,就顺便发到随笔上了

在之前实现一个自己的Mvvm中,用 setter 来观测model,将界面上所有的 viewModel 绑定到 model 上。 当model改变,更新所有的viewModel,将新值渲染到界面上 。同时监听界面上通过v-model 绑定的所有 input,并通过 addEventListener事件将新值更新到 model 上,以此来完成双向绑定 。

但是那段程序除了用来理解 defineProperty,其它一文不值。

没有编译节点 。 没有处理表达式依赖 。

这里我将解决表达式依赖这个问题,vue 模板的编译我会在下一节介绍 。

为数据定义 getter setter

class Observer {
 constructor(data) {
 this._data = data;
 this.walk(this._data);
 walk(data) {
 Object.keys(data).forEach((key) = { this.defineRective(data, key, data[key]) })
 defineRective(vm, key, value) {
 var self = this;
 if (value typeof value === "object") {
 this.walk(value);
 Object.defineProperty(vm, key, {
 get: function() {
 return value;
 set: function(newVal) {
 if (value != newVal) {
 if (newVal typeof newVal === "object") {
 self.walk(newVal);
 value = newVal;
module.exports = Observer;

这样,就为每个属性添加了 getter 和 setter ,当属性是一个对象,那么就递归添加。

一旦获取属性值或者为属性赋值就会触发 get 或 set ,当触发了 set,即model变化,就可以发布一个消息,通知所有viewModel 更新。

defineRective(vm, key, value) {
 // 将这个属性的依赖表达式存储在闭包中。
 var dep = new Dep();
 var self = this;
 if (value typeof value === "object") {
 this.walk(value);
 Object.defineProperty(vm, key, {
 get: function() {
 return value;
 set: function(newVal) {
 if (value != newVal) {
 if (newVal typeof newVal === "object") {
 self.walk(newVal);
 value = newVal;
 // 通知所有的 viewModel 更新
 dep.notify();

那么怎么定义 Dep 呢??

class Dep {
 constructor() {
 // 依赖列表
 this.dependences = [];
 // 添加依赖
 addDep(watcher) {
 if (watcher) {
 this.dependences.push(watcher);
 // 通知所有依赖更新
 notify() {
 this.dependences.forEach((watcher) = {
 watcher.update();
module.exports = Dep;

这里的每个依赖就是一个Watcher 。

看看如何定义 Watcher

这里每一个 Watcher 都会有一个唯一的id号,它拥有一个表达式和一个回调函数 。

比如 表达式 a +b ; 会在get 计算时 访问 a 与 b , 由于 JavaScript是单线程,任一时刻只有一处JavaScript代码在执行, 用Dep.target 作为一个全局变量来表示当前 Watcher pute 访问 a ,b ,触发 a 与b 的getter,在 getter 里面将 Dep.target 添加为依赖 。

一旦 a 与 b 的set 触发,调用 update 函数,更新依赖的值 。

var uid = 0;
class Watcher {
 constructor(viewModel, exp, callback) {
 this.viewModel = viewModel;
 this.id = uid++;
 this.exp = exp;
 this.callback = callback;
 this.oldValue = "";
 this.update();
 get() {
 Dep.target = this;
 var res = pute(this.viewModel, this.exp);
 Dep.target = null;
 return res;
 update() {
 var newValue = this.get();
 if (this.oldValue === newValue) {
 return;
 // callback 里进行Dom 的更新操作
 this.callback(newValue, this.oldValue);
 this.oldValue = newValue;
 compute(viewModel, exp) {
 var res = replaceWith(viewModel, exp);
 return res;
module.exports = Watcher;

由于当前表达式需要在 当前的model下面执行,所以 采用replaceWith 函数来代替 with ,具体可以查看另一篇随笔。

通过get 添加依赖

Object.defineProperty(vm, key, {
 get: function() {
 var watcher = Dep.target;
 if (watcher !dep.dependences[watcher.id]) {
 dep.addDep(watcher);
 return value;
 set: function(newVal) {
 if (value != newVal) {
 if (newVal typeof newVal === "object") {
 self.walk(newVal);
 value = newVal;
 dep.notify();
})

这种添加依赖的方式实在太巧妙了 。

 这里我画了一个图来描述

最后通过一段代码简单测试一下

const Observer = require('./Observer.js');
const Watcher = require('./watcher.js');
var data = {
 a: 10,
 b: {
 c: 5,
 d: {
 e: 20,
var observe = new Observer(data);
var watcher = new Watcher(data, "a+b.c", function(newValue, oldValue) {
 console.log("new value is " + newValue);
 console.log("oldValue is " + oldValue);
console.log("\r\n");
console.log("a has changed to 50,then the expr should has value 55");
data.a = 50;
console.log("\r\n");
console.log("b.c has changed to 50,then the expr should has value 122");
data.b.c = 72;;
console.log("\r\n");
console.log("b.c has reseted an object,then the expr should has value 80");
data.b = { c: 30 }

OK 大功告成

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持凡科。


分享新闻到:

更多阅读

深圳小程序开发_详解VueJS 数据驱动和依赖

公司新闻 2021-01-11
详细说明VueJS 数据信息驱动器和依靠跟踪剖析 本文关键详细介绍了详细说明VueJS 数据信...
查看全文

唐山市网站建设-旺龙智能品牌VI设计

公司新闻 2021-01-11
旺龙开创于一九九七年,是我国智能化一可爱卡通综合性处理计划方案创导者。依次创造发明...
查看全文

广州凡科互联网科技股份有限公司招聘剪

公司新闻 2021-01-11
招聘人数:24职位信息岗位职责:1、负责短视频剪辑、字幕、音效及画面处理以合成输出;2、...
查看全文
返回全部新闻


区域站点: 南丰县主图制作软件   南宫市自动抠图   囊谦县图片加水印   南和县怎么p图   南华县主图制作软件   南江县自动抠图   南京市图片加水印   南靖县怎么p图   南康市主图制作软件   南乐县自动抠图   南陵县图片加水印   南宁市怎么p图   南平市主图制作软件   南皮县自动抠图   南市区图片加水印   南通市怎么p图   南投县主图制作软件   南雄市自动抠图   南溪县图片加水印   南阳市怎么p图   南漳县主图制作软件   南召县自动抠图   南郑县图片加水印   那坡县怎么p图   那曲县主图制作软件   纳雍县自动抠图   讷河市图片加水印   内黄县怎么p图   内江市主图制作软件   内丘县自动抠图   内乡县图片加水印   嫩江市怎么p图   聂荣县主图制作软件   尼玛县自动抠图   尼木县图片加水印   宁安市怎么p图   宁波市主图制作软件   宁城县自动抠图   宁德市图片加水印   宁都县怎么p图   宁国市主图制作软件   宁海县自动抠图   宁化县图片加水印   宁晋县怎么p图   宁陵县主图制作软件   宁明县自动抠图   宁南县图片加水印   宁强县怎么p图   宁陕县主图制作软件   宁武县自动抠图   宁乡市图片加水印   宁阳县怎么p图   宁远县主图制作软件   农安县自动抠图   磐安县图片加水印   盘锦市怎么p图   盘山县主图制作软件   磐石市自动抠图   盘州市图片加水印   蓬安县怎么p图   澎湖县主图制作软件   蓬莱市自动抠图   彭山县图片加水印   蓬溪县怎么p图   彭阳县主图制作软件   彭泽县自动抠图   彭州市图片加水印   偏关县怎么p图   平安县主图制作软件   平昌县自动抠图   平定县图片加水印   屏东县怎么p图   平度市主图制作软件   平果县自动抠图   平和县图片加水印   平湖市怎么p图   平江县主图制作软件   平乐县自动抠图   平凉市图片加水印   平利县怎么p图   平罗县主图制作软件   平陆县自动抠图   屏南县图片加水印   平泉市怎么p图   屏山县主图制作软件   平顺县自动抠图   平塘县图片加水印   平潭县怎么p图   平武县主图制作软件   萍乡市自动抠图   平乡县图片加水印   平阳县怎么p图   平遥县主图制作软件   平阴县自动抠图   平邑县图片加水印   平远县怎么p图   平舆县主图制作软件   皮山县自动抠图   普安县图片加水印   浦北县怎么p图   浦城县主图制作软件   普洱市自动抠图   普格县图片加水印   浦江县怎么p图   普兰县主图制作软件   普宁市自动抠图   莆田市图片加水印   迁安市怎么p图   乾安县主图制作软件   潜江市自动抠图   潜山市图片加水印  

友情链接: 一键抠图在线 在线ps抠图 在线ps抠图 免费做图 手机版

Copyright © 2002-2020 图片加水印_怎么p图_主图制作软件_自动抠图_抠图网址 版权所有 (网站地图) 备案号:粤ICP备10235580号