从0开始探究vue-双向绑定原理
理解
vue是一个非常优秀的框架,其优秀的双向绑定原理,mvvm模型,组件,路由解析器等,非常的灵活方便,也使开发者能够着重于数据处理,让开发者更清晰的设计自己的业务。
双向绑定,就是数据变化的时候,自动触发视图的变化。
实践
我们都理解,vue2.0中,双向绑定的核心为Object.defineProperty(obj, prop, descriptor),方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象
参数obj为要在其上定义属性的对象。
参数prop为要定义或修改的属性的名称。
参数descriptor为将被定义或修改的属性描述符。
返回被传递给函数的对象。
尝试Object.defineProperty拦截用户对变量的设置
我们可以新建一个项目,用来模拟及学习vue双向绑定的相关内容
+ vue相关
+ |- 双向绑定原理
+ |- js
+ |- myVue.js
+ |- index.html
修改index.html中的内容,引入自己创建的myVue.js。
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Document</title>
+ </head>
+ <body>
+
+ <script src="./js/myVue.js"></script>
+ </body>
+ </html>
编辑myVue.js的内容,来尝试一下Object.defineProperty(obj, prop, descriptor)这个API
+ var data = {
+ a: 1
+ }
+ Object.defineProperty(data, 'a', {// 为data中的a进行拦截,读取a的时候返回自己新建的_a的值,设置a的值的时候,设置到_a上。这样,开发者对a的操作,都会映射到我们新建的虚拟的_a变量上
+ configurable: true, // 是否允许删除属性,默认true
+ enumerable: true, // 是否允许遍历,默认true
+ get: function () {
+ console.log('我被读取了,返回了_a的值', this._a)
+ return this._a
+ },
+ set(value) {
+ // this.a = value;
+ this._a = value;
+ console.log('我被设置了,被设置的值为', this._a, '并放进了a的对象中')
+ }
+ })
在浏览器中,打开页面,并查看控制台,对data.a进行操作
data.a myVue.js:8
我被读取了,返回了_a的值 undefined
undefined
——————————————————————————————————————————————————————————————————————————————
data.a = 10 myVue.js:14
我被设置了,被设置的值为 10 并放进了a的对象中
10
——————————————————————————————————————————————————————————————————————————————
data.a myVue.js:8
我被读取了,返回了_a的值 10
10
可以看到,我们对data.a进行的操作,实际改变的变量是我们已经拦截的_a变量。
目前出现的问题是,第一次读取的时候,这个值没有被设置上,在下面来模拟解决方案
私有变量
声明概念_开头的变量一版为私有变量,外部无法访问,但是我们现在在控制台中输入并修改私有变量data._a
data._a
10
——————————————————————————————————————————————————————————————————————————————
data._a = 20
20
——————————————————————————————————————————————————————————————————————————————
data._a
20
——————————————————————————————————————————————————————————————————————————————
data.a myVue.js:8
我被读取了,返回了_a的值 20
20
却可以拿到私有变量中的_a的值,也可以进行无拦截的修改,这显然是我们所不希望的
所以我们可以为Object.defineProperty(obj, prop, descriptor)来进行封装一次,把我们理解的_a变成一个私有变量
修改myVue.js的内容为如下内容,
var data = {
a: 1
}
myDefineProperty(data, 'a')
function myDefineProperty(obj,key){//对Object.defineProperty进行一次拦截,使外界无法访问私有变量value
var value = obj[key];
Object.defineProperty(obj,key,{// 为data增加
configurable: true, // 是否允许删除属性,默认true
enumerable: true, // 是否允许遍历,默认true
get: function () {
console.log('我被读取了,返回了value的值', value)
return value
},
set(newValue) {
value = newValue;
console.log('我被设置了,被设置的值为', newValue, '并放进了value的对象中')
}
})
}
然后再查看控制台
data._a
undefined
——————————————————————————————————————————————————————————————————————————————
data.value
undefined
——————————————————————————————————————————————————————————————————————————————
data.a myVue.js:12
我被读取了,返回了value的值 1
1
——————————————————————————————————————————————————————————————————————————————
开发者就无法自行操作我们设计的私有变量value的内容了
自此,我们解决了,对一个对象属性的拦截,并且阻止了用户对我们设计的私有变量进行操作
双向绑定实践
我们知道了拦截属性之后,那么就进一步来实现,一个简单的双向绑定
我们修改一下index.html中的内容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
+ <input type="text" @change='changeIpt'>
+ <p id='changeValue'></p>
</head>
<body>
<script src="./js/myVue.js"></script>
</body>
</html>
并在myVue.js中,在set中添加双向绑定的操作
var data = {
a: 1
}
myDefineProperty(data, 'a')
+ var ipt = document.getElementById('ipt');
+ ipt.oninput = function(e){
+ data.a = e.target.value
+ }
function myDefineProperty(obj,key){
var value = obj[key];
Object.defineProperty(obj,key,{// 为data增加
configurable: true, // 是否允许删除属性,默认true
enumerable: true, // 是否允许遍历,默认true
get: function () {
console.log('我被读取了,返回了value的值', value)
return value
},
set(newValue) {
value = newValue;
+ document.getElementById('iptValue').innerText = newValue;
+ ipt.value = newValue;
console.log('我被设置了,被设置的值为', newValue, '并放进了value的对象中')
}
})
}
然后我们在input框里输入内容,便表现出了双向绑定的能力。
记得打开控制台哦!~下方为录制的屏幕,可能无法正常显示,可以点击上方demo来查看
觉得好的话,可以给我的 github点个star哦
从0开始探究vue-双向绑定原理的更多相关文章
- vue双向绑定原理分析
当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/jiangzhenf ...
- vue双向绑定原理及实现
vue双向绑定原理及实现 一.总结 一句话总结:vue中的双向绑定主要是通过发布者-订阅者模式来实现的 发布 订阅 1.单向绑定和双向绑定的区别是什么? model view 更新 单向绑定:mode ...
- Vue双向绑定原理(源码解析)---getter setter
Vue双向绑定原理 大部分都知道Vue是采用的是对象的get 和set方法来实现数据的双向绑定的过程,本章将讨论他是怎么利用他实现的. vue双向绑定其实是采用的观察者模式,get和s ...
- [Vue源码]一起来学Vue双向绑定原理-数据劫持和发布订阅
有一段时间没有更新技术博文了,因为这段时间埋下头来看Vue源码了.本文我们一起通过学习双向绑定原理来分析Vue源码.预计接下来会围绕Vue源码来整理一些文章,如下. 一起来学Vue双向绑定原理-数据劫 ...
- Vue双向绑定原理,教你一步一步实现双向绑定
当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...
- vue 学习二 深入vue双向绑定原理
vue双向绑定原理 请示总体来讲 就是为data的中的每个属性字段添加一个getter/seter属性 以此来追踪数据的变化,而执行这部操作,依赖的就是js的Object.defineProperty ...
- vue双向绑定原理
要了解vue的双向绑定原理,首先得了解Object.defineProperty()方法,因为访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过 Object.definePrope ...
- Vue双向绑定原理及其实现
在之前面试的时候被面试官问到是否了解Vue双向绑定的原理,其实自己之前看过双向绑定的原理,但也就是粗略的了解,但是没有深入.面试官当时让我手写一个原理,但是就蒙了
- 通俗易懂了解Vue双向绑定原理及实现
看到一篇文章,觉得写得挺好的,拿过来给大家分享一下,刚好解答了一些困扰我的一些疑惑!!! 1. 前言 每当被问到Vue数据双向绑定原理的时候,大家可能都会脱口而出:Vue内部通过Object.defi ...
随机推荐
- 操作系统实验——PV操作实现生产者消费者模型
操作系统PV操作之--生产者消费者模型 个人博客主页 参考资料: Java实现PV操作 | 生产者与消费者 浙大公开课 在操作系统的多进程.多线程操作中经常会有因为同步.互斥等等问题引发出的一系列问题 ...
- python执行脚本报错: Non-ASCII character '\xe4' in file yang.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
这是因为我们在写python程序的时候,无论在注释里面出现中文,还是在代码里面出现中文,也就是说只要这个python程序里面有中文,我们就不能直接用python2来进行执行,如果安装是python3可 ...
- band-pass filtering
from scipy import signal # 带通滤波器 # 信号,频率下限,频率上限, 采样率 def bandPass(signals, fre_low, fre_high, fs): b ...
- Angular 从入坑到挖坑 - Router 路由使用入门指北
一.Overview Angular 入坑记录的笔记第五篇,因为一直在加班的缘故拖了有一个多月,主要是介绍在 Angular 中如何配置路由,完成重定向以及参数传递.至于路由守卫.路由懒加载等&quo ...
- dumpsys-package
dumpsys-package ams和pms是android系统最重要的系统服务,本文解析dumpsys package命令,看哪些PMS相关的系统信息,数据结构是运行时可以查看的. 命令提示 co ...
- Linux Charger IC 驱动移植总结
Linux Charger IC 驱动移植总结 文章目录 Linux Charger IC 驱动移植总结 1 设备树的基本知识 设备树的概念 设备树的基本结构 compatible属性 举个栗子 2 ...
- 计算机组成及系统结构-第十章 输入输出(I/O)系统
输入输出(I/O)系统 一.概述 1.输入输出设备的编址 2.设备控制器(I/O接口)的基本功能 3.I/O设备数据传送控制方式 二.程序中断输入输出方式 1.中断的定义 2.中断的作用 3.中断的产 ...
- BufferedInputStream:字节缓冲输入流
package com.itheima.demo01.BufferedStream; import java.io.BufferedInputStream; import java.io.FileIn ...
- Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像
前文传送门: 「Python 图像处理 OpenCV (1):入门」 普通操作 1. 读取像素 读取像素可以通过行坐标和列坐标来进行访问,灰度图像直接返回灰度值,彩色图像则返回B.G.R三个分量. 需 ...
- 【雕爷学编程】Arduino动手做(57)---四档矩形波模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...