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. docker镜像下载出现:received unexpected HTTP status: 500 Internal Server Error

    1.镜像下载总是出现报错:received unexpected HTTP status: 500 Internal Server Error 2.尝试多种方法: ①阿里云docke加速器:注册之后, ...

  2. 如何通过 SSH/Telnet 用 root 权限登录群晖

    出于系统安全原因,对 Synology NAS 的 root 访问有限.如果您获取 root 权限,请在命令行界面中用任何属于Local Administrators群组的帐户证书登录 DSM(如Pu ...

  3. 7-8 矩阵A乘以B (15分)

    7-8 矩阵A乘以B (15分)   给定两个矩阵A和B,要求你计算它们的乘积矩阵AB.需要注意的是,只有规模匹配的矩阵才可以相乘.即若A有R​a​​行.C​a​​列,B有R​b​​行.C​b​​列, ...

  4. 精心收集java基础106条

    Java基础 1.一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 一个Java源文件中可以定义多个类,但最多只能定义一个public的类,并且public ...

  5. 关于JavaScript的原型继承与原型链

    在讨论原型继承之前,先回顾一下关于创建自定义类型的方式,这里推荐将构造函数和原型模式组合使用,通过构造函数来定义实例自己的属性,再通过原型来定义公共的方法和属性. 这样一来,每个实例都有自己的实例属性 ...

  6. BZOJ 3438 小M的礼物

    BZOJ 3438 小M的礼物 Description 小M在MC里开辟了两块巨大的耕地A和B(你可以认为容量是无穷),现在,小P有n中作物的种子,每种作物的种子 有1个(就是可以种一棵作物)(用1. ...

  7. Uva 1609 Feel Good

    题面:给出长度为n的数列,然后算出其区间和乘区间最小数所能得到的最大值,并且输出区间 样例输入: 6 3 1 6 4 5 2 样例输出: 60 3 5 原题链接:https://vjudge.net/ ...

  8. .gitignore文件说明-git提交时可忽略的文件

    在我们平时做项目时,总有一些文件不想提交到服务器的版本管理上 这时就要设置相应的忽略规则,来忽略这些文件的提交 规则 作用/mtk 过滤整个文件夹*.zip 过滤所有.zip文件/mtk/do.c 过 ...

  9. Git下载GitHub仓库里的某一个文件夹或某一个文件

    从Github上下载github上的整个项目,可以用下面指令: git clone https://github.com/XXX/xxxxx.git 其中:XXX是用户在Github上的用户名 xxx ...

  10. XSS挑战之旅,学习笔记

    第一关: http://test.ctf8.com/level1.php?name=test 观察到通过get方式传参有会显, 直接打最简单的xss playload: <script>a ...