真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Vue官方文檔梳理之全局API的示例分析

這篇文章將為大家詳細(xì)講解有關(guān)Vue官方文檔梳理之全局API的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括平川網(wǎng)站建設(shè)、平川網(wǎng)站制作、平川網(wǎng)頁(yè)制作以及平川網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,平川網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶(hù)以成都為中心已經(jīng)輻射到平川省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶(hù)的支持與信任!

Vue.extend

配置項(xiàng)data必須為function,否則配置無(wú)效。data的合并規(guī)則源碼如下:

Vue官方文檔梳理之全局API的示例分析

傳入非function類(lèi)型的data(上圖中data配置為{a:1}),在合并options時(shí),如果data不是function類(lèi)型,開(kāi)發(fā)版會(huì)發(fā)出警告,然后直接返回了parentVal,這意味著extend傳入的data選項(xiàng)被無(wú)視了。

我們知道實(shí)例化Vue的時(shí)候,data可以是對(duì)象,這里的合并規(guī)則不是通用的嗎?注意上面有個(gè)if(!vm)的判斷,實(shí)例化的時(shí)候vm是有值的,因此不同于Vue.extend,其實(shí)下面的注釋也做了說(shuō)明(in a Vue.extend merge, both should be function),這也是官方文檔為何說(shuō)data是個(gè)特例。

另外官方文檔所說(shuō)的“子類(lèi)”,是因?yàn)閂ue.extend返回的是一個(gè)“繼承”Vue的函數(shù),源碼結(jié)構(gòu)如下:

Vue.extend = function (extendOptions) {
  //***
  var Super = this;
  var SuperId = Super.cid;
  //***
  var Sub = function VueComponent(options) {
    this._init(options);
  };
  Sub.prototype = Object.create(Super.prototype);
  Sub.prototype.constructor = Sub;
  //***
  return Sub
};

Vue.nextTick

既然使用vue,當(dāng)然要沿著數(shù)據(jù)驅(qū)動(dòng)的方式思考,所謂數(shù)據(jù)驅(qū)動(dòng),就是不要直接去操作dom,dom的所有操作完全可以利用vue的各種指令來(lái)完成,指令將數(shù)據(jù)和dom進(jìn)行了“綁定”,操作數(shù)據(jù)不僅能實(shí)現(xiàn)dom的更新,而且更方便。

如果瀏覽器支持Promise,或者用了Promise庫(kù)(但是對(duì)外暴露的必須叫Promise,因?yàn)樵创a中的判斷為typeof Promise !== 'undefined'),nextTick返回的就是Promise對(duì)象。

Vue.nextTick().then(() => {
  // do sth
})

Vue執(zhí)行nextTick的回調(diào)采用call的方式cb.call(ctx);ctx就是當(dāng)前Vue實(shí)例,因此在回調(diào)中可以直接使用this調(diào)用實(shí)例的配置。
nextTick可以簡(jiǎn)單理解為將回調(diào)放到末尾執(zhí)行,源碼中如果當(dāng)前不支持Promise和MutationObserver,那么會(huì)采用setTimeout的方式來(lái)執(zhí)行回調(diào),這不就是我們常用的延后執(zhí)行代碼的方式。

 if (typeof Promise !== 'undefined' && isNative(Promise)) {
 } else if (typeof MutationObserver !== 'undefined' && (
     isNative(MutationObserver) ||
     // PhantomJS and iOS 7.x
     MutationObserver.toString() === '[object MutationObserverConstructor]'
   )) {
 } else {
   // fallback to setTimeout
   /* istanbul ignore next */
   timerFunc = function () {
     setTimeout(nextTickHandler, 0);
   };
 }

舉個(gè)例子來(lái)實(shí)際看下:


  {{a}}
new Vue({   el: '#app',   data: {     a: 1   },   mounted: function name(params) {     console.log('start');     this.$nextTick(function () {       console.log('beforeChange', this.$refs.dom.textContent)     })     this.a = 2;     console.log('change');     this.$nextTick(function () {       console.log('afterChange', this.$refs.dom.textContent)     })     console.log('end');   } }) // 控制臺(tái)依次打印 // start // change // end // beforeChange 1 // afterChange 2

