文档章节

自已实现一个mvvm的框架

gtandsn
 gtandsn
发布于 2019/11/27 13:29
字数 492
阅读 8
收藏 0
  1. 先确定一个定义后缀的文件(比如.vue)
  2. 通过正则海选出css,js,数据,和html,并存入一个对象中(vnode)
  3. 通过Object.defineProperty去监听数据的变化
    Object.defineProperty(obj,'name',{
        configurable: true, // false 不可以删除
        enumerable: true, // false 在枚举时会忽略
        value: undefined, // 任意类型的值,默认为undefined、
        writable:true // false 不可以通过数据运算符进行赋值
    });
    
    Object.defineProerty(obj,'name',{
        get:function(){
            return value;
        },
        set:function(val){
            value = val;
        }
    });
    

     

 

 

最精简的mvvm框架

思想:

 

//Model
const student = {
    'first-name': 'Tracy',
    'last-name': 'Kent',
    'height': 170,
    'weight': 50,
}
const measurement = 'cm';

//View
const createList = function (kvPairs) {
    const createListItem = function (label, content) {
        const li = document.createElement('li')
        const labelSpan = document.createElement('span')
        labelSpan.textContent = label
        const contentSpan = document.createElement('span')
        contentSpan.textContent = content;
        li.appendChild(labelSpan);
        li.appendChild(contentSpan);
        return li;
    }
    const root = document.createElement('ul')
    kvPairs.forEach(item => {
        root.appendChild(createListItem(item.key, item.value));
    })
    return root;
}

const createToggle = function (options) {
    const createRadio = function (name, opt) {
        const radio = document.createElement('input')
        radio.name = name
        radio.value = opt.value
        radio.type = 'radio'
        radio.textContent = opt.value
        radio.addEventListener('click', opt.onclick)
        radio.checked = opt.checked
        return radio
    }
    const root = document.createElement('form')
    options.opts.forEach(function (x) {
        root.appendChild(createRadio(options.name, x))
        root.appendChild(document.createTextNode(x.value))
    })
    return root
}

const createToggleableList = function (vm) {
    const listView = createList(vm.kvPairs)
    const toggle = createToggle(vm.options)
    const root = document.createElement('div')
    root.appendChild(toggle)
    root.appendChild(listView)
    return root
}

//view-movel
const createVm = function (model) {
    const calcHeight = function (measurement, cms) {
        if (measurement === 'm') {
            return cms / 100 + 'm'
        } else {
            return cms + 'cm'
        }
    }

    const options = {
        name: 'measurement',
        opts: [
            {
                value: 'cm',
                checked: model.measurement === 'cm',
                onclick: () => model.measurement = 'cm'
            },
            {
                value: 'm',
                checked: model.measurement === 'm',
                onclick: () => model.measurement = 'm'
            }
        ]
    }

    const kvPairs = [
        {
            key: 'Name: ',
            value: model.student['first-name'] + ' ' + model.student['last-name']
        },
        {
            key: 'Height: ',
            value: calcHeight(model.measurement, model.student['height'])
        },
        {
            key: 'Weight: ',
            value: model.student['weight'] + 'kg'
        },
        {
            key: 'BMI: ',
            value: model.student['weight'] / (model.student['height'] * model.student['height'] / 10000)
        }]

    return {kvPairs, options};
}

const run = function (root, {model, view, vm}) {
    // const rendered = view(vm(model));
    // root.appendChild(rendered);

    //轮询监听model的变化,如果变化了就通知view更新

    let m = {...model}
    let m_old = {}
    setInterval( function (){
        //_.isEqual是lodash里面的方法
        if(!_.isEqual(m, m_old)){
            const rendered = view(vm(m))
            root.innerHTML = ''
            root.appendChild(rendered)
            m_old = {...m}
        }
    },1000)
}

run(document.body, {
    model: {student,measurement},
    view: createToggleableList,
    vm: createVm
});

致敬: https://mengera88.github.io/2017/07/24/%E4%BB%8E%E9%9B%B6%E5%BC%80%E5%A7%8B%E7%BC%96%E5%86%99%E4%B8%80%E4%B8%AAMVVM%E6%A1%86%E6%9E%B6/

© 著作权归作者所有

上一篇: createDocumentFragment
下一篇: 深入理解模块
gtandsn
粉丝 0
博文 121
码字总数 54169
作品 0
成都
私信 提问
Mvvm设计模式

最近前端圈子里面,发现大家都在热炒概念,什么knockout,angularJs,都被捧成神了,鄙人不才,最近心情也不好,特地写这篇文章来找骂 写代码的码农都知道,Java社区虽然不是一个提出分层思想...

村长大神
2015/04/24
161
0
前端面试题:这是我理解的MVVM,请注意查收~~

MVVM模式是什么?你是怎么理解MVVM原理的?理解它不只是应付面试,对VUE、Backbone.js、angular、Ember、avalon框架的设计模式也会有更进步一步的理解,有可能下一个流行框架就是你的杰作~~本...

草履虫的思考
2019/04/18
0
0
轻量级 JavaScript 框架--Sugarjs

Sugar.js 是一个用于开发前端模块化 UI 组件的轻量级 JavaScript 框架 ( mvvm & template ) 框架特点: 体积轻量 Api 简单。 模块化/组件化前端工程。 视图组件可复用、可继承,方便开发和维...

唐朝的唐
2016/05/03
807
0
C 语言 MVVM 框架 - AWTK-MVVM

AWTK-MVVM是一套为AWTK用C语言开发,并支持各种脚本语言的MVVM框架,实现了数据绑定、命令绑定和窗口导航等基本功能,使用AWTK-MVVM开发应用程序,无需学习AWTK本身的API,只需学习绑定规则和...

lixianjing
2019/12/12
631
0
RoboBinding 0.8.6 发布,Android数据绑定框架

首先恭喜RoboBinding成为最流行的Android native MVVM框架。 RoboBinding是一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架。请看框架介绍了解学习。MVVM模式是MVC模式的...

cheng112
2014/09/21
2.1K
8

没有更多内容

加载失败,请刷新页面

加载更多

如何为MVC-3转换为4应用程序添加对System.Web.Optimization的引用

我正在最近从MVC 3转换为MVC 4 beta的项目中尝试使用新的捆绑功能。 它需要global.asax中的一行代码, BundleTable.Bundles.RegisterTemplateBundles(); ,这需要using System.Web.Optimiza...

技术盛宴
今天
61
0
Kettle自定义jar包供javascript使用

我们都知道 Kettle 是用 Java 语言开发,并且可以在 JavaScript 里面直接调用 java 类方法。所以有些时候,我们可以自定义一些方法,来供 JavaScript 使用。 本篇文章有参考自:https://www...

CREATE_17
昨天
106
0
处理CSV文件中的逗号

我正在寻找有关如何处理正在创建的csv文件的建议,然后由我们的客户上传,并且该值可能带有逗号(例如公司名称)。 我们正在研究的一些想法是:带引号的标识符(值“,”值“,”等)或使用|...

javail
昨天
79
0
计算一个数的数位之和

计算一个数的数位之和 例如:128 :1+2+8 = 11 public int numSum(int num) { int sum = 0; do { sum += num % 10; } while ((num = num / 10) > 0); return sum;......

SongAlone
昨天
128
0
为什么图片反复压缩后普遍会变绿,而不是其他颜色?

作者:Lion Yang 链接:https://www.zhihu.com/question/29355920/answer/119088684 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 业余版概要:安卓的...

shzwork
昨天
85
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部