• Road to the future——伪MVVM库Q.js


    模仿Vuejs的伪MVVM库,下面是使用说明 
    项目地址:https://github.com/miniflycn/Q.js

    相关项目:https://github.com/miniflycn/Ques

    一个简单例子

    模版:

    <a href="javascript:void(0)" q-text="msg"></a>

    脚本:

    var vm = new Q({
        el: '#demo',
        data: {
            msg: 'hello'
        }
    });

    则会展示:

    <a href="javascript:void(0)">hello</a>

    当使用.data方法修改data时候会触发节点数据修改:

    vm.$set('msg', '你好');

    则会展示:

    <a href="javascript:void(0)">你好</a>

    TodoMVC例子

    我们用Q.js实现了一个TodoMVC的例子: 
    https://github.com/miniflycn/Q.js/tree/master/examples/todomvc

    相比jQuery的实现,分层较为清晰,而比BackBone的实现要简单。

    当然我们与Vuejs的实现非常像,咳咳。

    基本概念

    directive

    告知libaray如何对节点进行操作,遵循Vuejs写法:

    <element
      prefix-directiveId="[argument:] expression [| filters...]">
    </element>

    简单例子:

    <div q-text="message"></div>

    这里表示message对应的数据,用text指令进行操作,text指令是在该节点塞入文字。

    自定义directive

    举一个我们在todoMVC的例子:

    <input q-todo-focus="editing" />

    则表示editing对应的数据变化时执行todo-focus指令,看看我们todo-focus指令怎么写的:

    directives: {
        'todo-focus': function (value) {
            // 如果editing的值为false,则不处理
            if (!value) {
                return;
            }
            // 为true则,对该节点focus()一下
            var el = this.el;
            setTimeout(function () {
                el.focus();
            }, 0);
        }
    }

    通用directive

    目前只提供了极少的通用directive,未来可拓展

    • show - 显示与否
    • class - 是否添加class
    • value - 改变值
    • text - 插入文本
    • repeat - 重复节点
    • on - 事件绑定
    • model - 双向绑定(只支持input、textarea)
    • vm - 创建子VM

    filter

    如果设置了filter,则绑定的数据会经过filter才执行对应的directive,这是我们可以在塞入数据前做输出处理,或事件触发前做数据处理。

    模版:

    <input q-model="msg" q-on="keyup: showMsg | key enter" />

    key是其中一个通用filter,基本实现是:

    var keyCodes = {
            enter    : 13,
            tab      : 9,
            'delete' : 46,
            up       : 38,
            left     : 37,
            right    : 39,
            down     : 40,
            esc      : 27
        };
    
    /**
     * A special filter that takes a handler function,
     * wraps it so it only gets triggered on specific
     * keypresses. v-on only.
     *
     * @param {String} key
     */
    function key(handler, key) {
        if (!handler) return;
        var code = keyCodes[key];
        if (!code) {
            code = parseInt(key, 10);
        }
        return function (e) {
            if (e.keyCode === code) {
                return handler.call(this, e);
            }
        };
    }

    则,当keyup发生,keyCode为13(即enter)时候,才会触发showMsg方法。

    method

    特制on指令会调用的方法,例如:上面讲到的showMsg。

    设置方法:

    var vm = new Q({
        el: '#demo',
        data: {
            msg: 'hello'
        },
        methods: {
            showMsg: function () {
                alert(this.msg);
            }
        }
    });

    则那个input框会在初始化时自动设值为hello,当改变时候msg值也会改变,当按下回车键,则会触发showMsg方法打印值。

    data

    大部分操作都和对象与数组的操作相同,只有当设置值的时候需要使用.$set方法,因为我们没有defineProperty的支持。

    • 得到一个msg的值:
    vm.msg
    • 设置msg的值
    vm.$set('msg', obj);
    • 对于数组可使用大部分数组方法,目前已经支持了:pushpopunshiftshiftindexOfspliceforEachfilter

    性能如何

    感谢@ouvenzhang提供的测试数据,具体参考https://github.com/miniflycn/Q.js/tree/master/benchmarks

    用例Q.jsjQueryNative
    单节点html操作OPS 82,652 ops/sec ±2.32% 46,526 ops/sec ±5.45% 1,101,462 ops/sec ±1.06%
    多节点html操作OPS 23,641 ops/sec ±0.58% 4,416 ops/sec ±7.76% 33,434 ops/sec ±1.37%
    1000个节点repeat渲染操作OPS 13.54 ops/sec ±2.32% 31.67 ops/sec ±5.45% 前一个数据为通常的模版引擎
  • 相关阅读:
    Java面试:用set集合的时候,重写过hashcode()和equal()方法吗?有什么作用?
    Bootstrap起步
    Java NIO
    Dobbo和SpringCloud区别
    Java虚拟机类加载机制和双亲委派模型
    继承和组合的特点和区别
    LinkedList和ArrayList底层原理
    聚集索引和非聚集索引
    Stream和迭代器的区别
    悲观锁和乐观锁
  • 原文地址:https://www.cnblogs.com/justany/p/4256759.html
Copyright © 2020-2023  润新知