浅析vue数据绑定

前言:最近团队需要做一个分享,脚进脑子,不知如何分享。最后想着之前一直想研究一下 vue 源码,今天刚好 “借此机会” 研究一下。

网上研究vue数据绑定的文章已经非常多了,但是自己写一遍,敲一遍demo和看别人的文章是完全不同的,so……搬运工来了

目前数据绑定主要有以下三种实现方式:

1.   脏值检查(angular.js)    轮询检测数据变化

DOM事件,譬如用户输入文本,点击按钮等。( ng-click )

  • XHR响应事件 ( $http )
  • 浏览器Location变更事件 ( $location )
  • Timer事件( $timeout , $interval )
  • 执行 $digest() 或 $apply()

2、Object.defineProperty劫持对象的get、set,从而实现对数据的监控。 (vue)

3、发布/订阅者模式实现数据与视图的自动同步

Object.defineProperty的优点

  • “脏值检测”——数据发生变更后,对于所有的数据和视图的绑定关系进行一次检测,识别是否有数据发生了改变,有变化进行处理,可能进一步引发其他数据的改变,所以这个过程可能会循环几次,一直到不再有数据变化发生后,将变更的数据发送到视图,更新页面展现
  • Object.defineProperty() 监控对数据的操作,可以自动触发数据同步。并且,由于是在不同的数据上触发同步,可以精确的将变更发送给绑定的视图,而不是对所有的数据都执行一次检测。

Object.defineProperty的用法

var a = {};

Object.defineProperty(a, "b", {

 set: function (newValue) {

 console.log("我被赋值了!" + newValue);

 },

 get: function () {

 console.log("我被取值了!");

 return 2
 }
})

a.b = 3; //我被赋值了!

console.log(a.b); //我被取值了! //打印 2

由上面的例子看出,Object.defineProperty  传人3个参数

第一个: a对象

第二个: a对象里面的b属性

第三个: 属性比较多,列举有用的 value,set,get,configurable

数据绑定原理:

1、实现一个数据监听器Observer,对数据对象的所有属性进行监听,如有变动则拿到最新值并通知 dep数组

2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据

3、实现一个dep数组 ,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,更新视图

1. 实现observer

var data = {name: 'beidan'};

observe(data);

data.name = 'test'; // 监听到值变化了 beidan 变成 test

function observe(data) {

 if (!data || typeof data !== 'object') {

 return;

 }

 // 取出所有属性遍历

 Object.keys(data).forEach(function(key) {

  defineReactive(data, key, data[key]);

 });
}
function defineReactive(data, key, val) {


 Object.defineProperty(data, key, {

 enumerable: true, // 可枚举

  configurable: false, // 不能再define
  get: function() {

   return val;

  },

  set: function(newVal) {

   console.log('监听到值变化了 ', val, ' 变成 ', newVal);

   val = newVal;

  }

 });
}

2. 维护一个数组

function Dep() {

 this.subs = [];
}

Dep.prototype = {

 addSub: function (sub) {

 this.subs.push(sub);

 },

 notify: function (val) {

  this.subs.forEach(function (sub) {

  sub.update(val)

 });

}
};
function defineReactive(data, key, val) {
 Object.defineProperty(data, key, {
 ……
 set: function(newVal) {
  if (val === newVal) return;
  console.log('监听到值变化了 ', val, ' 变成 ', newVal);
  val = newVal;
  dep.notify(val); // 通知所有订阅者
 }
 });
}

3. compile

bindText: function () {

 var textDOMs = this.el.querySelectorAll('[v-text]'),
bindText,_context = this;


 for (var i = 0; i < textDOMs.length; i++) {

 bindText = textDOMs[i].getAttribute('v-text');
 textDOMs[i].innerHTML = this.data[bindText];

 var val = textDOMs[i]


 var up = function (text) {

  val.innerText = text

 }

 _context.dep.addSub({

  value: textDOMs[i],

  update: up

 });

 }
},

最后,附上源码 github   https://github.com/beidan/vue_bind

参考链接:

http://www.jb51.net/article/103297.htm

http://www.jb51.net/article/99129.htm

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持我们!

(0)

