直接进入主题了,想必大家都知道实现vue响应式核心方法就是 Object.defineProperty,那就从它开始说

Object.defineProperty

缺点:

  • 深度监听,需要递归到底,一次性计算量大
  • 无法监听新增、删除属性(需要vue.set 和 vue.delete)
  • 无法原生监听数组,需要特殊处理

实现响应式

function updateView () {
console.log('视图更新')
} // 重新定义数组原型
const oldArrayProperty = Array.prototype
// 创建新对象原型指向 Array.prototype,在扩展新的方法不会影响原型
const arrProto = Object.create(oldArrayProperty);
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(methodName => {
arrProto[methodName] = function () {
updateView()
oldArrayProperty[methodName].call(this, ...arguments)
}
}); // 监听data传入的属性
function defineReactive(target, key, value) {
// 深度监听 多层对象嵌套
observer(value)
// 核心api
Object.defineProperty(target, key, {
get() {
return value
}, set(newVal) {
// 设置新值也要监听 比如{age:27}
observer(newVal)
if (newVal !== value ) {
value = newVal
updateView()
}
}
})
}
// 监听对象属性
function observer(target) {
if (typeof target !== 'object' || target === null) {
// 不是对象或数组
return target
}
// 监听数组 把原数组的隐式原型赋值给我们定义好的数组对象
if (Array.isArray(target)) {
target.__proto__ = arrProto
}
// 重新定义各个属性,加getter、setter属性
for(let key in target) {
defineReactive(target, key, target[key])
}
} const data = {
name: 'zk',
age: 26,
info: {
address: 'city' // 需深度监听
},
nums: [1, 2, 3]
}
observer(data)
// data.info.address = 'beijing' // 需要深度监听
// data.info = {address:'beijing'} // 需要深度监听
// data.x = 666 // 新增属性,监听不到 需要vue.set方法
// delete data.name // 删除属性,监听不到 需要vue.delete方法
data.nums.push(21)

vue2简单的数据双向绑定实现

<div>内容:<span id="content"></span></div>
<input id="iptName" />
const iptName = document.getElementById('iptName')
const content = document.getElementById('content')
let obj = {
name: ''
}
let newObj = JSON.parse(JSON.stringify(obj))
Object.defineProperty(obj, 'name', {
get() {
return newObj.name
}, set(val) {
if (val === newObj.name) return
newObj.name = val
observer()
}
})
function observer () {
iptName.innerText = obj.name
content.innerText = obj.name
}
iptName.oninput = function () {
obj.name = this.value
}

Vue2源码解读 - 响应式原理及简单实现的更多相关文章

  1. vue源码之响应式数据

    分析vue是如何实现数据响应的. 前记 现在回顾一下看数据响应的原因. 之前看了vuex和vue-i18n的源码, 他们都有自己内部的vm, 也就是vue实例. 使用的都是vue的响应式数据特性及$w ...

  2. Spring:源码解读Spring IOC原理

    Spring IOC设计原理解析:本文乃学习整理参考而来 一. 什么是Ioc/DI? 二. Spring IOC体系结构 (1) BeanFactory (2) BeanDefinition 三. I ...

  3. Spring源码解读Spring IOC原理

    一.什么是Ioc/DI? IoC 容器:最主要是完成了完成对象的创建和依赖的管理注入等等. 先从我们自己设计这样一个视角来考虑: 所谓控制反转,就是把原先我们代码里面需要实现的对象创建.依赖的代码,反 ...

  4. 通用后台管理系统源码,响应式布局,Java管理系统源码,零门槛安装部署

    本项目是一个通用响应式管理后台,导入开发环境安装就能直接运行,界面也非诚漂亮,在PC端和移动端也是自适应的.非常适合企业或者个人搭建各种商城后台,博客后台,网站管理后台等. 源码启动后的截图 需要这套 ...

  5. Python Web Flask源码解读(二)——路由原理

    关于我 一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android.Python.Java和Go,这个也是我们团队的主要技术栈. Github:https:/ ...

  6. JGUI源码:响应式布局简单实现(13)

    首先自我检讨下,一直没有认真研究过响应式布局,有个大致概念响应式就是屏幕缩小了就自动换行或者隐藏显示,就先按自己的理解来闭门造车思考实现过程吧. 1.首先把显示区域分成12等分,bootstrap是这 ...

  7. java 企业门户网站 源码 自适应响应式 freemarker 静态引擎 html5 SSM

    官网 http://www.fhadmin.org/ 系统介绍: 1.网站后台采用主流的 SSM 框架 jsp JSTL,网站后台采用freemaker静态化模版引擎生成html 2.因为是生成的ht ...

  8. vue2.0 之 深入响应式原理

    实例demo<div id="app"> <span>{{a}}</span> <input type="text" ...

  9. 2,MapReduce原理及源码解读

    MapReduce原理及源码解读 目录 MapReduce原理及源码解读 一.分片 灵魂拷问:为什么要分片? 1.1 对谁分片 1.2 长度是否为0 1.3 是否可以分片 1.4 分片的大小 1.5 ...

随机推荐

  1. Python - 面向对象编程 - 新式类和旧式类

    object object 是 Python 为所有对象提供的父类,默认提供一些内置的属性.方法:可以使用 dir 方法查看 新式类 以 object 为父类的类,推荐使用 在 Python 3.x ...

  2. Sentry Web 性能监控 - Web Vitals

    系列 1 分钟快速使用 Docker 上手最新版 Sentry-CLI - 创建版本 快速使用 Docker 上手 Sentry-CLI - 30 秒上手 Source Maps Sentry For ...

  3. shell循环语句while

    格式1: while 条件 do 执行命令 done 格式2: while 条件;do 命令 done 例子: while [ 1 -eq 1 ];do echo "这一步需要先修改/dat ...

  4. vue的常见理论问题

    1.什么是 mvvm? mvvm 和 mvc 区别? MVVM 是 Model-View-ViewModel 的缩写.mvvm 是一种设计思想.Model 层代表数据模型,View 代表 UI 组件. ...

  5. Appium问题解决方案(4)- Error while obtaining UI hierarchy XML file: com.android.ddmlib.SyncException

    背景 操作步骤 运行 uiautomatorviewer.bat 点击左上角的 Device ScreensShot 报错 截图 解决方法 网上还是有很多方法的,可能造成的原因不同,我是第六种方法解决 ...

  6. 获取office版本

    /// <summary>         /// office版本         /// </summary>         public enum OfficeVers ...

  7. vue开发 回到顶部操作

    第一种:使用vue-router history 模式下,用scrollBehavior 方法实现. 1 export default new Router({ 2 mode: 'history', ...

  8. C++ 飞行游戏

    源代码: #include<bits/stdc++.h> #include<windows.h> #include<conio.h> using namespace ...

  9. swiper-wrapper轮滑组件(多组轮滑界面)间隔无效问题

    在多组此种轮滑效果出现时,你需要加两个属性值,即 new Swiper('.swiper-container', { slidesPerView: 3, slidesPerColumn: 2, spa ...

  10. Java之SpringBoot自定义配置与整合Druid

    Java之SpringBoot自定义配置与整合Druid SpringBoot配置文件 优先级 前面SpringBoot基础有提到,关于SpringBoot配置文件可以是properties或者是ya ...