zoukankan      html  css  js  c++  java
  • 撸一个简单的MVVM例子

    我个人以为mvvm框架里面最重要的一点就是VM这部分,它要与Model层建立联系,将Model层转换成可以被View层识别的数据结构;其次也要同View建立联系,将数据及时更新到View层上,并且响应View对数据的更改,同步到Model层。
    MVVM的具体例子,可以看一下阮一峰老师的这篇博客
    我们提取其中比较关键的点:

    1. Model层存储数据
    2. 需要一个View-Model来对数据做中转,响应数据变化,同步到两端
    3. View层来负责展示数据,接受用户事件

    Model层,我们用一个对象来代表。例如:

    let data = {
        text: 'foo'
    };
    

    View层对于我们而言,可以认为是DOM节点。例如:

    <div id="app">
    <p>text</p>
    </div>
    

    为了方便注入内容,改用JS来写,可以写成

    let str = `<div id="app"><p>test</p></div>`;
    

    至于View-Model,我们要做两件事,一是将数据及时同步到View层,二是响应用户事件,更改数据。我们设计一个函数来完成这项工作。

    // 把对象转成可监听的
    const ob = function (data) {
      // 无new构造
      if (!(this instanceof ob)) {
        return new ob(data);
      }
      // 设定观察者列表
      let observerList = [];
    
      // 暴露添加观察者方法
      this.addOb = function (fn) {
        observerList.push(fn);
      }
    
      // 遍历属性,通过defineProperty来对属性变化做监听
      for (let key in data) {
        let value = data[key];
        Object.defineProperty(data, key, {
          enumerable:true, // 枚举
          get () {
            return value;
          },
          set (newVal) {
            value = newVal;
            observerList.forEach((el)=>{
              el(newVal);
            })
          }
        })
      }
    };
    

    为了简单起见,把View的渲染封装成一个函数,当然实际上不能这么操作。

    const render = (text) => {
      document.getElementById('app').innerHTML = '<p>'+ text +'</p>';
    }
    

    然后将render和数据绑定起来。

    let testObj = {
      name: 'liu'
    };
    
    const vm = (data) => {
      render(testObj.name);
      let newOb = ob(data);
      newOb.addOb(function () {
        render(data.name);
      })
    };
    
    vm(testObj);
    
    // 如果直接设置testObj.name = 'test';就会触发对应的修改
    

    以上,基本上实现了数据和视图间的绑定。
    可以再继续改进,在render之前,加入virtual dom的逻辑,或者加入一些语法特性,比如类似VUE和React的语法糖。
    由于直接设置对象属性其实不大安全,而且不易于追踪,可以把状态统一提取出来,进一步封装,只能通过action去触发修改,然后分发到各个调用方。保证数据的单项流动。
    这里是一个简单的例子
    感谢阅读。

  • 相关阅读:
    UIAutomator简介
    初识Anrdiod SDK
    Andriod App类型简介
    Mybatis之collection嵌套查询mapper文件写法
    Ubuntu16.04 启动纯文本界面方法
    Ubuntu16.04网络不能访问解决办法
    JavaScript之简易http接口测试工具网页版
    SpringBoot之修改单个文件后立刻生效
    JavaScript之Json的使用
    Ajax之Jquery封装使用举例2(Json和JsonArray处理)
  • 原文地址:https://www.cnblogs.com/liuyongjia/p/9231873.html
Copyright © 2011-2022 走看看