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