摘要:通過(guò)查看官網(wǎng)說(shuō)明,中不要使用和開(kāi)頭,因?yàn)樵趦?nèi)部也使用和作為方法或?qū)傩裕@是為了防止沖突。使用如下就不會(huì)報(bào)錯(cuò)了。
我們先來(lái)看一個(gè)簡(jiǎn)單的例子:
{{test}} {{_tttttttttt}} {{$tttttt}}
這么一個(gè)簡(jiǎn)單例子,但是vue卻會(huì)提示你報(bào)錯(cuò)了,錯(cuò)誤如下:
從錯(cuò)誤中我們可以發(fā)現(xiàn)報(bào)錯(cuò)的原因竟然是$tttttt和_tttttttttt的變量是沒(méi)有定義。這是為什么呢?
我們明明在data中定義了。
通過(guò)查看官網(wǎng)API說(shuō)明,data中不要使用$和_開(kāi)頭,因?yàn)樵赩ue內(nèi)部也使用$和_作為方法或?qū)傩?,這是為了防止沖突。
那么我們就從源碼的角度來(lái)分析,我們定義的變量為什么沒(méi)了呢??、
我們都知道vue采用了ES的defineProperty來(lái)實(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中是沒(méi)法通過(guò)this.xxx來(lái)獲取變量的,而必須是通過(guò)this.$data.xxx。因此vue的變量都掛在在$data或_data上。
所以vue內(nèi)部還做了一層代理,如下
// target是vue實(shí)例,key為_(kāi)data,這樣就能通過(guò)訪問(wèn)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è)檢測(cè),檢測(cè)你的變量的開(kāi)頭是否為_(kāi)或$,如果使用了那么就不會(huì)使用代理了,
變量只會(huì)存在$data上或_data上。我們來(lái)看下源碼:
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是否為_(kāi)和$ } }
到這里我們就完成的解釋為什么無(wú)法訪問(wèn)了,所以一般不要使用_和$命名,如果真的要使用的話,那也行。
使用如下就不會(huì)報(bào)錯(cuò)了。
{{test}} {{_data._tttttttttt}} {{_data.$tttttt}} {{$data._tttttttttt}} {{$data.$tttttt}}