本文非vue教程,僅爲學習vue過程當中的我的理解與筆記,有說的不正確的地方歡迎指正討論html
在計算屬性的函數中,不能使用Vue構造函數返回的vm變量,由於此時vm還未返回,依然處於Vue內部構造函數過程當中,遂只能使用this來代替vm。
若要使用typescript
,可以使用如下方法來實現代碼智能感知vue
vm = vm || this;
另:其餘不能用vm變量,只能使用this變量的地方,均可以經過此方法來得到Typescript的智能感知和代碼語法檢查,好比mounted
生命週期系列函數等。
不過模板裏的vm引用Typescript無能爲力,只能等待ts支持vue的jsx語法了╮(╯_╰)╭typescript
官方教程中沒有找到相關說明(應該是我沒找到),從使用角度而言大體能夠總結出如下結論:數組
DEMO1:官方標準用法,計算屬性引用非計算屬性:app
var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { //標準用法,計算屬性引用非計算屬性 return this.dataVal + "_1";//輸出 xxcanghai_1 } } });
DEMO2:計算屬性鏈式依賴其餘計算屬性,則依賴鏈頭必須引用非計算屬性或固定值函數
var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { return this.dataVal + "_1"; }, computedVal2: function () { //合法,計算屬性computedVal2引用computedVal1,computedVal1再引用dataVal return this.computedVal1 + "_2";//輸出 xxcanghai_1_2 } } });
緣由很容易理解,若是最終沒有引用或依賴任何非計算屬性,那麼計算屬性在計算時會陷入死循環。學習
觸發這個問題有如下幾個前提:this
$children
變量$children
變量寫入過父組件的data
變量(或其餘vm數據)<!--父組件HTML模板--> <div id="app"> <div>{{$children.length}}</div> <!--此處顯示0,應該爲3--> <child></child> <child></child> <child></child> </div> //子組件代碼 Vue.component("child", { template: "<div>child</div>", }); //父組件聲明 new Vue({ el: "#app", });
以下圖:
3d
註冊父組件的mounted
方法,執行$forceUpdate()
code
<div id="app"> <div>{{$children.length}}</div> <child></child> <child></child> <child></child> </div> Vue.component("child", { template: "<div>child</div>", }); new Vue({ el: "#app", mounted: function () { this.$forceUpdate();//強制從新繪製 } });
$children正確了:

註冊父組件的mounted
方法,將$children
賦值給自定義的vm的變量。
同時模板中使用自定義的變量來代替默認的$children
<div id="app"> <div>{{child.length}}</div> <!--使用自定義的child對象--> <child></child> <child></child> <child></child> </div> Vue.component("child", { template: "<div>child</div>", }); var vm = new Vue({ el: "#app", data: { child: [] }, mounted: function () { this.child = this.$children;//手動將$children對象賦值給自定義child變量 } });

至於致使此問題的緣由只能經過閱讀vue2.0版本的源碼才能瞭解了。
此問題關聯上面第3個問題。
觸發此問題的前提:
$children
變量復現代碼:
<div id="app"> <!--子組件直接寫在調用方的模板中--> <parent> <child></child> <child></child> <child></child> </parent> </div> //父組件 Vue.component("parent", { template: "<p>parent child:{{$children.length}} </p>",//模板中無slot元素 mounted(){ this.$forceUpdate(); } }); Vue.component("child", { template: "<div>child</div>" }); var vm = new Vue({ el: "#app" });

在父組件的模板中加入slot
元素。或在render函數中引用了this.$slots.default
變量
Vue.component("parent", { template: "<p>parent child:{{$children.length}} <slot></slot></p>", mounted(){ this.$forceUpdate(); } });

此解決方案要修改此問題的復現第2要素,即子組件定義從調用方改成寫到父組件的模板中也可解決此問題。
<div id="app"> <parent> </parent> </div> Vue.component("parent", { //直接在父組件中寫明調用子組件標籤 template: "<p>parent child:{{$children.length}}\ <child></child>\ <child></child>\ </p>", mounted(){ this.$forceUpdate(); } }); Vue.component("child", { template: "<div>child</div>", }); var vm = new Vue({ el: "#app", data: { child: [] } });

此方法雖然能夠解決問題,可是有時咱們直接把子組件寫在調用方會更方便更利於理解,好比Tab與TabPage組件。
以下Tab組件代碼,可能更符合通常人的使用思惟:
<div id="app"> <tab> <tab-page>Page1</tab-page> <tab-page>Page2</tab-page> <tab-page>Page3</tab-page> </tab> </div>