Object.defineProperty介绍--
let obj = {};
Object.defineProperty(obj,'school',{
configurable : true, // 属性能否被删除
//writable : true, // 属性能否被修改
enumerable : true, // 属性能否枚举
//value : 'zfpx', // 设置属性值 set : function(value){
console.log(value); // obj.school赋值时, 调用set() 方法
},
get : function(){
return 'zfpx'; // 获取 obj.school 的值时,调用 get() 方法
}
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<body>
<div id="app">
<p>{{a.a}}</p>
<div>{{b}}
<div>{{b}}</div>
</div>
</div>
</body>
<!-- mvvm 双向数据绑定
vue 数据劫持+发布订阅模式
不兼容低版本 Object.defineProperty -->
<script> (function(window,document){
function ZF(options = {}){
this.$options = options; // 将所有的属性挂载在 $options 上
let data = this._data = this.$options.data;
this.observe(data);
for(let key in data){ // 把data属性通过Object.defineProperty的方式定义属性
// 数据代理
// this代理了this._data
Object.defineProperty(this,key,{
enumerable : true, // 可枚举
get: function(){
return this._data[key];
},
set: function(newVal){ // 更改值的时候
this._data[key] = newVal;
}
});
}
this.Compile(options.el,this);
}
// 编译
ZF.prototype.Compile = function(el,vm){
vm.$el = document.querySelector(el);
let fragment = document.createDocumentFragment();
while(child = vm.$el.firstChild){ // 将app中的内容 移入内存中
fragment.appendChild(child);
}
// 循环每一层
Array.from(fragment.childNodes).forEach(function(node){ let text = node.textContent;
let reg = /\{\{(.*)\}\}/; if( reg.test(text)){
let arr = RegExp.$1.split('.');
let val = vm;
console.log(node.childNodes)
console.log(arr)
arr.forEach(function(k){
val = val[k];
})
// 替换
node.textContent = text.replace(/\{\{(.*)\}\}/,val)
}
//node.textContent.textContent(12) })
vm.$el.appendChild(fragment);
}
// 观察对象给对象增加ObjectDefineProperty;
ZF.prototype.observe = function(data){
//console.log(data)
return new Observe(data); }
function Observe(data){
for(let key in data){ // 把data属性通过Object.defineProperty的方式定义属性
let val = data[key];
// 递归
if(typeof val === 'object'){
Observe(val);
}
Object.defineProperty(data,key,{
enumerable : true, // 可枚举
get: function(){
return val;
},
// 数据劫持
set: function(newVal){ // 更改值的时候
if(newVal === val){
return;
}
if(typeof newVal === 'object'){
Observe(newVal);
}
val = newVal; //
}
});
}
}
window.ZF = ZF; })(window,document); let zf = new ZF({
el : "#app",
data : {a:{a:'是a'},b:'是b'},
}) </script>
</html>

vue mvvm原理与简单实现 -- 上篇的更多相关文章

  1. vue 实现原理及简单示例实现

    目录 相关html代码,用于被解析绑定数据 observer代码 Dep代码 Watcher 代码 Compile 代码 vue 简要构造函数 创建vue实例 结语 主要理解.实现如下方法: Obse ...

  2. 对Vue中的MVVM原理解析和实现

    对Vue中的MVVM原理解析和实现 首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写 下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章 ...

  3. mvvm实现一个简单的vue

    vue,基于mvvm模式下的一个前端框架 mvvm模式下简单的实现数据代理,数据劫持 1.是用Object.defineProperty 实现数据代理 2.使用发布订阅者模式,配合 Object.de ...

  4. vue运行原理

    Vue工作原理小结 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简 ...

  5. 直播课(1)如何通过数据劫持实现Vue(mvvm)框架

    19.6.28更新: 这篇博客比较完善:将每一部分都分装在单独的js文件中: 剖析Vue原理&实现双向绑定MVVM 半个月前看的直播课,现在才自己敲了一遍,罪过罪过 预览: 思路: 简单实现V ...

  6. vue 编译原理 简介

    来源 tinycompile 关于vue的内部原理其实有很多个重要的部分,变化侦测,模板编译,virtualDOM,整体运行流程等. 之前写过一篇<深入浅出 - vue变化侦测原理> 讲了 ...

  7. 总结Vue第一天:简单介绍、基本常用知识、辅助函数

    总结Vue第一天:简单介绍.基本常用知识.辅助函数 中文官网:https://cn.vuejs.org/v2/guide/syntax.html 遇到不熟悉的可以先看一下官网,然后再看一下一些别人写的 ...

  8. vue 快速入门 系列 —— 侦测数据的变化 - [vue api 原理]

    其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue api 原理] 前面(侦测数据的变化 - [基本实现])我们已经介绍了新增属性无法被侦测到,以及通过 delete 删除数据也不会 ...

  9. HBase笔记:对HBase原理的简单理解

    早些时候学习hadoop的技术,我一直对里面两项技术倍感困惑,一个是zookeeper,一个就是Hbase了.现在有机会专职做大数据相关的项目,终于看到了HBase实战的项目,也因此有机会搞懂Hbas ...

随机推荐

  1. 打印机打印pdf文件特别慢怎么解决

    PDF等文件中都包含了一些或者很多光栅化数据(图片.嵌入的字体等).这些文件在打印时,打印机驱动程序都会在系统中生成大量EMF文件(增强型变换文件),小到1MB,大到500MB,过大的EMF临时文件会 ...

  2. 论文阅读笔记(二十二)【CVPR2017】:See the Forest for the Trees: Joint Spatial and Temporal Recurrent Neural Networks for Video-based Person Re-identification

    Introduction 在视频序列中,有些帧由于被严重遮挡,需要被尽可能的“忽略”掉,因此本文提出了时间注意力模型(temporal attention model,TAM),注重于更有相关性的帧. ...

  3. Tutorial: Publishing additional services for printing

    Complexity:IntermediateData Requirement:Use your own data There may be occasions when you need to pu ...

  4. 快捷使用 Iterm2 连接SSH ( HTTP代理 )

    1,配置iterm2 > Preferences.. > Profiles > 填写:name : 别名 : Command : expect /Users/jerryxu/wwwr ...

  5. markdown转成word或者pdf

    利用typora软件 1.登陆官网下载软件 官网地址:https://typora.io/ 点击download 根据自己的电脑下载64位或者32位 2.安装软件 安装界面如下: 3.转换 3.1首先 ...

  6. Spring Boot源码(二):SPI去除web.xml

    SPI广泛用于dubbo,spring boot,spring cloud alibaba等 关于SPI,可见SPI-Service Provider Interface 继续上篇文章 上面三句代码的 ...

  7. java连接Sqlserver数据库问题总结

    网上说的要在:Sqlserver配置管理器中设置SQL Server网络配置->SQLEXPRESS的协议->TCP/IP的方法试了没啥用 不知道是不是自己测试设置的时候改了啥参数给整好了 ...

  8. Linux connect: Network is unreachable

    在虚拟机中ping,发现网络不通: [root@node01 ~]# ping 114.114.114.114 connect: Network is unreachable 发生此问题时,环境如下: ...

  9. Javascript的重要数据类型-对象

    这次的分享,主要还是想跟大家聊聊Javascript语言中很重要的概念之一,对象.为什么说之一呢?因为Javascript其他重要概念还包括:作用域 作用域链 继承 闭包 函数 继承 数组 ..... ...

  10. Leetcode Week2 Two Sum

    Question Given an array of integers, return indices of the two numbers such that they add up to a sp ...