你估計(jì)會(huì)有些納悶,既然都是最后才執(zhí)行,那為什么beforeChange輸出的是1而不是2,這是因?yàn)閠his.a=2背后觸發(fā)dom更新也是采用nextTick的方式,上面的代碼實(shí)際執(zhí)行的順序是:beforeChange>更新dom>afterChange。

Vue.set

Vue.set( target, key, value ),target不能是 Vue 實(shí)例,或者 Vue 實(shí)例的根數(shù)據(jù)對(duì)象,因?yàn)樵创a中做了如下判斷:

var ob = (target).__ob__;
if (target._isVue || (ob && ob.vmCount)) {
"development" !== 'production' && warn(
  'Avoid adding reactive properties to a Vue instance or its root $data ' +
  'at runtime - declare it upfront in the data option.'
);
return val
}

target._isVue阻止了給Vue實(shí)例添加屬性,ob && ob.vmCount阻止了給Vue實(shí)例的根數(shù)據(jù)對(duì)象添加屬性。

Vue.delete

如果Vue能檢測(cè)到delete操作,那么就不會(huì)出現(xiàn)這個(gè)api。如果一定要用delete來(lái)刪除$data的屬性,那就用Vue.delete,否則不會(huì)觸發(fā)dom的更新。

同Vue.set,Vue.delete( target, key )的target不能是一個(gè) Vue 示例或 Vue 示例的根數(shù)據(jù)對(duì)象。源碼中的阻止方式和Vue.set相同。

在2.2.0+ 版本中target若為數(shù)組,key則是數(shù)組下標(biāo)。因?yàn)閂ue.delete刪除數(shù)組實(shí)際是用splice來(lái)刪除,delete雖然能用于刪除數(shù)組,但位置還在,不能算真正的刪除。

var a = [1, 2, 3];
delete a[0];
console.log(a); // [undefined, 2, 3]

Vue.use

Vue.use 源碼比較簡(jiǎn)單,可以全部貼出來(lái)。

Vue.use = function (plugin) {
  var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
  if (installedPlugins.indexOf(plugin) > -1) {
    return this
  }
  // additional parameters
  var args = toArray(arguments, 1);
  args.unshift(this);
  if (typeof plugin.install === 'function') {
    plugin.install.apply(plugin, args);
  } else if (typeof plugin === 'function') {
    plugin.apply(null, args);
  }
  installedPlugins.push(plugin);
  return this
};

安裝的插件放到了 installedPlugins ,安裝插件前通過(guò)installedPlugins.indexOf(plugin)來(lái)判斷插件是否被安裝過(guò),進(jìn)而阻止注冊(cè)相同插件多次。

插件類(lèi)型為 object,必須指定 install 屬性來(lái)安裝插件(typeof plugin.install === 'function'),另外插件執(zhí)行采用plugin.install.apply(plugin, args);,因此 this 訪(fǎng)問(wèn) object 的其他屬性。此處的 args 是由 Vue(args.unshift(this);) 和 Vue.use 傳入的除了 plugin 的其他參數(shù)(toArray(arguments, 1),1 表示從 arguments[1] 開(kāi)始截取)。

Vue.use({
  a: 1,
  install: function (Vue) {
    console.log(this.a) // 1
    console.log(arguments) // [function Vue(options),"a", "b", "c"]
  }
}, 'a', 'b', 'c')

插件類(lèi)型為 function,安裝調(diào)用plugin.apply(null, args);,因此在嚴(yán)格模式下插件運(yùn)行時(shí)上下文 this 為 null,非嚴(yán)格模式為 Window。

'use strict'
Vue.use(function plugin() {
  console.log(this) // null
  console.log(arguments) // [function Vue(options),"a", "b", "c"]
}, 'a', 'b', 'c')

Vue.compile

和眾多 JS 模板引擎的原理一樣,預(yù)先會(huì)把模板轉(zhuǎn)化成一個(gè) render 函數(shù),Vue.compile 就是來(lái)完成這個(gè)工作的,目標(biāo)是將模板(template 或 el)轉(zhuǎn)化成 render 函數(shù)。
Vue.compile 返回了{(lán)render:Function,staticRenderFns:Array},render 可直接應(yīng)用于 Vue 的配置項(xiàng) render,而 staticRenderFns 是怎么來(lái)的,而且按照官網(wǎng)的例子,Vue 還有個(gè)隱藏的配置項(xiàng) staticRenderFns,先來(lái)個(gè)例子看看。

