天天看點

你真的會用vuex嗎?

不得不說,vuex真實一個非常好用的庫,在vue中起着舉足輕重的作用,那麼,vuex的作用是什麼呢?作為一個新手,我們關心的是在什麼樣的場景下,應該請出vuex這個大殺器。

vuex的作用

當然,我這裡肯定不會給你講官話,我将的隻可能是基于實踐中自己的感受,vuex實際上就是多頁面共享資料倉庫。是的,這就是我的vuex的了解,在我們開發也許需求的時候,不可避免的我們需要在多頁面之間共享一些資料,比如使用者基本資訊,比如,省份城市清單等等,活在在舉出一個例子,比如電商網站,使用者的購物車資料,是的,這些資料都是要在所有頁面中能個随時拿随時取的。好,我們不免有一個問題要問,難道我們就非得要使用vuex嗎?

非得需要使用vuex來共享資料

這個答案明顯是不一定的,官方也有着其建議,比較小的項目,本身的業務邏輯也不是很複雜,也不存在居多頁面之間的互動,邏輯在怎麼亂也亂不到哪裡,是以是沒有比較引入vuex的,一個簡單的 store 模式就足夠您所需了,嗯,沒錯,實際上隻有中大型項目才有引入vuex的必要,是以說,引入vuex的另外一個不可忽視的原因是,代碼解耦,扪心自問,頁面的邏輯已經比較複雜了,有自己的資料,有跳轉,有那麼多的methods,computes,等等,已經受夠了,還要去維護一個全局資料的管理,還要擔心髒資料,真實受夠了,這些交給一個專業的全局資料管理者多好呢?嗯,vuex就是你需要的這個管理者。

vuex三問

  1. vuex資料存在什麼地方
  2. vuxe資料怎麼修改
  3. vuex是誰的

要弄懂這三個問題,我們直接就看一個vuex的執行個體就好了

Vue.use(vuex);
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})           

複制

是以,直覺的講,資料是存在,state裡面的,操作資料在什麼地方,答案是放在actions中,具體到了業務怎麼觸發,則是使用dispatch,比如

state.dispath('increment')

,然而,那麼mutations是幹嘛的,呵呵,我也是覺得脫褲子放屁,多此一舉,如果你和我們一樣這麼認為,很不幸,我們都了解錯了,事實上,隻有通過mutations裡面的方法去修改state中存儲的資料,這些資料的變化才可以被追蹤。

改變 store 中的狀态的唯一途徑就是顯式地**送出 (commit) mutation**。這樣使得我們可以友善地跟蹤每一個狀态的變化,進而讓我們能夠實作一些工具幫助我們更好地了解我們的應用

這是官方原話,不按照這麼做,妄圖直接修改state中的變量,bug是一定會粗線的。

Action和mutation是很相似的,不同在于:

  • Action 送出的是 mutation,而不是直接變更狀态,這也就是以為這可以緩沖。
  • Action 可以包含任意異步操作,是以耗時操作可以網這裡丢。

第三問,這個倉庫是屬于誰的,這很重要,這就要看他如何挂載了。

export const vm = new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
});           

複制

事實上,vuex屬于這個vm執行個體這個執行個體的,是以,他存儲的資料的隻對目前這個vm負責,換句話說,你在起一個new Vue,不好意思,資料你拿不到,就好比程序隔離資料一樣,這也就是業界說的對于多頁面(開多個頁面)的vue是共享不到資料的。

你真的會用vuex嗎?

如圖,vue的這棵樹,可以了解app就是我們的vue執行個體,至于root是什麼,我目前也不清楚,然後其他下面的都是可以認為是component,然後,順理成章的來說,被這顆vue管理的這個vuex,被這棵樹自己所共享,無論是更節點,還是葉子節點都是一樣,能拿,能修改,router-view路由過去的也是如此,事實上你将其想成一個component即可。你router-view切換再多層次,千遍萬變,你會發下App雷打不動,是以vue也是雷打不動。

是以,有人就問啊,為什麼我的頁面重新整理一下,vuex存儲的資料都丢了

是以,明白了上面的三問,這都不是一個問題了,因為重新整理之後,vm會重新執行個體化,上一個vm的vuex中state怎麼可能被你拿到呢?是以,關鍵是怎麼辦呢?很簡單,使用sessionStorage來存儲一下state狀态,具體做法是:在App.vue中

<script>
  export default {
    name: 'App',
    methods: {
      store() {
        console.log('正在儲存store的狀态到sessionStorage')
        console.log(this.$store.state)
        sessionStorage.setItem("store", JSON.stringify(this.$store.state))
      }
    },
    created() {
      //在頁面加載時讀取sessionStorage裡的狀态資訊,解決浏覽器重新整理之後vuex資料丢失的問題,導緻需要重複請求網絡
      if (sessionStorage.getItem("store")) {
        this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem("store"))))
        console.log('正在從sessionStorage恢複store')
        console.log(this.$store.state)
      }

      //在頁面重新整理時将vuex裡的資訊儲存到sessionStorage裡
      window.addEventListener("beforeunload", this.store)
    },
    destroyed() {
      window.removeEventListener("beforeunload", this.store)
    }
  }
</script>           

複制

那麼,為什麼不用localStorage,這個還是留給讀者自己吧,别制作伸手黨,自己也要有點思考。