相关推荐

  • Vue实现双向数据绑定

    Vue实现双向数据绑定的方式,具体内容如下 Vue是如何实现双向数据绑定的呢?答案是前端数据劫持.其通过Object.defineProperty()方法,这个方法可以设置getter和setter函数,在setter函数中,就可以监听到数据的变化,从而更新绑定的元素的值. 实现对象属性变化绑定到UI 大概的思路是: 1. 确定绑定的数据,使用Object.defineProperty()对其数据变化进行监听(对应defineGetAndSet) 2. 一旦数据发生改动,会触发setter函数.

  • Vue.js中数据绑定的语法教程

    数据绑定语法 Vue.js 的模板是基于 DOM 实现的.这意味着所有的 Vue.js 模板都是可解析的有效的 HTML,且通过一些特殊的特性做了增强.Vue 模板因而从根本上不同于基于字符串的模板,请记住这点. 插值 文本 数据绑定最基础的形式是文本插值,使用 "Mustache" 语法(双大括号): <span>Message: {{ msg }}</span> Mustache 标签会被相应数据对象的 msg 属性的值替换.每当这个属性变化时它也会更新.

  • Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)

    我在整理javascript高级程序设计的笔记的时候看到面向对象设计那章,讲到对象属性分为数据属性和访问器属性,我们平时用的js对象90%以上都只是用到数据属性;我们向来讲解下数据属性和访问器属性到底是什么? 数据属性:数据属性包含一个数据值的位置,在这个位置可以读取和写入值. 访问器属性:访问器属性不包含数据值;他们包含一对getter和setter函数在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值,在写入访问器属性时,会调用setter函数并传入新值. 这里介绍的重点是

  • vue实现动态数据绑定

    实现的步骤: 1.监听对象属性的读取与变化 Object.defineProperty() 方法会直接在对象上定义一个新的的属性,或者已经存在的属性并且返回这个属性 语法是 Object.defineProperty(obj, prop, descript) obj: 目标对象 prop: 需要定义或修改的属性的名字 descript: 将被定义或修改的属性的描述符 描述: 这个方法精确添加或修改对象的属性,我们添加的属性是可以枚举的属性(Object.keys()/ for...in) 对象里

  • vue.js动态数据绑定学习笔记

    对于vue.js的动态数据绑定,经过反复地看源码和博客讲解,总算能够理解它的实现了,心累~ 分享一下学习成果,同时也算是做个记录.完整代码GitHub地址:https://github.com/hanrenguang/Dynamic-data-binding.也可以到仓库的 README 阅读本文,容我厚脸皮地求 star,求 follow. 整体思路 不知道有没有同学和我一样,看着vue的源码却不知从何开始,真叫人头大.硬生生地看了observer, watcher, compile这几部分的

  • Vue关于数据绑定出错解决办法

    Vue关于数据绑定出错 错误提示: 相对应的代码: <input id="input-check" type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value="b"> <label for="input-check">check</label> <scrip

  • 简单谈谈Vue 模板各类数据绑定

    『天下武功,唯快不破』√,这一直是对武学造诣方面的追捧,虽然对于这个丝毫不会:更是对待现实工作不懈渴求,乃至苛求.因为这已不是遁隐修行,而是职场卖命,唯有先快速解决需求,方能攫取更为充盈的时间去深究技术机理,以使臻于更强,更强而优于快,如此优良循环得以形成.言归正传,作为前端ER,一度觉得,这 Vue 的诞生,好比一柄倚天利器,其易上手,写以及运行也都很高效,十分让人爱不释手:但这易上手,倒不等于容易精通,蛮多东西都需悉心学习.练习.理解,才能运用自如. 在使用 Vue 开发过程中,那基于 Do

  • vue双向数据绑定原理探究(附demo)

    昨天被导师叫去研究了一下vue的双向数据绑定原理...本来以为原理的东西都非常高深,没想到vue的双向绑定真的很好理解啊...自己动手写了一个. 传送门 双向绑定的思想 双向数据绑定的思想就是数据层与UI层的同步,数据再两者之间的任一者发生变化时都会同步更新到另一者. 双向绑定的一些方法 目前,前端实现数据双向数据绑定的方法大致有以下三种: 1.发布者-订阅者模式(backbone.js) 思路:使用自定义的data属性在HTML代码中指明绑定.所有绑定起来的JavaScript对象以及DOM元

  • vue数据双向绑定的注意点

    最近一个vue和element的项目中遇到了一个问题: 动态生成的对象进行双向绑定是失败 直接贴代码: <el-form :model="addClass" :rules="rules" ref="addClass"> <el-form-item label="表单分类名称" prop="NAME" :label-width="formLabelWidth"> &

  • 浅析vue数据绑定

    前言:最近团队需要做一个分享,脚进脑子,不知如何分享.最后想着之前一直想研究一下 vue 源码,今天刚好 "借此机会" 研究一下. 网上研究vue数据绑定的文章已经非常多了,但是自己写一遍,敲一遍demo和看别人的文章是完全不同的,so--搬运工来了 目前数据绑定主要有以下三种实现方式: 1.   脏值检查(angular.js)    轮询检测数据变化 DOM事件,譬如用户输入文本,点击按钮等.( ng-click ) XHR响应事件 ( $http ) 浏览器Location变更事

  • 浅析 Vue 3.0 的组装式 API(一)

    (一)响应式数据 1. 简单例子 从最简单的数据绑定开始,在 Vue 2.0 中,我们这样将一个数据绑定到模板的指定位置: 在组件创建参数的 data 构造函数中返回一个用来绑定的数据对象,其中有个 now 字段,会被渲染到模板内的 .app > p 内. <template> <div class="app"> <h1>Hello world!</h1> <p>Now is: {{now.toString()}}<

  • 浅析Vue自定义组件的v-model

    最近在学习vue,今天看到自定义事件的表单输入组件,纠结了一会会然后恍然大悟...官方教程写得不是很详细,所以我决定总结一下. v-model语法糖 v-model实现了表单输入的双向绑定,我们一般是这么写的: <div id="app"> <input v-model="price"> </div> new Vue({ el: '#app', data: { price: '' } }); 通过该语句实现price变量与输入值双

  • 浅谈Vue数据绑定的原理

    本文介绍了Vue数据绑定的原理,分享给大家,具体如下: 原理 其实原理很简单,就是拦截了Object的get/set方法,在对数据进行set (obj.aget=18) 时去重现渲染视图 实现方式有两种 方式1 定义了同名的get/set就相当于定义了age var test = { _age: 18, get age() { console.log('触发get'); //直接会this.age会进入死递归的 return this._age; }, set age(age) { consol

  • 浅析Vue 中的 render 函数

    render函数是什么 简单的说,在vue中我们使用模板HTML语法组建页面的,使用render函数我们可以用js语言来构建DOM 因为vue是虚拟DOM,所以在拿到template模板时也要转译成VNode的函数,而用render函数构建DOM,vue就免去了转译的过程. 当使用render函数描述虚拟DOM时,vue提供一个函数,这个函数是就构建虚拟DOM所需要的工具.官网上给他起了个名字叫createElement.还有约定的简写叫h, vm中有一个方法_c,也是这个函数的别名 先看官网对

  • 浅析vue cli3 封装Svgicon组件正确姿势(推荐)

    vue cli3 手把手教学封装Svgicon组件 第一步:在src文件下新建一个放置svg文件的文件夹 第二步:在components文件下新建一个Svg组件 这是一个 文件夹 专门用来存放项目里面需要使用的svg文件,比如 a.svg b.svg - svg组件源码 <template> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="iconNam

  • 深入浅析vue全局环境变量和模式

    我们可以在项目根目录中的下列文件来指定环境变量: .env                # 在所有的环境中被载入 .env.local          # 在所有的环境中被载入,但会被 git 忽略 .env.[mode]         # 只在指定的模式中被载入 .env.[mode].local   # 只在指定的模式中被载入,但会被 git 忽略 一个环境文件只包含环境变量的"键=值"对,并且必须以VUE_APP开始: FOO=bar     //无效 VUE_APP_SE

  • Vue 数据绑定的原理分析

    原理 其实原理很简单,就是拦截了Object的get/set方法,在对数据进行set(obj.aget=18)时去重现渲染视图 实现方式有两种 方式1 定义了同名的get/set就相当于定义了age var test = { _age: 18, get age() { console.log('触发get'); //直接会this.age会进入死递归的 return this._age; }, set age(age) { console.log('触发set'); this._age = ag

  • 浅析vue中的nextTick

    背景 vue是异步渲染的,当data改变之后,DOM不会立刻被渲染,页面渲染时会将data的修改做整合,多次data修改只会做整合最后一次性渲染出来,这也是异步渲染的原因.只有异步渲染才可以实现整合操作. 例子 methods: { update() { for (let i = 0; i < 10; i++) { this.testNum = this.testNum + i; } }, }, 在你的 Vue 视图中, testNum 会发生变化.不过需要注意的是这个变化的过程,虽然我们把 f

  • 浅析VUE防抖与节流

    防抖和节流到底是啥 函数防抖(debounce) 解释:当持续触发某事件时,一定时间间隔内没有再触发事件时,事件处理函数才会执行一次,如果设定的时间间隔到来之前,又一次触发了事件,就重新开始延时. 案例:持续触发scroll事件时,并不立即执行handle函数,当1000毫秒内没有触发scroll事件时,才会延时触发一次handle函数. function debounce(fn, wait) { let timeout = null return function() { if(timeout

随机推荐