var compiled = Vue.compile(
  '
' +   '

no data binding

' +   '
{{prop}}
' +   '
' ) console.log(compiled.render.toString()) console.log(compiled.staticRenderFns.toString()) // render function anonymous() {   with(this) {     return _c('div', [_m(0), _c('section', [_v(_s(prop))])])   } } // staticRenderFns function anonymous() {   with(this) {     return _c('header', [_c('h2', [_v("no data binding")])])   } }

原來(lái)沒(méi)有和數(shù)據(jù)綁定的 dom 會(huì)放到 staticRenderFns 中,然后在 render 中以_m(0)來(lái)調(diào)用。但是并不盡然,比如上述模板去掉

,staticRenderFns 長(zhǎng)度為 0,header 直接放到了 render 函數(shù)中。

function anonymous() {
  with(this) {
    return _c('div', [_c('header', [_v("no data binding")]), _c('section', [_v(_s(prop))])])
  }
}

Vue.compile 對(duì)應(yīng)的源碼比較復(fù)雜,上述渲染

沒(méi)有放到 staticRenderFns 對(duì)應(yīng)源碼的核心判斷如下:

 // For a node to qualify as a static root, it should have children that
 // are not just static text. Otherwise the cost of hoisting out will
 // outweigh the benefits and it's better off to just always render it fresh.
 if (node.static && node.children.length && !(
     node.children.length === 1 &&
     node.children[0].type === 3
   )) {
   node.staticRoot = true;
   return
 } else {
   node.staticRoot = false;
 }

不符判斷條件 !(node.children.length === 1 && node.children[0].type === 3),
有一個(gè)子節(jié)點(diǎn) TextNode(nodeType=3)。 注釋也說(shuō)明了一個(gè) node 符合靜態(tài)根節(jié)點(diǎn)的條件。

另外官網(wǎng)說(shuō)明了此方法只在獨(dú)立構(gòu)建時(shí)有效,什么是獨(dú)立構(gòu)建?這個(gè)官網(wǎng)做了詳細(xì)的介紹,不再贅述。對(duì)應(yīng)官網(wǎng)地址:對(duì)不同構(gòu)建版本的解釋。

仔細(xì)觀(guān)察編譯后的 render 方法,和我們自己寫(xiě)的 render 方法有很大區(qū)別。但是仍然可以直接配置到 render 配置選項(xiàng)上。那么里面的那些 _c()、_m() 、_v()、_s() 能調(diào)用?隨便看一個(gè) Vue 的實(shí)例的 __proto__ 就會(huì)發(fā)現(xiàn):

Vue官方文檔梳理之全局API的示例分析

// internal render helpers.
// these are exposed on the instance prototype to reduce generated render
// code size.
Vue.prototype._o = markOnce;
Vue.prototype._n = toNumber;
Vue.prototype._s = toString;
Vue.prototype._l = renderList;
Vue.prototype._t = renderSlot;
Vue.prototype._q = looseEqual;
Vue.prototype._i = looseIndexOf;
Vue.prototype._m = renderStatic;
Vue.prototype._f = resolveFilter;
Vue.prototype._k = checkKeyCodes;
Vue.prototype._b = bindObjectProps;
Vue.prototype._v = createTextVNode;
Vue.prototype._e = createEmptyVNode;
Vue.prototype._u = resolveScopedSlots;
Vue.prototype._g = bindObjectListeners;

正如注釋所說(shuō),這些方法是為了減少生成的 render 函數(shù)的體積。

全局 API 還剩 directive、filter、component、mixin,這幾個(gè)比較類(lèi)似,而且都對(duì)應(yīng)著配置項(xiàng),會(huì)在「選項(xiàng)」中再詳細(xì)介紹。

關(guān)于“Vue官方文檔梳理之全局API的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


當(dāng)前名稱(chēng):Vue官方文檔梳理之全局API的示例分析
分享URL:http://weahome.cn/article/pdccsh.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部