Vuex 狀態管理實踐城市選擇頁

Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue

狀態管理模式 vuex

一個狀態自管理應用包含如下幾個部分:

state,驅動應用的數據源;bash

view,以聲明方式將 state 映射到視圖;ui

actions,響應在 view 上的用戶輸入致使的狀態變化。this

當咱們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:spa

多個視圖依賴於同一狀態。code

不一樣視圖須要變動同一狀態。component

因此狀態管理模式就是把共享的狀態提取出來,在一個全局的地方進行統一管理。無論組件在哪,都能觸發行爲、獲取狀態,提升了代碼維護性。cdn

原理簡單理解 對象

Vuex 實現了一個單向數據流,全局管理 state 狀態樹,組件經過派發 Dispatch 一個 action,action 也是沒法直接修改State的,仍是須要經過 Mutation來修改State的數據。action 進行 commit 並調用 Mutations 方法來更改 state,Mutation同時提供了訂閱者模式供組件調用獲取State數據的更新。最後根據 state 的變化觸發視圖的更新。

Vue Components:Vue組件。

dispatch:是惟一能執行action的方法。

actions:由組件 dispatch 觸發。而後由commit()來觸發mutation的調用 , 更新 state。

commit:狀態改變提交操做方法。對mutation進行提交,是惟一能執行mutation的方法。

mutations:狀態改變操做方法,由actions中的commit('mutation 名稱')來觸發。該方法只能進行同步操做,且方法名只能全局惟一。

state:頁面狀態管理容器對象。

實踐 - 城市選擇

實現一個常見的城市選擇頁面。包含首頁和城市選擇頁。

新建一個 IndexPage.vue

// IndexPage.vue
 
<template>
  <div>{{city}}</div>
</template>

<script>
  import { mapState} from 'vuex'

  export default {
    name: "IndexPage",
    computed: {
      ...mapState(['city'])
    }
  }
</script>
複製代碼

新建一個 CityPage.vue

// CityPage.vue

<template>
<div>
  <p>當前城市:{{city}}</p>
  <div v-for="item of ['北京','上海','廣州']" :key="item">
    <button @click="handleChangeCity(item)"
    >{{item}}
    </button>
  </div>
</div>
</template>

<script>
  import { mapState ,mapMutations  } from 'vuex'

  export default {
    name: "CityPage",
    computed: {
      ...mapState(['city'])
    },
    methods: {
      ...mapMutations(['changeCity']),
      handleChangeCity (city) {
        this.changeCity(city)
      },
    },
  }
</script>
複製代碼

在 App.vue 中加入這兩個頁面。

//  App.vue

<template>
  <div>
    <IndexPage/>
    -----------
    <CityPage/>
  </div>
</template>

<script>
import IndexPage from './pages/IndexPage'
import CityPage from './pages/CityPage'

export default {
  name: 'App',
  components: {
    IndexPage,
    CityPage
  }
}
</script>
複製代碼

接下來重點來了,src 裏 新建一個 store 文件夾 (若是使用腳手架搭建的就已經有這個文件夾了)。

store 文件夾下新建一個 index.js ,別忘了注入到 main.js。

//  index.js

import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'

Vue.use(Vuex)

export default new Vuex.Store({
  state,
  actions,
  mutations
})
複製代碼

新建一個 state.js

//  state.js

let defaultCity = '全國'

try {
  if (localStorage.city) {
    defaultCity = localStorage.city
  }
} catch (e) {
}

export default {
  city: defaultCity
}
複製代碼

新建一個 actions.js

// actions.js

export default {
  changeCity (context, city) {
    context.commit('changeCity', city)
  }
}
複製代碼

新建一個 mutations.js

// mutations.js

export default {
  changeCity (state, city) {
    state.city = city
    try {
      localStorage.city = city
    } catch (e) {
    }
  }
}
複製代碼

完成後以下圖所示。選擇新的城市,首頁和城市選擇頁裏的 city 會同步更新。

相關文章
相關標籤/搜索