原文: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. [Alpha]Scrum Meeting#3

    github 本次会议项目由PM召开,时间为4月3日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写团队贡献分配计划(issue#39) 调整&分配工作 SiM ...

  2. 高阶篇:4.3)FTA故障树分析法-DFMEA的另外一张脸

    本章目的:明确什么是FTA,及与DFMEA的关系. 1.FTA定义 故障树分析(FTA) 其一:故障树分析(Fault Tree Analysis,简称FTA)又称事故树分析,是安全系统工程中最重要的 ...

  3. rsa字符串格式公钥转换python rsa库可识别的公钥形式

    在爬虫分析的时候,经常在网页上看到如下格式的rsa公钥: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC7kw8r6tq43pwApYvkJ5laljaN9BZb21 ...

  4. 剑指offer——面试题22:链表中倒数第k个节点

    注意代码的鲁棒性! 函数: ListNode* TheLastKthNode(ListNode* pHead,int k) { ) return nullptr; ListNode* quickNod ...

  5. iis上部署本地数据库LocalDB的方法

    1. iis应用程序池的标识设置为"ApplicationPoolIdentify"(比较安全) 2. 不要将数据库物理文件保存在网站的物理路径内,因为iis应用程序池的标识为Ap ...

  6. C#嵌入字体

    1:将字体文件(*.ttf)添加到资源文件里,注意资源的名称 2:在Program.cs文件里声明 using System; using System.Collections.Generic; us ...

  7. 分分钟钟学会Python - 数据类型(dict)

    今日内容 字典(dict) 具体内容 1.字典含义 帮助用户去表示一个事物的信息(事物是有多个属性). 基本格式 data = {键:值,键:值,键:值,键:值,键:值,键:值,} # 练习题 use ...

  8. vue 之bug<1> Warn : [vue-router] Duplicate named routes definition:

    原因:定义重复的路由名称. 我有3个不同的(父级)vue文件分别配置了3个相同的(子级)vue文件,配置路由的js文件里子集路由的name重复了. 解决方案: 一天一个小Bug

  9. hadoop踩坑:localhost:50070 无法访问 关闭防火墙

    ubuntu 关闭防火墙:ufw disable hadoop3.0以下版本web访问端口50070:3.0及以上web访问端口9870 参考链接:https://blog.csdn.net/qq_3 ...

  10. Struts中Validate()和validateXxx的使用

    Struts中Validate()和validateXxx的使用 学习struts2之后,你会发现validate在之前是没有的!它是怎么实现的呢? validate和validateXxxx都是拦截 ...