亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Vue踩坑記錄(一)——vue,data屬性為什么使用了_或$開頭卻會(huì)提示報(bào)錯(cuò)?

ThreeWords / 2840人閱讀

摘要:通過查看官網(wǎng)說明,中不要使用和開頭,因?yàn)樵趦?nèi)部也使用和作為方法或?qū)傩?,這是為了防止沖突。使用如下就不會(huì)報(bào)錯(cuò)了。

我們先來看一個(gè)簡單的例子:


這么一個(gè)簡單例子,但是vue卻會(huì)提示你報(bào)錯(cuò)了,錯(cuò)誤如下:

從錯(cuò)誤中我們可以發(fā)現(xiàn)報(bào)錯(cuò)的原因竟然是$tttttt和_tttttttttt的變量是沒有定義。這是為什么呢?
我們明明在data中定義了。
通過查看官網(wǎng)API說明,data中不要使用$和_開頭,因?yàn)樵赩ue內(nèi)部也使用$和_作為方法或?qū)傩?,這是為了防止沖突。
那么我們就從源碼的角度來分析,我們定義的變量為什么沒了呢??、

我們都知道vue采用了ES的defineProperty來實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)視圖,如下:

Object.defineProperty(target, key) {
    enumerable: true,
    configurable: true,
    get: function() {
        // 這里獲取數(shù)據(jù)
    },
    set: function() {
        // 這里設(shè)置參數(shù),通知更新視圖
    }
}

可如果僅僅是這樣的話,我們?cè)趘ue中是沒法通過this.xxx來獲取變量的,而必須是通過this.$data.xxx。因此vue的變量都掛在在$data或_data上。

所以vue內(nèi)部還做了一層代理,如下

// target是vue實(shí)例,key為_data,這樣就能通過訪問this.xxx = this._data.xxx了
function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter () {
    return this[sourceKey][key]
  };
  sharedPropertyDefinition.set = function proxySetter (val) {
    this[sourceKey][key] = val;
  };
  Object.defineProperty(target, key, sharedPropertyDefinition);
}

所以那么我們的變量為什么還是不存在呢,那是因?yàn)関ue做了一個(gè)檢測,檢測你的變量的開頭是否為_或$,如果使用了那么就不會(huì)使用代理了,
變量只會(huì)存在$data上或_data上。我們來看下源碼:

function initData (vm) {
  var data = vm.$options.data;
  data = vm._data = typeof data === "function"
    ? getData(data, vm)
    : data || {};
  if (!isPlainObject(data)) {
    data = {};
    process.env.NODE_ENV !== "production" && warn(
      "data functions should return an object:
" +
      "https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function",
      vm
    );
  }
  // proxy data on instance
  var keys = Object.keys(data);
  var props = vm.$options.props;
  var methods = vm.$options.methods;
  var i = keys.length;
  while (i--) {
    var key = keys[i];
    if (process.env.NODE_ENV !== "production") {
      if (methods && hasOwn(methods, key)) {
        warn(
          ("Method "" + key + "" has already been defined as a data property."),
          vm
        );
      }
    }
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== "production" && warn(
        "The data property "" + key + "" is already declared as a prop. " +
        "Use prop default value instead.",
        vm
      );
    } else if (!isReserved(key)) {
        // 這邊處理代理,所以isReserved處理了是否要進(jìn)行代理
      proxy(vm, "_data", key);
    }
  }
  // observe data
  observe(data, true /* asRootData */);

  function isReserved (str) {
      var c = (str + "").charCodeAt(0);
      return c === 0x24 || c === 0x5F // 這邊判斷chartCode是否為_和$
   }
}

到這里我們就完成的解釋為什么無法訪問了,所以一般不要使用_和$命名,如果真的要使用的話,那也行。
使用如下就不會(huì)報(bào)錯(cuò)了。


                
閱讀需要支付1元查看
<