vue mvvm原理与简单实现 -- 上篇
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原理与简单实现 -- 上篇的更多相关文章
- vue 实现原理及简单示例实现
目录 相关html代码,用于被解析绑定数据 observer代码 Dep代码 Watcher 代码 Compile 代码 vue 简要构造函数 创建vue实例 结语 主要理解.实现如下方法: Obse ...
- 对Vue中的MVVM原理解析和实现
对Vue中的MVVM原理解析和实现 首先你对Vue需要有一定的了解,知道MVVM.这样才能更有助于你顺利的完成下面原理的阅读学习和编写 下面由我阿巴阿巴的详细走一遍Vue中MVVM原理的实现,这篇文章 ...
- mvvm实现一个简单的vue
vue,基于mvvm模式下的一个前端框架 mvvm模式下简单的实现数据代理,数据劫持 1.是用Object.defineProperty 实现数据代理 2.使用发布订阅者模式,配合 Object.de ...
- vue运行原理
Vue工作原理小结 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简 ...
- 直播课(1)如何通过数据劫持实现Vue(mvvm)框架
19.6.28更新: 这篇博客比较完善:将每一部分都分装在单独的js文件中: 剖析Vue原理&实现双向绑定MVVM 半个月前看的直播课,现在才自己敲了一遍,罪过罪过 预览: 思路: 简单实现V ...
- vue 编译原理 简介
来源 tinycompile 关于vue的内部原理其实有很多个重要的部分,变化侦测,模板编译,virtualDOM,整体运行流程等. 之前写过一篇<深入浅出 - vue变化侦测原理> 讲了 ...
- 总结Vue第一天:简单介绍、基本常用知识、辅助函数
总结Vue第一天:简单介绍.基本常用知识.辅助函数 中文官网:https://cn.vuejs.org/v2/guide/syntax.html 遇到不熟悉的可以先看一下官网,然后再看一下一些别人写的 ...
- vue 快速入门 系列 —— 侦测数据的变化 - [vue api 原理]
其他章节请看: vue 快速入门 系列 侦测数据的变化 - [vue api 原理] 前面(侦测数据的变化 - [基本实现])我们已经介绍了新增属性无法被侦测到,以及通过 delete 删除数据也不会 ...
- HBase笔记:对HBase原理的简单理解
早些时候学习hadoop的技术,我一直对里面两项技术倍感困惑,一个是zookeeper,一个就是Hbase了.现在有机会专职做大数据相关的项目,终于看到了HBase实战的项目,也因此有机会搞懂Hbas ...
随机推荐
- leetcode再次总结
注释 testcases (1)简单一想O(n)算法,有可能通过二分查找变形优化成log(n) (2)双指针:一快一慢 一静一动(数组中最小的长度满足条件,常常用于,确定了一个范围,然后一个指针静止, ...
- gogs搭建git服务教程
使用gogs搭建自己的git服务!!! 一.GIT服务器搭建方式 上一节课我们讲过GIT是一个分布式版本管理系统,既然是分布那么必定会涉及远程通信,那么GIT是采用什么协议进行远程通信的呢? git支 ...
- 关于iScroll在安卓移动端/chrome模拟移动端上下滑动卡顿问题处理!!!!真实可靠!!!已解决!!!
滑动卡顿效果 安卓手机打开微信浏览网页,Chrome模拟手机浏览网页,都出现的问题滑动卡顿! 修改代码点: 1. <style type="text/css"> ...
- .net mvc中epplus导出excel
帮助类 using OfficeOpenXml; using OfficeOpenXml.Style; using System; using System.Collections.Generic; ...
- stringstream使用小结
1.头文件:#include<sstream> 2.stringstream是C++提供的串流(stream)物件 3.clear()重置流的标志状态:str()清空流的内存缓冲,重复使用 ...
- 关于MySQL数据库中null的那些事
在mysql数据库中,null是一个经常出现的情况,关于mysql中的null,有哪些注意事项呢?下面简单总结归纳下,后续会不断补充. 1. is null 首先判断数据库中某一列的值是否为null, ...
- PAT (Basic Level) Practice (中文)1046 划拳 (15 分)
划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳的方法为:每人口中喊出一个数字,同时用手比划出一个数字.如果谁比划出的数字正好等于两人喊出的数字之和,谁就赢了,输家罚一杯酒.两人同赢或两人同输 ...
- easyUI footer 的格式渲染
网上好多的例子,但是自己使用的情况下还是出现bug.比如以下代码: var myview = $.extend({}, $.fn.datagrid.defaults.view, { renderFoo ...
- phpstorm安装bootstrap插件
一个插件可以很好的让我们工作节约时间 Bootstrap,来自 Twitter,是目前最受欢迎的前端框架.Bootstrap 是基于 HTML.CSS.JAVASCRIPT 的,它简洁灵活,使得 We ...
- 【Unity|C#】基础篇(17)——字符串处理(String/StringBuilder)
[学习资料] <C#图解教程>(第25章):https://www.cnblogs.com/moonache/p/7687551.html 电子书下载:https://pan.baidu. ...