首先, 咱們一般說數據傳遞, 組件通訊什麼什麼的, 我認爲能夠分紅兩種場景:javascript
頁面和頁面之間vue
組件和組件之間java
無論什麼場景, 在使用 Vue 的時候, 通常咱們有下面 5 種選擇去實現數據通訊.vuex
vuex緩存
storagesession
props函數
eventthis
URL queryStringurl
咱們在選擇通訊方案的時候, 好比說肯定 列表頁如何把每一項的 id 傳遞給 詳情頁的時候,
通常要考慮什麼問題? 你是直接全套都是 vuex, 仍是說喜歡使用 sessionStorage?code
通常咱們要考慮下面的幾個問題:
頁面是否能夠刷新
頁面是否能夠分享 (或者說URL 是否要求 RESTful)
數據更新以後, 全部使用此數據的組件是否都須要響應更新
先說 '頁面和頁面之間的通訊場景', 首先上面的 5 種方案, 咱們可選的有:
vuex, storage, URL queryString.
而後分析一下, 每一種方案, 它對上面的 3個問題, 是否是很好的解決掉了:
備註:
頁面通訊場景不會要求實時響應, 由於就算下個頁面的確是實時響應, 你也看不見,
因此主要看 '刷新' 和 '分享'
vuex: 不能刷新, 不能分享
storage: 不能分享
url: 能刷新, 能分享
這樣看來, url queryString 的方式是 '頁面通訊場景' 中的最佳選擇, 可是我依舊有疑慮:
我始終以爲把跳轉信息, 暴露給用戶, 是很很差的事情; (心理問題, 能夠克服)
url 的長度限制; 這個無所謂的, 2k, 你再怎麼傳遞, 我都不會以爲你會出現超過 2k 的狀況
url 須要拼接, 這個拼接是否麻煩? 也不麻煩, 只是對象轉字符串.
這樣每一個頁面都須要在進入的時候先解析一下 queryString, 這樣是否是增長了麻煩的程度
也能夠經過 mixins 來操做. 聚合到 mixins, 何況也不必定不少.
因此咱們能夠選擇 'url queryString' 做爲 '頁面和頁面通訊場景' 中的通訊方案.
之後你就能夠這樣用了:
好比列表頁面跳轉到詳情頁要帶一個 id
this.$router.push({ path: 'detail', query: { id } })
你的 url 會始終長這樣:
https://abc.com/#/?id=123
備註: 若是你的頁面不能刷新和分享, 你徹底能夠三種方案隨便選, 愛誰誰.
重點: url queryString 的方式, 有一個問題解決不了:
從詳情頁到訂單頁, 經過 queryString 帶了商品信息過來, 假設此時 url 長這樣: order/?goods=xxx 訂單頁面有一個收貨地址欄, 點擊能夠進入地址編輯頁面, 此時的 url 不會帶參數的(你能夠試試帶一下看多麻煩) address-edit/ 地址編輯頁面有一個保存按鈕, 點擊會返回到訂單頁面 order/
so, url queryString 丟了.
我目前的解決方案:
針對這種存在多入口的頁面, 必定要在進入它的第一時間, 先把 queryString 存起來.
而且作以下判斷:
if (// 存在 queryString) { // use queryString } else { // use storage }
可是這種方式仍是搞不定 從地址編輯頁返回到訂單頁, 用戶此時分享訂單頁, 分享出去的玩意確定會是錯的.
如今來講下 '組件和組件之間的通訊場景'
上面的 5 種方案, 能夠選擇 vuex, event, props, storage
先看下 刷新, 分享和實時響應
vuex, 不能刷新
event, props 能刷新能分享
storage 不能分享 & 實時.
解釋:
爲何 vuex 在這裏仍是不能刷新
由於若是使用的 state 裏面的值是其餘頁面設置的而不是 init 就存在的, 刷新丟值.
爲何 event, props 能夠作到防刷新防分享
由於這兩個玩意是程序運行它就生效的, 它也能夠作到實時更新.
storage 雖然在存的時候有一個事件, 可是這太 trick 了.
因此咱們選擇的是 event, props?
分析一下吧.
組件通訊能夠分紅兩種, 父子, 同輩.
父子之間呢:
父傳子: props
子傳父: $emit(event)
這就是 'props down, events up';
可是其實還有:
父傳子: this.$refs.xxx
子傳父: this.$parent.xxx
還有: 自定義 v-model
還有: 讓 props 是一個對象.
同輩之間: event-bus.
因此這就完了? 啥都沒有了? 嗯, 就這樣.
關於 vuex 的應用場景的考慮
不是應該全部的組件, 路由之間的數據傳遞都應該經過 vuex, 當同時存在兩種方式能夠選擇的時候,選擇 vuex 的惟一理由只有一個:
須要響應式的狀態
why?
由於 vuex 雖然有輔助函數, 可是用起來仍是要 引入, 定義. 並且真的是一刷新頁面就掛了.
能夠經過監聽 beforeunload 事件, 在其中緩存 state, 而後在 onload 事件再恢復, 這樣能夠避免掉vuex 的丟值.
沒有必要追求全項目統一的一種通訊方式, 理論上你不考慮刷新分享, 全項目都用 vuex, 什麼事情也不會有的.
vuex 是狀態管理, 不是保存常量的地方.