MVVM框架介绍--简易mvvm框架 | 青训营笔记

192 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天

介绍

  • M(Model,模型层)
  • V (View,视图层)
  • VM (ViewModel,视图模型,V与M连接的桥梁)
  • MVVM框架实现了数据双向绑定
  • 当M层数据进行修改时,VM层会监测到变化,并且通知V层进行相应的修改
  • 修改V层会通知M层数据进行修改
  • MVVM框架实现视图与模型层的相互解藕

vue相当于ViewModel的作用

几种双向数据绑定的方式

  • 发布-订阅者模式(backbone.js) --一般通过pub、sub的方式来实现数据和视图的绑定,但是麻烦

  • 脏值检查(angular,js) --通过脏值检测的方式比对数据是否变更,来决定是否更新视图。类似于通过定时器轮训检测数据是否发生了改变

  • 数据劫持 --采用数据劫持结合发布-订阅者模式的方式。通过Object.defineProperty()来劫持各个属性的setter,getter在数据变动时发布消息给订阅者,触发相应的监听回调

vue中也是允许进行dome操作的(但是不建议)

this.elthis.el和this.ref的区别

  • this.$el是在mounted中才会出现的,在created的时候是没有的所以我们引用的时候

this.$el指的是当前组件的的元素

mounted () {
 +      /* 事件绑定 */
 +      this.$el.addEventListener('touchstart', this.itemTouchStart)
 +      this.$el.addEventListener('touchmove', this.itemTouchMove)

* Compile构建 (专门负责解析模板内容)

constructor构建

(考虑重绘和回流,如果每个内容挨个更新渲染就会低效)

  • 1.把el中所有的子结点都放入内存中,fragment
  • 2.在内存中编译fragment
  • 3.把fragment一次性加入页面

核心方法 1. node2fragment

(DocumentFragment):

与 document 相比,最大的区别是它不是真实 DOM 树的一部分,它的变化不会触发 DOM 树的重新渲染,且不会对性能产生影响。

(childNodes)

childNodes 属性返回节点的子节点集合,以 NodeList 对象。

提示:您可以使用 length 属性来确定子节点的数量,然后您就能够遍历所有的子节点并提取您需要的信息。

  • 语法
element.childNodes

类数组(NodeList,arguments)变成数组

[].slice.call(arguments)等价于:Array.prototype.slice.call(arguments) 和 [].__proto__.slice.call(arguments)

        Array.prototype.mySlice = function () {
            var start = 0;
            var end = this.length;
            var temp = [];

            if (arguments.length === 1) {
                start = arguments[0];
            } else if (arguments.length === 2) {
                start = arguments[0];
                end = arguments[1];
            }
            for (var i = start; i < end; i++) {
                // fakeArr[0]
                // fakeArr[1]
                // fakeArr[2]
                temp.push(this[i]);

            }
            //最后得到真正的数组
            return temp;
        }

        //伪数组
        var fakeArr = {
            0: 'a',
            1: 'b',
            2: 'c',
            length: 3
        }

        var newArr = [].mySlice.call(fakeArr); //this指向 fakeArr
        console.log(newArr); // ["a", "b", "c"]
  • array.slice(start, end),类数组可以for循环,起始点 start 和 结束点 end 将一段指定区间内的 类数组元素 push 到一个新数组中

判断节点类型

//如果是元素,需要解析指令 //如果是文本节点,需要解析

   isElementNode(node) {
       //nodeType :节点类型 1:元素节点 3:文本节点
       return node.nodeType === 1
   }
   isTextNode(node) {
       return node.nodeType === 3
   }

1、文档节点

  • document

  • 重点记忆属性:

    • nodeType(节点类型):9
    • nodeName(节点名字):“#document”
    • nodeValue(节点文本内容):null

2、元素节点

  • 所有元素标签

  • 重点记忆属性:

    • nodeType(节点类型):1
    • nodeName(节点名字):“大写标签名”
    • nodeValue(节点文本内容):null

3、文本节点

  • 文字、标签之间的空格和换行也被当作文本节点

  • 重点记忆属性:

    • nodeType(节点类型):3
    • nodeName(节点名字):“#text”
    • nodeValue(节点文本内容):文本内容

4、注释节点

  • 注释内容

  • 重点记忆属性:

    • nodeType(节点类型):8
    • nodeName(节点名字):“#comment”
    • nodeValue(节点文本内容):注释内容

回到基础:什么是DOM及DOM操作? - 掘金 (juejin.cn) (速查)