原文: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. K2路由器刷机笔记

    临近双11,K2路由器广告加的越来越放肆,实在太难忍受就刷了个固件.这里把路由器刷机的一般流程记录一下. 一.开启telnet 刷固件,首先要取得路由器系统的控制权,这样我们才能自由的进行操作. 方法 ...

  2. TX2 内核编译

    准备工作 版本:jetpack3.1,R28.1,TX2 虚拟机:ubuntu14.04 参考文档.编译工具链.源码下载 编译 主要步骤记载如下: export CROSS_COMPILE=<c ...

  3. 分享自建的 Jrebel License Server 激活 Jrebel

    使用在线验证服务器激活 Jrebel 与 Idea 说明 代码来自于开源项目: gsls200808 / JrebelLicenseServerforJava 自建的服务地址 http://jrebe ...

  4. angular5新增全局的模块

    比如新增一个全局的swiper,需要在webpack中配置: 之后在代码中就可以用了

  5. 显示point data的时均值注意事项

    正确的导入顺序应该是: 先导入cell data,再做时均处理,最后再转换成point data.如果先转换成point data再做时均处理,速度会非常慢.

  6. Codeforces - tag::dp 大合集 [占坑 6 / inf]

    Gym - 100753J 某国家仅有金币和银币两种货币,起汇率为g,纪念品市场有n个商人和商品,商人结帐只用银币,并且把一堆银币装在袋子里,分为三种类型,分别按向下/向上/四舍五入取整(其中向上的优 ...

  7. R 安装包遇到问题(一) loadNamespace()里算'rJava'时.onLoad失败了 rJava 包的安装与载入

    > library(xlsx) Error: package or namespace load failed for ‘xlsx’: loadNamespace()里算'rJava'时.onL ...

  8. WinScp结合Putty在Windows与UNIX之间进行文件传输

    1. 关于传输协议: SSH Secure Shell安全外壳协议 SFTP Secure File Transfer Protocal安全文件传送协议 2. WinScp与Putty的作用: Put ...

  9. Java框架-mybatis01查询单个数据

    1.什么是mybatis? mybatis是一个基于Java的持久层框架. 2.持久化:数据从瞬时状态变为持久状态. 3.持久层:完成持久化工作的代码块.---dao 4.Mybatis是帮助程序员将 ...

  10. cv2.FileNode has no keys

    把 python-opencv  版本由3.4.1 换成 3.4.4之后,问题解决