1. 程式人生 > 程式設計 >前端的狀態管理(上)

前端的狀態管理(上)

目錄
  • 1、什麼是前端狀態管理?
  • 2、x
  • 3、Bus 匯流排
  • 4、web storage

前言:

提到狀態管理大家可能馬上就想到:VuexReduxFluxMobx等等方案。其實不然,不論哪種方案只要內容一多起來似乎都是令人頭疼的問題,也許你有適合自己的解決方案又或者簡單的註釋和區分模組,今天來聊一聊前端的狀態管理,如果你有好的建議或問題歡迎在下方留言提出。

1、什麼是前端狀態管理?

舉個例子:圖書館裡所有人都可以隨意進書庫借書還書,如果人數不多,這種方式可以提高效率減少流程,一旦人數多起來就容易混亂,書的走向不明確,甚至丟失。所以需要一個圖書管理員來專門記錄借書的記錄,也就是你要委託圖書管理員給你借書及還書。

實際上,大多數狀態管理方案都是如上思想,通過管理員(比如 Vuex)去規範書庫裡書本的借還(專案中需要儲存的資料)

2、Vuex

在國內業務使用中 Vuex 的比例應該是最高的,Vuex 也是基於 Flux 思想的產品,Vuex 中的 state 是可以被修改的。原因和 Vue 的執行機制有關係,Vue 基於 ES5 中的 getter/setter 來實現檢視和資料的雙向繫結,因此 Vuex state 的變更可以通過 setter 通知到檢視中對應的指令來實現檢視更新。更改 Vuex store 中的狀態的唯一方法是提交 mutation我們以圖書館來作為例子:

const state = {
  book: 0
}

const mutations = {
  borrow_book(state) {
    state.book ++
  }
}

//呼叫時
store.commit('borrow_book')

那還有acthttp://www.cppcns.comion呢? 在 mutation 中混合非同步呼叫會導致你的程式很難除錯。你怎麼知道是哪個先執行完呢? aciton 可以包含任意非同步操作,用法跟上面基本類似,不再敘述。

其實我只是拿 Vuex 來淺入一下相關用法大家應該是都熟悉了,那 Vuex 解決了什麼問題呢?

  • 管理多個元件共享狀態。
  • 全域性狀態管理。
  • 狀態變更跟蹤。
  • 讓狀態管理形成一種規範,使程式碼結構更清晰。

實際上大部分程式設計師都比較懶(狗頭保命),只是為了能多個元件共享狀態,至於其他的都是事後了。最典型的就是加入購物車的數量,加入一個就通過 Vuex 記錄儲存最終的總數顯示在下欄。

那問題來了,既然你的目的只是共享多個狀態,那何不直接用 Bus 匯流排好了?

3、Bus 匯流排

Bus 匯流排實際上他是一個公共的 Vue 例項,專門處理 emit on 事件。

實際上 Bus 匯流排十分輕便,他並不存在 Dom 結構,他僅僅只是具有例項方法而已。

Vue.prototype.$Bus = new Vue()

然後,你可以通過 emit 來發送事件, on 來接收事件。

// 傳送事件
this.$Bus.$emit('borrow_book',1)

// 任意元件中接收
this.$Bus.$on('borrow_book',(book) => {
    console.log(`借了${book}本書`)
})

當然還有 off(移除)、once(監聽一次)等操作感興趣可以自行搜尋引擎。

怎麼樣?上面對於滿足共享一個狀態是不是比 Vuex 要簡單多了?實際上確實是簡單多了,但這也代表他比較適合中小型專案。多於大型專案來說 Bus 只會讓你追http://www.cppcns.com述更改源時一臉懵逼甚至你都不知道他在哪裡改變了。

他的工作原理就是釋出訂閱者的思想,雖然非常優雅簡單,但實際 Vue 並不提倡這種寫法,並在3.0版本中移除了大部分相關Api(emit、on等),其實不然,釋出訂閱模式我們可以自己手寫一個去實現:

class Bus {
 constructor() {
  // 收集訂閱資訊,排程中心
  this.list = {};
 }

 // 訂閱
 $on(name,fn) {
  this.list[name] = this.list[name] || [];
  this.list[name].push(fn);
 }

 // 釋出
 $emit(name,data) {
  if (this.list[name]) {
                    this.list[name].forEach((fn) => {
                        fn(data);
                    });
                }
 }

 // 取消訂閱
 $off(name) {
  if (this.list[name]) {
   delete this.list[name];
  }
 }
}
export default Bus;

簡單吧?你只需要跟用 Vue Bus 一樣去例項化然後用就可以了。什麼?你想共享兩三個甚至更少的狀態(一個),那封裝一個 Bus 是不是有點沒必要了? 行吧,那你用 web storage 吧。

4、web storage

其實說到這,storage只是資料儲存方式,跟狀態管理其實沒有太大關係,只是共享資料。但是既然都提到了那就順帶說一下(狗頭)

web storage 有這三種:cookielocal storagesession storage

無論這三種的哪種都強烈建議不要將敏感資訊放入其中,這裡應該是加密或一些不那麼重要的資料在裡面。

先簡單複習一下三者:

前端的狀態管理(上)

cookie 不必多說,大家發起請求時經常會攜帶cokie請求一些個人資料等,與我們要探討的內容沒有太大關係。

loaclStorage 可以儲存理論上永久有效的資料,如果你要儲存狀態一般推薦是放在 sessionStoragelocalStorage 也有以下侷限:

  • 瀏覽器的大小不統一,並XopUSZgEvc且在 IE8 以上的 IE 版本才支援 localStorage 這個屬性。
  • 目前所有的瀏覽器中都會把localStorage的值型別限定為string型別,這個在對我們日常比較常見的ON物件型別需要一些轉換。
  • localStorage在瀏覽器的隱私模式下面是不可讀取的。
  • localStorage本質上是對字串的讀取,如果儲存內容多的話會消耗記憶體空間,會導致頁面變卡。
  • localStorage不能被爬蟲抓取到。

localStorage sessionStorage 的唯一一點區別就是 localStorage 屬於永久性儲存,而 sessionStorage 屬於當會話結束的時候,sessionStorage 中的鍵值對會被清空。

localStorage 本身只支援字串形式儲存,所以你存整數型別,拿出來的會是字串型別。

sessionStorage localStorage 基本差不多,只是回話關閉時,資料就會清空。

總結:

不論哪種方案選擇合適自己專案的方案才是最佳實踐。沒有最好的方案,只有合適自己的方案。

到此這篇關於前端的狀態管理的文章就介紹到這了,更多相關前端的狀態管理內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!