摘要:我在中寫了這段代碼在組件被創(chuàng)建時(shí)候?qū)?huì)執(zhí)行此函數(shù)相當(dāng)于進(jìn)入頁(yè)面的自執(zhí)行使用方法監(jiān)聽(tīng)屬性并執(zhí)行一個(gè)回調(diào)函數(shù)按道理在元素被創(chuàng)建的時(shí)候,會(huì)將監(jiān)聽(tīng)到的值賦給并且打印。
天地不仁以萬(wàn)物為芻狗,宇宙無(wú)義視眾生如螻蟻
——蕭鼎和我
上一節(jié)列出了5個(gè)關(guān)鍵點(diǎn),第一個(gè)路由已經(jīng)解決了,接下來(lái)解決第二個(gè)問(wèn)題:
組件的通信問(wèn)題
一、組件的關(guān)系
組件之間的關(guān)系無(wú)非就是兩種父子關(guān)系和沒(méi)有父子關(guān)系。為什么我這樣說(shuō)呢?
按道理應(yīng)該還有兄弟關(guān)系(也就是并列的組件,比如一個(gè)組件中引用了hreder和footer組件。),還有爺孫關(guān)系(比如我有七個(gè)Calabash Brothers組件,放在的HanHan組件下,而HanHan組件放在了Chairman Mao組件下)
那么不應(yīng)該是父子、爺孫、兄弟關(guān)系嗎?
然而并不是,因?yàn)槲铱戳藇ue的文檔。他的意思就是父子通信和非父子通信。
二、父子之間的通信——Prop和自定義事件
組件實(shí)例的作用域是孤立的。這意味著不能并且不應(yīng)該在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)。
prop 是父組件用來(lái)傳遞數(shù)據(jù)的一個(gè)自定義屬性。子組件需要顯式地用 props 選項(xiàng)聲明 “prop”。
將我們的App.vue當(dāng)作父組件,將test當(dāng)作子組件(什么當(dāng)作,本來(lái)就是)。
在App.vue中修改我們的
在Test.vue中接收,并在頁(yè)面中顯示:
我是全英雄聯(lián)盟最騷的騷豬
說(shuō): {{say}}
然后在瀏覽器的顯示效果如下:
綜上所述可以看出,其實(shí)所謂的prop就是在
上面的例子很漂亮的把父?jìng)髯拥耐ㄐ欧绞秸宫F(xiàn)出來(lái)了。但是子傳父呢?
vue文檔中使用的自定義事件。
使用 $on(eventName) 監(jiān)聽(tīng)事件
使用 $emit(eventName) 觸發(fā)事件
我們還是用APP.vue作為父組件,Test.vue作為子組件
App.vue
... /*增加一個(gè)位置來(lái)顯示子組件傳過(guò)來(lái)的值*/我兒子對(duì)我說(shuō): {{noSay}}
/* 增加一個(gè)自定義的事件mychild,并給他指定觸發(fā)的方法*/... data () { return { noSay: "" // 用來(lái)接收子組件穿過(guò)來(lái)的數(shù)據(jù) } }, methods: { toFatherSay: function(massage) { // mychlid事件觸發(fā)調(diào)用的方法 this.noSay = massage // massage就是子組件穿過(guò)來(lái)的內(nèi)容 } }
Test.vue
.... /*增加一個(gè)按鈕,一點(diǎn)擊就向父組件傳值*/ .... data() { return { massage: "我才不說(shuō)呢" // 定義一個(gè)向父組件傳遞的值 } }, methods: { toFather: function() { // 按鈕點(diǎn)擊觸發(fā)的方法 this.$emit("myChild",this.massage)// 使用$emit來(lái)向父組件傳播 } }, ....
做完以上操作之后在瀏覽器上測(cè)試:
三、非父子關(guān)系之間的通信——eventBus
在veu文檔上,非父子之間的通信是通過(guò)使用一個(gè)空的Vue實(shí)例作為中央事件總線。
空的Vue實(shí)例? and 中央事件總線?
空的Vue實(shí)例也就是說(shuō)
var bus = new Vue(); // 的確是一個(gè)空的
中央事件總線,難道組件通信要通過(guò)全局的事件來(lái)進(jìn)行?
的確是這樣,vue提供了$emit和$on方法來(lái)進(jìn)行參數(shù)監(jiān)聽(tīng)(其實(shí)就是個(gè)發(fā)布訂閱模式)。
創(chuàng)建一個(gè)空的Vue實(shí)例 Bus.js:
import Vue from "vue" export default new Vue();
將我們的Apart.vue和Bpart.vue當(dāng)作非父子關(guān)系組件:
Apart.vue
我是Apart
點(diǎn)我切換
Bpart.vue
然后在瀏覽器中測(cè)試一下:
有問(wèn)題!!!無(wú)論怎么點(diǎn)擊我們發(fā)現(xiàn)Bpart中定義的whiteSay并沒(méi)有改變,并且第一次點(diǎn)擊控制臺(tái)沒(méi)有打印。我在Bpart中寫了這段代碼:
data () { return { whiteSay: "nihao" } }, created: function() { // 在組件被創(chuàng)建時(shí)候?qū)?huì)執(zhí)行此函數(shù) 相當(dāng)于進(jìn)入頁(yè)面的自執(zhí)行 Bus.$on("whiteSay", function(data) { // 使用$on方法監(jiān)聽(tīng)white屬性并執(zhí)行一個(gè)回調(diào)函數(shù) this.whiteSay = data console.log(this.whiteSay) }); }
按道理在元素被創(chuàng)建的時(shí)候,會(huì)將監(jiān)聽(tīng)到的值賦給whiteSay并且打印。但是我們注意到第一次點(diǎn)擊,兩個(gè)操作都沒(méi)有執(zhí)行,也就是說(shuō)沒(méi)有監(jiān)聽(tīng)到whiteSay值的變化。而第二次之后都監(jiān)聽(tīng)到了。這是為什么?為什么把值賦給data中定義的whiteSay之后沒(méi)有網(wǎng)頁(yè)沒(méi)有更新?
帶著這兩個(gè)問(wèn)題我去問(wèn)了度娘和股哥。一下是答案:
第一個(gè)為什么: 項(xiàng)目中使用了vue-router,會(huì)先加載新的組件,等新的組件渲染好但是還沒(méi)掛載前,銷毀舊組件,在掛載新組件。將Apart.vue的代碼修改為:
... methods: { goPage: function () { this.$router.push("/bb") } }, /*Vue 實(shí)例銷毀后調(diào)用 就是所謂的生命周期鉤子*/ destroyed() { Bus.$emit("whiteSay", "克里斯,關(guān)下門") // 使用$emit方法創(chuàng)建一個(gè)鍵值對(duì) }, ...
這樣第一個(gè)問(wèn)題就解決了。附上找到的答案連接:https://segmentfault.com/q/10...
第二個(gè)為什么:這個(gè)是我自己代碼有問(wèn)題,問(wèn)了隔壁大神。說(shuō)是我的作用域有問(wèn)題,將Bpart.vue中的代碼改為:
··· created: function() { // 在組件被創(chuàng)建時(shí)候?qū)?huì)執(zhí)行此函數(shù) 相當(dāng)于進(jìn)入頁(yè)面的自執(zhí)行 var _self = this; // 將當(dāng)前作用域保存在變量中,和$on()的作用域區(qū)分開(kāi)來(lái) Bus.$on("whiteSay", function(data) { // 使用$on方法監(jiān)聽(tīng)white屬性并執(zhí)行一個(gè)回調(diào)函數(shù) _self.whiteSay = data console.log(_self.whiteSay) }); } ···
這樣所有的問(wèn)題就都解決了。
四、Vuex
當(dāng)我使用了上面幾種方法來(lái)實(shí)現(xiàn)組件的通信存在著一些缺陷。比如父組件向子組件傳一個(gè)值,子組件將值處理完了返回給父組件,這將同時(shí)用到prop和自定義事件。還不如直接寫一個(gè)所有組件都可以訪問(wèn)的變量呢來(lái)得方便呢。比如:
/*這是vuex文檔中的例子*/ const sourceOfTruth = {} const vmA = new Vue({ data: sourceOfTruth }) const vmB = new Vue({ data: sourceOfTruth })
再比如當(dāng)項(xiàng)目過(guò)大,組件之間的通信將變得難以管理。veux的初衷就是為何更好的管理組件的狀態(tài)。一下是vuex文檔對(duì)vuex的定義:
Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開(kāi)發(fā)的狀態(tài)管理模式。它采用集中式存儲(chǔ)管理應(yīng)用的所有組件的狀態(tài),并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測(cè)的方式發(fā)生變化。Vuex 也集成到 Vue 的官方調(diào)試工具 devtools extension,提供了諸如零配置的 time-travel 調(diào)試、狀態(tài)快照導(dǎo)入導(dǎo)出等高級(jí)調(diào)試功能。
寫得好累,還好最近沒(méi)事做,不會(huì)被boss罵。
接下來(lái)直接開(kāi)始使用vuex。
先下載
在根目錄下打開(kāi)cmd:
npm install vuex -save
下載成功看到一下數(shù)據(jù):
C:Users59227Desktopx-chat>npm install vuex --save x-chat@1.0.0 C:Users59227Desktopx-chat `-- vuex@2.1.1 npm WARN optional Skipping failed optional dependency /chokidar/fsevents: npm WARN notsup Not compatible with your operating system or architecture: fsevents@1.0.15
然后在main.js中引用,并安裝到Vue上面
import Vuex from "vuex" Vue.use(Vuex)
前面兩步將Vuex引入到了項(xiàng)目當(dāng)中,接下來(lái)如何使用Vuex。
Vuex的核心是一個(gè)store(倉(cāng)庫(kù))這個(gè)倉(cāng)庫(kù)的作用就是用來(lái)管理應(yīng)用中的state(狀態(tài))。這里狀態(tài)該怎么理解?
我個(gè)人的理解是:所有組件共享的并可以進(jìn)行更改的對(duì)象。
除了state的,store還有g(shù)etter、Mutations、Actions以及Modules。在vuex文檔中都有非常詳細(xì)的說(shuō)明:http://vuex.vuejs.org/zh-cn/s...
籠統(tǒng)的說(shuō):
組件獲取 state 用 vuex 的 getter
組件觸發(fā)動(dòng)作用 vuex 的 action
修改 state 用 vuex 的 mutation
知乎上看到的,說(shuō)得很貼切易懂。
直接上代碼,建議擼完代碼,再去看一遍vuex的文檔。
main.js
.... const store = new Vuex.Store({ //創(chuàng)建一個(gè)倉(cāng)庫(kù) state: { showDagger: true, // 定義一個(gè)狀態(tài) }, mutations: {// 定義 mutation ,更改 Vuex 的 store 中的狀態(tài)的唯一方法是提交mutation daggerCtrl (state) { // 一定要傳入state,并且是第一個(gè)參數(shù) state.showDagger = !state.showDagger // 將showDagger值取反 } } }) /* eslint-disable no-new */ new Vue({ el: "#app", router, // 將router對(duì)象傳給vue,這樣就可以通過(guò)this.$router獲取到router對(duì)象了 store, // 將store對(duì)象傳給vue,這樣就可以通過(guò)this.$store獲取到store對(duì)象了 template: "", components: { App } })
然后更改App.vue:
我兒子對(duì)我說(shuō): {{noSay}}
1.添加按鈕和組件
dagger.vue
Dagger
打開(kāi)瀏覽器 看效果:
使用vuex實(shí)現(xiàn)組件通信就搞定了,更多的用法請(qǐng)參考vuex文檔。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/86718.html
摘要:在離開(kāi)過(guò)渡被觸發(fā)時(shí)生效,在完成之后移除。可以鏈?zhǔn)降亩啻问褂煤陀梅ㄏ嗤堑脑貢?huì)始終渲染并保存在中,只是改變值。用法如下對(duì)應(yīng)前面的數(shù)據(jù) 在我一生的黃金時(shí)代,我有好多奢望。我想愛(ài),想吃,還想在一瞬間變成天上半明半暗的云。 ——王小波上一章研究了vue中組件的通信,算是對(duì)vue的組件通信有了大致的了解。綜合上三章對(duì)搭建項(xiàng)...
摘要:用法如下注冊(cè)全局的指令注冊(cè)一個(gè)全局自定義指令當(dāng)綁定元素插入到中。具體代碼如下當(dāng)組件中需要用到其他的組件時(shí),需要使用屬性去創(chuàng)建一個(gè)哈希表。具體用法如下包含組件引入組件在中添加組件的哈希表收尾除了上面這些屬性,還有一些雜項(xiàng)詳情請(qǐng)看官網(wǎng) 后來(lái)我才知道,生活就是個(gè)緩慢受錘的過(guò)程,人一天天老下去,奢望也一天天消失,最后變得像挨了錘的牛一樣。 ...
摘要:借我殺死庸碌的情懷,借我縱容的悲愴與哭喊謝知非上一節(jié)已經(jīng)把架子搭好了,接下來(lái)就要開(kāi)始真正的使用進(jìn)行開(kāi)發(fā)了。一啟動(dòng)原理打開(kāi)我們的目錄,能看到這樣的結(jié)構(gòu)很簡(jiǎn)單有木有,存放資源。一個(gè)字符串模板作為實(shí)例的標(biāo)識(shí)使用。模板將會(huì)替換掛載的元素。 借我殺死庸碌的情懷,借我縱容的悲愴與哭喊 - 謝知非 上一節(jié)已經(jīng)把架子搭好了,接下來(lái)就要開(kāi)始真正的使用vue2.0進(jìn)行開(kāi)...
摘要:先看看兼容性創(chuàng)建連接構(gòu)造函數(shù)接收兩個(gè)參數(shù)這里的不能是或者而是對(duì)應(yīng)的或者和是定義的兩種方案,類似于類似于協(xié)議名稱,是可選的。服務(wù)端和客戶端的協(xié)議名稱必須一致。協(xié)議有三種注冊(cè)協(xié)議,開(kāi)放協(xié)議,自定義協(xié)議。限制以內(nèi)就是在構(gòu)造函數(shù)中選傳的參數(shù)。 愿天下所有的情侶,都是失散多年的兄妹 ——好妹妹webScoket是html5提出的一個(gè)協(xié)議,咱們用的http是無(wú)狀態(tài)...
摘要:主要表現(xiàn)在復(fù)雜的語(yǔ)句事務(wù)支持等。僅支持,在等瀏覽器中,會(huì)出現(xiàn)樣式布局混亂的情況。將群群對(duì)應(yīng)的聊天記錄保存在數(shù)據(jù)庫(kù)。用戶進(jìn)入群聊,則將其加入到對(duì)應(yīng)的中。文件大小不能超過(guò)通過(guò)模塊操作登錄注冊(cè)將用戶名作為唯一值。登錄支持自動(dòng)登錄,將密碼保存在中。 showImg(https://segmentfault.com/img/bV4jYr?w=402&h=710);showImg(https://...
閱讀 2967·2021-11-25 09:43
閱讀 3633·2021-08-31 09:41
閱讀 1237·2019-08-30 15:56
閱讀 2119·2019-08-30 15:55
閱讀 2993·2019-08-30 13:48
閱讀 2816·2019-08-29 15:15
閱讀 984·2019-08-29 15:14
閱讀 2657·2019-08-28 18:26