原文:https://github.com/louzhedong/blog/issues/4

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<form>
<input type="text" v-model="number">
<button type="button" v-click="increment">增加</button>
</form>
<h3 v-bind="number"></h3>
</div>
<script>
function myVue(options) {
this._init(options)
}
myVue.prototype._init = function (options) { // 参数 el: '#app',data: {number: 0},methods: {increment: function () {this.number++}}
this.$options = options
this.$el = document.querySelector(options.el) // 找到指定元素
this.$data = options.data // data中的数据结构,如number:0
this.$methods = options.methods // methods中的数据结构,如increment:function(){this.number++}
this._binding = {}
this._obverse(this.$data)
this._complie(this.$el)
}
myVue.prototype._obverse = function (obj) { // data结构,如number:0
var _this = this
Object.keys(obj).forEach(function (key) { // Object.keys()返回对象的Key
if (obj.hasOwnProperty(key)) { // 对象是否包含指定属性,返回boolean
_this._binding[key] = {
_directives: []
}
console.log(_this._binding[key])
var value = obj[key]
if (typeof value === 'object') { // 如果还是对象继续遍历
_this._obverse(value)
}
var binding = _this._binding[key]
// 定义属性描述 参数一定义属性的对象,参数二定义属性名称,参数三属性描述
Object.defineProperty(_this.$data, key, {
enumerable: true, // 开启才能出现在对象的枚举属性中
configurable: true, // 开启属性描述才能改变,同时属性能删除
get: function () { // 给属性提供getter方法
console.log(`${key}获取${value}`)
return value
},
set: function (newVal) { // 给属性提供setter方法
console.log(`${key}更新${value}`)
if (value !== newVal) {
value = newVal
binding._directives.forEach(function (item) {
item.update()
})
}
}
})
}
})
}
myVue.prototype._complie = function (root) {
var _this = this
var nodes = root.children
for (var i = 0; i < nodes.length; i++) {
var 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)
})()
}
if (node.hasAttribute('v-model') && (node.tagName == 'INPUT' || node.tagName == 'TEXTAREA')) {
node.addEventListener('input', (function (key) {
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
}
})(i))
}
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] // 触发值改变,会调属性get方法
}
window.onload = function () { // 页面初始化创建实例
var app = new myVue({
el: '#app',
data: {
number: 0
},
methods: {
increment: function () {
this.number++
}
}
})
}
</script>
</body>
</html>

vue双向绑定笔记的更多相关文章

  1. vue双向绑定的原理及实现双向绑定MVVM源码分析

    vue双向绑定的原理及实现双向绑定MVVM源码分析 双向数据绑定的原理是:可以将对象的属性绑定到UI,具体的说,我们有一个对象,该对象有一个name属性,当我们给这个对象name属性赋新值的时候,新值 ...

  2. IOS自带输入法中文不触发KEYUP事件导致vue双向绑定错误问题

    先上图: 可以看到输入框中的内容和弹出框的内容不一致, <input class="am-fr labRight" id="txcode" type=&q ...

  3. Vue双向绑定原理,教你一步一步实现双向绑定

    当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...

  4. 梳理vue双向绑定的实现原理

    Vue 采用数据劫持结合发布者-订阅者模式的方式来实现数据的响应式,通过Object.defineProperty来劫持数据的setter,getter,在数据变动时发布消息给订阅者,订阅者收到消息后 ...

  5. vue双向绑定原理分析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/jiangzhenf ...

  6. vue双向绑定原理及实现

    vue双向绑定原理及实现 一.总结 一句话总结:vue中的双向绑定主要是通过发布者-订阅者模式来实现的 发布 订阅 1.单向绑定和双向绑定的区别是什么? model view 更新 单向绑定:mode ...

  7. vue双向绑定原理源码解析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/maxlove123 ...

  8. Vue双向绑定实现原理demo

    一.index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  9. Vue双向绑定原理(源码解析)---getter setter

       Vue双向绑定原理      大部分都知道Vue是采用的是对象的get 和set方法来实现数据的双向绑定的过程,本章将讨论他是怎么利用他实现的. vue双向绑定其实是采用的观察者模式,get和s ...

随机推荐

  1. Windows下Anaconda安装 python + tensorflow CPU版

    下载安装Anaconda 首先下载Anaconda,可以从清华大学的镜像网站进行下载. 安装Anaconda,注意安装时不要将添加环境变量的选项取消掉. 安装完成之后,在安装目录下cmd,输入: co ...

  2. Mysql:如果数据存在则更新,不存在则插入

    mysql语法支持如果数据存在则更新,不存在则插入,首先判断数据存在还是不存在的那个字段要设置成unique索引, 例如表tb_addrbook如下: 索引: 语句1:不存在插入 INSERT INT ...

  3. CDH6安装文档

    1.准备工作 1.1 环境 centos7.jdk8.mysql5.7.python2.7.CDH6 1.2文件下载 1.2.1 cloudmanger地址 https://archive.cloud ...

  4. Q606 根据二叉树创建字符串

    你需要采用前序遍历的方式,将一个二叉树转换成一个由括号和整数组成的字符串. 空节点则用一对空括号 "()" 表示.而且你需要省略所有不影响字符串与原始二叉树之间的一对一映射关系的空 ...

  5. 送给张思漫,李志媛和王颖的C语言经典例题

    1.打印乘法口诀表 #include<stdio.h> int main() { int i, j; ; i <= ; i++){ ; j <= i; j++) { print ...

  6. python - 斐波那契(Fibonacci)数列

    斐波那契数列即数列中每一项等于它前面两项的和,公式如下: f(n) = f(n-1) + f(n-2)    n>2        -----        递推公式 f(n) = 1     ...

  7. C# 特性(Attribute)之Flag特性

    本文参考自C# 位域[flags],纯属读书笔记,加深记忆 [Flags]的微软解释是“指示可以将枚举作为位域(即一组标志)处理.”其实就是在编写枚举类型时,上面附上Flags特性后,用该枚举变量是既 ...

  8. selenium+Python(Js处理日历控件)

    日历控件是web网站上经常会遇到的一个场景,有些输入框是可以直接输入日期的,有些不能,以我们经常抢票的12306网站为例,详细讲解如何解决日历控件为readonly属性的问题. 基本思路:先用js去掉 ...

  9. sql developer链接不上oracle 报 The Network Adapter could not establish the connection

    安装时候报 : Oracle 支持在具有 DHCP 分配的公共 IP 地址的系统上进行安装.但应使用静态 IP 地址来配置系统的主网络接口, 以便 Oracle 软件正常工作.有关在配置有 DHCP ...

  10. 关于Map集合的遍历总结

    Map集合的遍历经常遇到,今天在这里总结一下Map集合遍历的几种方式: public static void main(String[] args){ Map<String,String> ...