zoukankan      html  css  js  c++  java
  • Vue.js学习与理解

    Vue.js(读音 /vjuː/, 类似于 view)是一个构建数据驱动的 web 界面的库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    Vue.js 自身不是一个全能框架——它只聚焦于视图层。因此它非常容易学习,非常容易与其它库或已有项目整合。另一方面,在与相关工具和支持库一起使用时,Vue.js 也能完美地驱动复杂的单页应用。

    Vue.js 的核心是一个响应的数据绑定系统,它让数据与 DOM 保持同步非常简单。在使用 jQuery 手工操作 DOM 时,我们的代码常常是命令式的、重复的与易错的。Vue.js 拥抱数据驱动的视图概念。通俗地讲,它意味着我们在普通 HTML 模板中使用特殊的语法将 DOM “绑定”到底层数据。一旦创建了绑定,DOM 将与数据保持同步。每当修改了数据,DOM 便相应地更新。这样我们应用中的逻辑就几乎都是直接修改数据了,不必与 DOM 更新搅在一起。这让我们的代码更容易撰写、理解与维护。

    Vue.js比Angular.js react.js简单,学习成本低。

    Vue.js使用到二个重要的函数:

    1.Object.defineProperty 函数

    将属性添加到对象,或修改现有属性的特性。

    Object.defineProperty(object, propertyname, descriptor)
    参数
    object 必需。  要在其上添加或修改属性的对象。  这可能是一个本机 JavaScript 对象(即用户定义的对象或内置对象)或 DOM 对象。  
    propertyname 必需。  一个包含属性名称的字符串。  
    descriptor 必需。  属性描述符。  它可以针对数据属性或访问器属性。
    例子:添加访问器属性
     var obj = {},newVal;
     // Add an accessor property to the object.
     Object.defineProperty(obj, "name", {
         set: function (x) {
             console.log("in property set accessor" + newVal);
             this.firstName= x;
         },
         get: function () {
             console.log("in property get accessor" + newVal);
             return this.firstName;
         },
         enumerable: true,
         configurable: true
     });

    Vue.js当数据有变化时,通过defineProperty的set方法去通知notify()订阅者subscribers有新的值修改

      function defineReactive(obj, key, val, doNotObserve) {
        var dep = new Dep();
    
        var property = Object.getOwnPropertyDescriptor(obj, key);
        if (property && property.configurable === false) {
          return;
        }
    
        // cater for pre-defined getter/setters
        var getter = property && property.get;
        var setter = property && property.set;
    
        // if doNotObserve is true, only use the child value observer
        // if it already exists, and do not attempt to create it.
        // this allows freezing a large object from the root and
        // avoid unnecessary observation inside v-for fragments.
        var childOb = doNotObserve ? isObject(val) && val.__ob__ : observe(val);
        Object.defineProperty(obj, key, {
          enumerable: true,
          configurable: true,
          get: function reactiveGetter() {
            var value = getter ? getter.call(obj) : val;
            if (Dep.target) {
              dep.depend();
              if (childOb) {
                childOb.dep.depend();
              }
              if (isArray(value)) {
                for (var e, i = 0, l = value.length; i < l; i++) {
                  e = value[i];
                  e && e.__ob__ && e.__ob__.dep.depend();
                }
              }
            }
            return value;
          },
          set: function reactiveSetter(newVal) {
            var value = getter ? getter.call(obj) : val;
            if (newVal === value) {
              return;
            }
            if (setter) {
              setter.call(obj, newVal);
            } else {
              val = newVal;
            }
            childOb = doNotObserve ? isObject(newVal) && newVal.__ob__ : observe(newVal);
            dep.notify();
          }
        });
      }

     2.MutationObserver函数,HTML5新特性之Mutation Observer

    Mutation Observer(变动观察器)是监视DOM变动的接口。当DOM对象树发生任何变动时,Mutation Observer会得到通知。

    要概念上,它很接近事件。可以理解为,当DOM发生变动会触发Mutation Observer事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说DOM发生变动立刻会触发相应的事件;Mutation Observer则是异步触发,DOM发生变动以后,并不会马上触发,而是要等到当前所有DOM操作都结束后才触发。

    这样设计是为了应付DOM变动频繁的情况。举例来说,如果在文档中连续插入1000个段落(p元素),会连续触发1000个插入事件,执行每个事件的回调函数,这很可能造成浏览器的卡顿;而Mutation Observer完全不同,只在1000个段落都插入结束后才会触发,而且只触发一次。

    Mutation Observer有以下特点:

    • 它等待所有脚本任务完成后,才会运行,即采用异步方式
    • 它把DOM变动记录封装成一个数组进行处理,而不是一条条地个别处理DOM变动。
    • 它即可以观察发生在DOM节点的所有变动,也可以观察某一类变动
    /**
       * Defer a task to execute it asynchronously. Ideally this
       * should be executed as a microtask, so we leverage
       * MutationObserver if it's available, and fallback to
       * setTimeout(0).
       *
       * @param {Function} cb
       * @param {Object} ctx
       */
    
      var nextTick = (function () {
        var callbacks = [];
        var pending = false;
        var timerFunc;
        function nextTickHandler() {
          pending = false;
          var copies = callbacks.slice(0);
          callbacks = [];
          for (var i = 0; i < copies.length; i++) {
            copies[i]();
          }
        }
    
        /* istanbul ignore if */
        if (typeof MutationObserver !== 'undefined') {
          var counter = 1;
          var observer = new MutationObserver(nextTickHandler);
          var textNode = document.createTextNode(counter);
          observer.observe(textNode, {
            characterData: true
          });
          timerFunc = function () {
            counter = (counter + 1) % 2;
            textNode.data = counter;
          };
        } else {
          // webpack attempts to inject a shim for setImmediate
          // if it is used as a global, so we have to work around that to
          // avoid bundling unnecessary code.
          var context = inBrowser ? window : typeof global !== 'undefined' ? global : {};
          timerFunc = context.setImmediate || setTimeout;
        }
        return function (cb, ctx) {
          var func = ctx ? function () {
            cb.call(ctx);
          } : cb;
          callbacks.push(func);
          if (pending) return;
          pending = true;
          timerFunc(nextTickHandler, 0);
        };
      })();

    异步更新队列,Vue.js 默认异步更新 DOM。每当观察到数据变化时,Vue 就开始一个队列,将同一事件循环内所有的数据变化缓存起来。如果一个 watcher 被多次触发,只会推入一次到队列中。等到下一次事件循环,Vue 将清空队列,只进行必要的 DOM 更新。在内部异步队列优先使用MutationObserver,如果不支持则使用 setTimeout(fn, 0)。通过MutationObserver, 实现了异步更新队列

     

  • 相关阅读:
    Java [leetcode 36]Valid Sudoku
    Java [leetcode 35]Search Insert Position
    java中正则表达式
    Java [leetcode 34]Search for a Range
    SSRS表达式里引用.net dll
    一个简单的批处理
    .NET大批量插入数据到Oracle
    AX2009里调用.NET DLL的效率问题
    生成折扣日记账
    python's twelth day for me
  • 原文地址:https://www.cnblogs.com/lengmeiyanok/p/5299226.html
Copyright © 2011-2022 走看看