原文: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. 2016级算法第二次上机-E.AlvinZH的儿时梦想——运动员篇

    862-AlvinZH的儿时梦想--运动员篇 思路 难题. 应该想到,不管给出的数据如何,每一个淘汰的人不会对最终答案产生任何影响,所以每次淘汰就把人除掉就可以了,最后剩下的两个人计算它们从开始到相遇 ...

  2. gitlab容器--带https配置

    #2.gitlab 重要目录 /home/maks/gitlab/config /etc/gitlab /home/maks/gitlab/logs /var/log/gitlab /home/mak ...

  3. css ie浏览器兼容问题

    第一,IE6,不支持小于12px的盒子,任何小于12px的盒子,在IE6中看都大 解决办法很简单,就是将盒子的字号,设置小(小于盒子的高),比如0px. 1 height: 4px; 2 _font- ...

  4. 06. 用css实现三角形

    用css实现三角形   <!DOCTYPE html> <html lang="en"> <head> <meta charset=&qu ...

  5. ACM-素数专题(持续更新)

    埃拉托斯特尼筛法,或者叫埃氏筛法(听上去似乎很高大上的样子) #include<bits/stdc++.h> using namespace std; typedef long long ...

  6. 获取select标签选中的值

    js获取select标签选中的值 var obj = document.getElementById(”testSelect”); var index = obj.selectedIndex; var ...

  7. ngx_echo_module

    https://github.com/openresty/echo-nginx-module echo $echo_request_body

  8. lua-nginx-module模块常用命令

    ngx.location.capture 用法: local res = ngx.location.capture(uri, options) 发起一个同步非阻塞的nginx子请求,uri是inter ...

  9. activeMQ入门+spring boot整合activeMQ

    最近想要学习MOM(消息中间件:Message Oriented Middleware),就从比较基础的activeMQ学起,rabbitMQ.zeroMQ.rocketMQ.Kafka等后续再去学习 ...

  10. 【云计算】pig基础、运行、编写

    会用和用得好是两个概念. 一.pig基础概念 二.pig运行方式 Pig 有两种运行模式: Local 模式和 MapReduce 模式. 本地模式:$pig-x local test.pig Map ...