首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >十三、MVVM模式

十三、MVVM模式

作者头像
Qwe7
发布2022-06-11 09:34:20
发布2022-06-11 09:34:20
5540
举报
文章被收录于专栏:网络收集网络收集

十三、MVVM模式

MVVM是Model-View-ViewModel的缩写

Model:代表数据模型也可以在model中定义数据修改和操作的业务逻辑,也可以称为数据层,因为它仅仅只关心数据,不关心任何行为

View:用户操作界面,当ViewModel对Mdodel进行更新的时候,会通过数据绑定更新到View

ViewModel:业务逻辑层,View需要什么数据,ViewModel要提供这个数据;View有某些操作ViewModel就要响应这些操作,所以可以说他是Model for View

mvvm即Model-View-ViewModel,mvvm的设计原理是基于mvc的,所以说mvvm不算是一种创新,充其量是一种改造,这其中的ViewModel便是一个小小的创新

1、Vue响应式数据原理解析

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script>
    
    /*
    
        如何去实现数据与视图绑定
        1.需要知道哪个数据改变了。一般我们可以使用数据访问对象的方法,在vue中我们使用的是es5的对象访问属性get/set
        2.需要知道修改的这个数据跟哪个视图有关联,观察者模式
        3.修改视图
    */

    // var test = {
    //     _a: undefined,
    //     get a() {
    //         return this._a
    //     },
    //     set a(newVal) {
    //         this._a = newVal
    //     }
    // }

    // console.log(test.a); // undefined

    // test.a = 'abc';

    // console.log(test.a); // abc

    // console.log(test); // {_a: abc}
    // // 如果不想打印出_a
    // var test2 = (function () { 
    //     var _a = undefined

    //     var test = {
    //         get a () {
    //             return _a;
    //         },
    //         set a (newVal) {
    //             _a = newVal;
    //         }
    //     }

    //     return test
    // })
    // console.log(test2); // {a: undefined}

    // var test3 = {_a: 111};

    // Object.defineProperty(test3, 'a', {
    //     get: function () { 
    //         return this._a;
    //     },
    //     set: function (newVal) { 
    //         this._a = newVal
    //     }
    // })

    // console.log(test3.a); // 111
    // test3.a = 'abc'
    // console.log(test3.a); // abc

    // ----------------

    // var data = {
    //     a: 1
    // };

    // var dep = []; // 依赖收集, 消息中心
    // var target = null; // 订阅者或者叫观察者

    // Object.defineProperty(data, 'a', {
    //     get: function () { 
    //         dep.push(target)
    //     },
    //     set: function (newVal) {  
    //         for(var i = 0; i < dep.length; i++) {
    //             dep[i]()
    //         }
    //     }
    // })

    // function watch(exp, fn) { 
    //     target = fn;
    //     data[exp] // 调用 data[exp].get()
    // }

    // watch('a', function () {  
    //     console.log('我是第一个监听a改变的函数');
    // })
    // watch('a', function () {  
    //     console.log('我是第二个监听a改变的函数');
    // })

    // data.a = 2

    /*
    上面代码存在的几个问题:
    1.我们现在访问不到a, 并且a的值需要另一个变量区暂存。
    2.目前只做了一个数据的收集工作
    3.如果再次访问属性的时候,就会重复收集依赖
    */
    
    var data = {
        a: 1,
        b: 2
    };

    for(var key in data) {
        (function (key) { 
            var dep = [];
            var value = data[key];
            Object.defineProperty(data, key, {
                get: function () { 
                    for(var i = 0; i < dep.length; i++) {
                        if (dep[i] === target) {
                            return value
                        }
                    }
                    dep.push(target)
                    return value
                },
                set: function (newVal) {  
                    if (newVal !== value) {
                        value = newVal;
                        for (var i = 0; i < dep.length; i++) {
                            dep[i]()
                        }
                    }
                }
            })
        })(key)
    }

    // var dep = []; // 依赖收集, 消息中心
    var target = null; // 订阅者或者叫观察者

    // Object.defineProperty(data, 'a', {
    //     get: function () { 
    //         dep.push(target)
    //     },
    //     set: function (newVal) {  
    //         for(var i = 0; i < dep.length; i++) {
    //             dep[i]()
    //         }
    //     }
    // })

    function render() { 
        document.write('<div>文案test: <p>a的值: ' + data.a + ', b的值:' + data.b + '</p></div>')
    }

    function watch(exp, fn) { 
        target = fn;
        if (typeof exp === 'function') {
            exp();
            return;
        }
        data[exp] // 调用 data[exp].get()
    }

    // watch('a', function () {  
    //     console.log('我是第一个监听a改变的函数');
    // })
    // watch('a', function () {  
    //     console.log('我是第二个监听a改变的函数');
    // })
    // watch('b', function () {  
    //     console.log('我是第一个监听b改变的函数');
    // })
    watch(render, render)

    data.a = 2
    data.b = 3
    </script>
</head>
<body>
    
</body>
</html>

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档