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>

原文地址:https://www.cnblogs.com/cl94/p/12235968.html

时间: 2024-11-13 20:05:26

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

Vue数据绑定原理及简单实现

本篇文章中的代码只是部分片段,完整代码存放于github上https://github.com/Q-Zhan/simple-vue. 进入正文~实现数据绑定主要是要实现两个方面的功能:数据变化导致视图变化,视图变化导致数据变化.后者比较容易实现,就是监听视图的事件,然后在回调函数中改变数据.所以重点是数据变化时如何改变视图. 这里的思路是通过object.defineProperty()来对数据的属性设置一个set函数,设置后当数据改变时set函数就会被调用,我们就可以里面进行视图更新操作. 具

理解vue实现原理,实现一个简单的Vue框架

参考: 剖析Vue实现原理 - 如何实现双向绑定mvvm Vue.js源码(1):Hello World的背后 Vue.js官方工程 本文所有代码可以在git上找到. 其实对JS我研究不是太深,用过很多次,但只是实现功能就算了.最近JS实在是太火,从前端到后端,应用越来越广泛,各种框架层出不穷,忍不住也想赶一下潮流. Vue是近年出的一个前端构建数据驱动的web界面的库,主要的特色是响应式的数据绑定,区别于以往的命令式用法.也就是在var a=1;的过程中,拦截'='的过程,从而实现更新数据,w

好程序员web前端分享MVVM框架Vue实现原理

好程序员web前端分享MVVM框架Vue实现原理,Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的.相比于Angular.js和react.js更加简洁.更易于理解的API,使得我们能够快速地上手并使用Vue.js. ? 1.什么是MVVM呢? MVVM的简写是Model-View-ViewModel. 在过去的10年里面,我们已经把很多传统的服务端代码放到了浏览器中,这样就产生了成千上万行的javascript代码,它们连接了HTML 和CSS文

poj 2356 Find a multiple 鸽巢原理的简单应用

题目要求任选几个自然数,使得他们的和是n的倍数. 由鸽巢原理如果我们只选连续的数,一定能得到解. 首先预处理前缀和模n下的sum,如果发现sum[i]==sum[j] 那么(sum[j]-sum[i])%n一定为0,直接输出i+1~j就够了. 为什么一定会有解,因为sum从1~n有n个数,而模n下的数只有0~n-1,把n个数放入0~n-1个数里,怎么也会有重复,所以这种构造方法一定没问题. 其实可以O(n)实现,嫌麻烦,就二重循环无脑了. #include <iostream> #includ

搜索引擎原理之链接原理的简单分析

在google诞生以前,传统搜索引擎主要依靠页面内容中的关键词匹配搜索词进行排名.这种排名方式的短处现在看来显而易见,那就是很容易被刻意操纵.黑帽SEO在页面上推挤关键词,或加入与主题无关的热门关键词,都能提高排名,使搜索引擎排名结果质量大为下降.现在的搜索引擎都使用链接分析技术减少垃圾,提高用户体验.下面泡馆史明星就来简单的介绍链接在搜索引擎排名中的应用原理. 在排名中计入链接因素,不仅有助于减少垃圾,提高结果相关性,也使传统关键词匹配无法排名的文件能够被处理.比如图片.视频无法进行关键词匹配

编译原理(简单自动词法分析器LEX)

编译原理(简单自动词法分析器LEX)源程序下载地址:  http://files.cnblogs.com/files/hujunzheng/%E6%B1%87%E7%BC%96%E5%8E%9F%E7%90%86%E7%AE%80%E5%8D%95LEX%EF%BC%88%E8%AF%8D%E6%B3%95%E8%87%AA%E5%8A%A8%E5%88%86%E6%9E%90%E5%99%A8%EF%BC%89.zip

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

早些时候学习hadoop的技术,我一直对里面两项技术倍感困惑,一个是zookeeper,一个就是Hbase了.现在有机会专职做大数据相关的项目,终于看到了HBase实战的项目,也因此有机会搞懂Hbase原理. 首先来点实在的东西,假如我们已经在服务器上部署好了Hbase应用,作为客户端或者说的具体点,本地开发环境如何编写程序和服务端的Hbase进行交互了? 下面我将展示这些,首先看工程的结构图,如下图所示: 接下来我们将hbase应用下lib文件夹里所有jar包都导入到工程lib目录下,还要把c

Windows-消息映射机制原理和简单的绘图技术

Windows-消息映射机制原理和简单的绘图技术 1.MFC消息映射机制 众所周知,Windows程序是基于消息编程的,但是在MFC中已经为我们封装好了这个框架的消息机制,我们需要了解它的实现原理,才能深入的学习和精通Visual C++. **(1).消息映射机制的原理: MFC消息映射机制的具体实现方法是,在每个能接收和处理消息的类中,定义一个消息和消息函数静态对照表,即消息映射表.在消息映射表中,消息与对应的消息处理函数指针是成对出现的.某个类能处理的所有消息及其对应的消息处理函数的地址都

Lvs原理及简单实现

Lvs原理及简单实现 大纲: 一.集群概述 二.什么是Lvs?(what) 三.为什么要用Lvs?(why) 四.什么时候需要用Lvs?(when) 五.什么地方需要用Lvs?(where) 六.什么人来部署Lvs?(who) 七.Lvs支持的三种模式与十种算法(Scheduler) 八.如何部署Lvs之NAT模式?(How) 九.如何部署Lvs之DR模式? 一.集群简介: 计算机集群(Cluster)技术可以通过网络连接把一组互相独立工作的计算机高度紧密的连接起来,从而高效可靠的共同完成协同任