原文: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. 如何在NSDocumentDirectory内新建一个文件夹

    iOS下载文件一般保存到NSDocumentDirectory内,但是为了更好整理文件内容,那就要自定义的生成一些文件夹,和做一些删除文件夹的操作. - (NSString *)pathToPatie ...

  2. css ie6双倍margin现象

    IE6双倍margin bug 当出现连续浮动的元素,携带和浮动方向相同的margin时,队首的元素,会双倍marign. 解决方案: 1)使浮动的方向和margin的方向,相反. 所以,你就会发现, ...

  3. POJ 2253-Frogger(最小生成树的最大权)

    原题链接:点击此处 题意: 一只叫Freddy的青蛙蹲坐在湖中的一块石头上.突然他发现一只叫Fiona的青蛙在湖中的另一块石头上.Freddy想要跟Fiona约会,但由于湖水太脏,他不想游泳过去而是跳 ...

  4. python全栈开发学习_day1_计算机五大组成部分及操作系统

    一.计算机五大组成部分: 1)五大组成: 1.控制器(指挥系统,用于控制其他计算机硬件的工作) 2.运算器(用于数学运算及逻辑运算) 3.存储器(寄存器,高速缓存,内存,磁盘(机械,固态),磁带) 4 ...

  5. 洛谷 P4307 [JSOI2009]球队收益 / 球队预算(最小费用最大流)

    题面 luogu 题解 最小费用最大流 先假设剩下\(m\)场比赛,双方全输. 考虑\(i\)赢一局的贡献 \(C_i*(a_i+1)^2+D_i*(b_i-1)^2-C_i*a_i^2-D_i*b_ ...

  6. sql count中加条件

    一般的,我们会在where, 或者 having中加条件,count中只是某个字段 今天看到另外一种写法,不知道性能怎么样 select count( case when xxx>10 and ...

  7. git特殊用法

    git stash的使用 1.当前分支写了一半的代码,需要切到其他分支修复bug或者完成优先级较高的任务时 git stash 暂存分支进度 git stash list 查看草稿区 git stas ...

  8. 小程序点击清除input内的内容不生效

    如下图,点击右侧的按钮清除input的内容,当获取焦点时点击按钮是会穿透的清除不了input,使用cover-image和cover-view页面不起作用 解决办法:input在左侧,按钮在右侧使他们 ...

  9. 在win7系统设置SQL Server2014 express为远程数据

    如何设置远程访问到SQLserver服务器(局域网内的设置) 1.首先,使用Windows+R键 输入services.msc 打开本地服务. *说明:①MSSQLSERVER是正式使用的SQL创建实 ...

  10. Python爬虫:常用的浏览器请求头User-Agent(转)

    原文地址:https://blog.csdn.net/mouday/article/details/80182397 user_agent = [ "Mozilla/5.0 (Macinto ...