關(guān)于Vue.js一些問題和思考學(xué)習(xí)筆記(2)
前言
本文非vue教程,僅為學(xué)習(xí)vue過程中的個(gè)人理解與筆記,有說的不正確的地方歡迎指正討論
1、computed計(jì)算屬性函數(shù)中不能使用vm變量
在計(jì)算屬性的函數(shù)中,不能使用Vue構(gòu)造函數(shù)返回的vm變量,因?yàn)榇藭r(shí)vm還未返回,依然處于Vue內(nèi)部構(gòu)造函數(shù)過程中,遂只能使用this來代替vm。
若要使用typescript,可使用以下方法來實(shí)現(xiàn)代碼智能感知
vm = vm || this;
另:其他不能用vm變量,只能使用this變量的地方,都可以通過此方法來獲得Typescript的智能感知和代碼語法檢查,比如mounted生命周期系列函數(shù)等。
不過模板里的vm引用Typescript無能為力,只能等待ts支持vue的jsx語法了╮(╯_╰)╭
2、計(jì)算屬性中不能引用其他計(jì)算屬性?
官方教程中沒有找到相關(guān)說明(應(yīng)該是我沒找到),從使用角度而言大致可以總結(jié)出以下結(jié)論:
- 計(jì)算屬性必須引用(依賴)非計(jì)算屬性或固定值。(見demo1)
- 計(jì)算屬性若引用(依賴)其他計(jì)算屬性,則被引用的計(jì)算屬性必須引用非計(jì)算屬性或固定值(見demo2)
- 計(jì)算屬性可循環(huán)依賴,但最終依賴鏈上的最上游的計(jì)算屬性,必須引用非計(jì)算屬性或固定值。
DEMO1:官方標(biāo)準(zhǔn)用法,計(jì)算屬性引用非計(jì)算屬性:
var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { //標(biāo)準(zhǔn)用法,計(jì)算屬性引用非計(jì)算屬性 return this.dataVal + "_1";//輸出 xxcanghai_1 } } });
DEMO2:計(jì)算屬性鏈?zhǔn)揭蕾嚻渌?jì)算屬性,則依賴鏈頭必須引用非計(jì)算屬性或固定值
var vm = new Vue({ el: "#app", data: { dataVal: "xxcanghai" }, computed: { computedVal1: function () { return this.dataVal + "_1"; }, computedVal2: function () { //合法,計(jì)算屬性computedVal2引用computedVal1,computedVal1再引用dataVal return this.computedVal1 + "_2";//輸出 xxcanghai_1_2 } } });
原因很容易理解,如果最終沒有引用或依賴任何非計(jì)算屬性,那么計(jì)算屬性在計(jì)算時(shí)會(huì)陷入死循環(huán)。
3、vue2.0中若使用組件嵌套,則在父組件執(zhí)行\(zhòng)$forceUpdate()之前模板中\(zhòng)$children為空數(shù)組
觸發(fā)這個(gè)問題有以下幾個(gè)前提:
- vue版本為2.0版本,1.0無此問題。
- 使用組件嵌套,在父組件的模板中訪問$children變量
- 在渲染完成后沒有再將$children變量寫入過父組件的data變量(或其他vm數(shù)據(jù))就會(huì)觸發(fā)此問題。
<!--父組件HTML模板--> <div id="app"> <div>{{$children.length}}</div> <!--此處顯示0,應(yīng)該為3--> <child></child> <child></child> <child></child> </div> //子組件代碼 Vue.component("child", { template: "<div>child</div>", }); //父組件聲明 new Vue({ el: "#app", });
如下圖:
解決方案1:使用\$forceUpdate()
注冊(cè)父組件的mounted方法,執(zhí)行$forceUpdate()
<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();//強(qiáng)制重新繪制 } });
$children正確了:
解決方案2:使用vm的變量代替\$children
注冊(cè)父組件的mounted方法,將$children賦值給自定義的vm的變量。
同時(shí)模板中使用自定義的變量來代替默認(rèn)的$children
<div id="app"> <div>{{child.length}}</div> <!--使用自定義的child對(duì)象--> <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;//手動(dòng)將$children對(duì)象賦值給自定義child變量 } });
至于導(dǎo)致此問題的原因只能通過閱讀vue2.0版本的源碼才能了解了。
4、若父組件的template或render函數(shù)中無引用slot元素,則\$children恒等于空數(shù)組
此問題關(guān)聯(lián)上面第3個(gè)問題。
觸發(fā)此問題的前提:
- vue2.0版本
- 父組件和子組件都直接寫在調(diào)用方模板中
- 在模板中訪問$children變量
- 已經(jīng)解決在上述問題3中強(qiáng)制刷新的問題
<div id="app"> <!--子組件直接寫在調(diào)用方的模板中--> <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" });
解決方案1:父組件模板包含slot元素
在父組件的模板中加入slot元素。或在render函數(shù)中引用了this.$slots.default變量
Vue.component("parent", { template: "<p>parent child:{{$children.length}} <slot></slot></p>", mounted(){ this.$forceUpdate(); } });
解決方案2:在父組件模板中編寫子組件定義
此解決方案要修改此問題的復(fù)現(xiàn)第2要素,即子組件定義從調(diào)用方改為寫到父組件的模板中也可解決此問題。
<div id="app"> <parent> </parent> </div> Vue.component("parent", { //直接在父組件中寫明調(diào)用子組件標(biāo)簽 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: [] } });
此方法雖然可以解決問題,但是有時(shí)我們直接把子組件寫在調(diào)用方會(huì)更方便更利于理解,比如Tab與TabPage組件。
如下Tab組件代碼,可能更符合一般人的使用思維:
<div id="app"> <tab> <tab-page>Page1</tab-page> <tab-page>Page2</tab-page> <tab-page>Page3</tab-page> </tab> </div>
相關(guān)筆記
Vue學(xué)習(xí)筆記-1(http://www.dbjr.com.cn/article/98869.htm)
Vue學(xué)習(xí)筆記-2(http://www.dbjr.com.cn/article/98878.htm)
本文已被整理到了《Vue.js前端組件學(xué)習(xí)教程》,歡迎大家學(xué)習(xí)閱讀。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue頁面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板(示例代碼)
本文中實(shí)現(xiàn)的附件上傳區(qū)域支持超多類型附件分類型上傳,并且可根據(jù)特定條件具體展示某些類型的附件上傳,本文給大家分享Vue頁面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板的示例代碼,需要的朋友參考下吧2021-12-12vue中{{}},v-text和v-html區(qū)別與應(yīng)用詳解
這篇文章主要介紹了vue中{{}},v-text和v-html區(qū)別與應(yīng)用詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-09-09vue學(xué)習(xí)筆記之vue1.0和vue2.0的區(qū)別介紹
今天我們來說一說vue1.0和vue2.0的主要變化有哪些?對(duì)vue相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧2017-05-05vue+elementUI-el-table實(shí)現(xiàn)動(dòng)態(tài)顯示隱藏列方式
這篇文章主要介紹了vue+elementUI-el-table實(shí)現(xiàn)動(dòng)態(tài)顯示隱藏列方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01vue使用高德地圖實(shí)現(xiàn)添加點(diǎn)標(biāo)記和獲取點(diǎn)擊位置信息的示例代碼
這篇文章主要介紹了vue使用高德地圖實(shí)現(xiàn)添加點(diǎn)標(biāo)記和獲取點(diǎn)擊位置信息的示例代碼,文中補(bǔ)充介紹了高德vue-amap使用(一)標(biāo)記點(diǎn)位獲取地址及經(jīng)緯度,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2024-01-01