// html

<body>
<div id="app">
    <input type="text" v-model="number">
    <input type="text" v-model="num">
    <input type="button" v-click="increment" value="加1">
    <input type="button" v-click="increment" value="加2">
    <h3 v-bind="number"></h3>
    <h3 v-bind="num"></h3>
  </div>
</body>
// js vue的实例

  window.onload = function () {
var app = new Vue({
el: '#app',
data: {
number: ,
num: ,
},
methods: {
increment: function () {
this.number++;
this.num++;
},
}
})
}
// vue的构造函数

  function Vue(options) {
this._init(options);
}
Vue.prototype._init = function (options) {
this.$options = options;
this.$el = document.querySelector(options.el);
this.$data = options.data;
this.$methods = options.methods; this._binding = {};
this._obverse(this.$data);
this._complie(this.$el);
}
Vue.prototype._obverse = function (obj) {
var _this = this
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
this._binding[key] = {
_directives: []
};
let value = obj[key];
if (typeof value === 'object') {
this._obverse(value);
}
let binding = this._binding[key];
Object.defineProperty(this.$data, key, {
enumerable: true,//目标属性是否可以被枚举。true | false
configurable: true, //目标属性是否可以被删除或是否可以再次修改特性 true | false
get: function () {
return value;
},
set: function (newVal) {
if (value !== newVal) {
value = newVal;
binding._directives.forEach(function (item) {
item.update();
})
}
}
})
}
}
} Vue.prototype._complie = function (root) {
var _this = this;
var nodes = root.children;
for (let i = ; i < nodes.length; i++) {
let node = nodes[i];
if (node.children.length) {
_this._complie(node);
} if (node.hasAttribute('v-click')) {
node.onclick = (function () {
var attrVal = nodes[i].getAttribute('v-click');
return _this.$methods[attrVal].bind(_this.$data);
})(i);
} if (node.hasAttribute('v-model') && (node.tagName == 'INPUT' || node.tagName == 'TEXTAREA')) {
node.addEventListener('input', (function() {
var attrVal = node.getAttribute('v-model');
_this._binding[attrVal]._directives.push(new Watcher(
'input',
node,
_this,
attrVal,
'value'
))
return function () {
_this.$data[attrVal] = nodes[key].value;
}
})());
}
if(node.hasAttribute("v-bind")){
var attrVal = node.getAttribute('v-bind');
_this._binding[attrVal]._directives.push(new Watcher(
'text',
node,
_this,
attrVal,
'innerHTML'
))
}
}
}
function Watcher(name, el, vm, exp, attr) {
this.name = name; //指令名称,例如文本节点,该值设为"text"
this.el = el; //指令对应的DOM元素
this.vm = vm; //指令所属myVue实例
this.exp = exp; //指令对应的值,本例如"number"
this.attr = attr; //绑定的属性值,本例为"innerHTML" this.update();
}
Watcher.prototype.update = function () {
this.el[this.attr] = this.vm.$data[this.exp];
}

vue之双绑实现的更多相关文章

  1. 前端MVVM模式及其在Vue和React中的体现

    MVVM相关概念 Mvvm 前端数据流框架精讲 1) MVVM典型特点是有四个概念:Model.View.ViewModel.绑定器.MVVM可以是单向绑定也可以是双向绑定甚至是不绑定 2) 绑定器: ...

  2. Vue.js 是如何实现 MVVM 的?

    目录 框架到底为我们做了什么? 如何理解 MVVM ? 如何实现 MVVM - 以 Vue.js 为例 Vue 如何实现响应式 Vue 如何解析模板 Vue.js 运行机制 手写一个 Vue.js 框 ...

  3. 理解MVVM在react、vue中的使用

    理解MVVM在react.vue中的使用 一:什么是MVC.为什么不用MVC 1:MVC的含义: M(modal):是应用程序中处理数据逻辑的部分. V (view)  :是应用程序中数据显示的部分. ...

  4. [转] Vue原理解析——自己写个Vue

    一.Vue对比其他框架原理 Vue相对于React,Angular更加综合一点.AngularJS则使用了“脏值检测”. React则采用避免直接操作DOM的虚拟dom树.而Vue则采用的是 Obje ...

  5. Vue原理解析——自己写个Vue

    Vue由于其高效的性能和灵活入门简单.轻量的特点下变得火热.在当今前端越来越普遍的使用,今天来剖析一下Vue的深入响应式原理. tips:转自我的博客唐益达博客,此为原创.转载请注明出处,原文链接 一 ...

  6. vue踩坑

    1. 双向绑定的对象 改变或新增其属性 DOM不刷新问题 var obj = { "attr1": "1", "attr2": [2] }; ...

  7. Vue(1)

    一:概述 Vue是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用.Vue的核心库只关心视图层,不仅易于上手,还便于与第三方库或既有项目 ...

  8. Vue学习记录第一篇——Vue入门基础

    前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...

  9. Vue入门基础

    前面的话 Vue中文文档写得很好,界面清爽,内容翔实.但文档毕竟不是教程,文档一上来出现了大量的新概念,对于新手而言,并不友好.个人还是比较喜欢类似于<JS高级程序设计>的风格,从浅入深, ...

随机推荐

  1. xp系统报错 windows explorer has encountered a problem and needs to close.We are sorry for the inconvenience

    xp系统遇到问题: 打开某个软件提示报错信息, windows explorer has encountered a problem and needs to close.We are sorry f ...

  2. loading图标modal弹窗 和jquery ajax的关系

    在ajax配置中 ,async:false,非异步,modal窗口会失效,只有重新设置为async:true,或者删除async的设置,则loading的模态框才能展示出来 loading图标的模态框 ...

  3. 使用webmagic搭建一个简单的爬虫

    刚刚接触爬虫,听说webmagic很不错,于是就了解了一下. webmagic的是一个无须配置.便于二次开发的爬虫框架,它提供简单灵活的API,只需少量代码即可实现一个爬虫. 这句话说的真的一点都不假 ...

  4. linux内存管理之vmalloc函数分析

    2017-07-09 今天周末,闲来无事聊聊linux内核内存分配那点事……重点在于分析vmalloc的执行 流程 以传统x86架构为例,内核空间内存(3G-4G)主要分为三大部分:DMA映射区,一致 ...

  5. Navicat连接服务器上的Mysql数据库

  6. mysql 约束条件 primary key 主键

    primary key字段的值不为空且唯一 约束:not null unique 存储引擎:innodb 对于innodb来说,一张表内必须有一个主键 单列做主键多列做主键(复合主键) 通常都是id字 ...

  7. JQuery的Ajax跨域请求的解决方式

            今天在项目中须要做远程数据载入并渲染页面,直到开发阶段才意识到ajax跨域请求的问题,隐约记得Jquery有提过一个ajax跨域请求的解决方式,于是即刻翻出Jquery的API出来研究 ...

  8. Spark源码分析之Checkpoint的过程

    概述 checkpoint 的机制保证了需要访问重复数据的应用 Spark 的DAG执行图可能很庞大,task 中计算链可能会很长,这时如果 task 中途运行出错,那么 task 的整个需要重算非常 ...

  9. maven运行junit用例并生成报告

    原文地址https://blog.csdn.net/hdyrz/article/details/78398964 测试类如下: [java] view plain copypackage com.mm ...

  10. Linux系统——FTP

    FTP连接及传输模式1. 控制连接:TCP21,用于发送FTP命令信息2. 数据连接:TCP20,用于上传.下载数据3. 数据连接的建立类型:(1)主动模式:服务器制动发起数据连接首先由客户端向服务端 ...