Vuex從入門到實戰(二)

由于多個狀態分散的跨越在許多組件和交互間各個角落,大型應用復雜度也經常逐漸增長。為了解決這個問題,Vue 提供 vuex:我們有受到 Elm 啟發的狀態管理庫。vuex 甚至集成到 vue-devtools,無需配置即可訪問時光旅行。

前言

如果你對vuex狀態管理還不是很了解的話,請先閱讀

Vuex從入門到實戰(一)

在本篇,我將演示如何使用

來完成一個 小型demo的制作(點擊按鈕,計數器自增)。

環境搭建

vue-cli & webpack

在任意目錄下打開控制臺, 輸入

vue init webpack counter
image

中間的項目可以隨便填選,但最后一項是否自動安裝依賴一定要選 No

cnpm

npm 依賴有一些是國外的,安裝比較慢還容易出錯誤.

命令行輸入 :

npm install cnpm -g --registry=https://registry.npm.taobao.org

安裝國內淘寶鏡像源的cnpm.

使用cnpm 安裝項目依賴 :

cnpm install

安裝Vuex :

cnpm i vuex -S

啟動項目服務 :

npm start

項目開發

目錄結構

image

源代碼

1. 建立store, 存放在store.js

import Vue from 'vue'
import Vuex from 'vuex'

// Vue 引入Vue插件方式
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    counter: 0
  },
  getters: {
    counter: state => state.counter
  },
  mutations: {
    addCounter (state) {
      state.counter ++
    }
  }
})

2. 修改webpack的入口文件 main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
import router from './router'
// 引入建立好的 store
import store from './store'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  router,
// 綁定到 Vue 實例上
  store,
  template: '<App/>',
  components: { App }
})

將store綁定到Vue實例上之后,可以在每個組件中 使用 this.$store 進行操作.

3. 建立 計數器 組件 Counter.vue

<template>
  <div>
    <h1>counter: {{counter}}</h1>
    <button @click="addCounter">add counter</button>
  </div>
</template>

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

  export default {
    name: 'Counter',
    computed: mapGetters([
      'counter'
    ]),
    methods: mapMutations([
      'addCounter'
    ])
  }
</script>

當然, Vuex 提供了 一種 十分友好的方式讓組件引用store 中的屬性和方法 :

  • getters 對應 mapGetters
  • mutations 對應 mapMutations
  • actions 對應mapActions

使用方式 :

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

  export default {
    name: 'Counter',
    computed: mapGetters([
      'counter'
    ]),
    methods: mapMutations([
      'addCounter'
    ])
  }
</script>

或者

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

  export default {
    name: 'Counter',
    computed: mapGetters({
      counter: 'counter'
    }),
    methods: mapMutations({
      addCounter: 'addCounter'
    })
  }
</script>

如果methods和computed中 存在組件的私有屬性和方法, 那么可以使用 ES6 對象展開運算符

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

  export default {
    name: 'Counter',
    computed: {
      ...mapGetters([
        'counter'
      ]),
      selfProperty () {
        return 'self property'
      }
    },
    methods: {
      ...mapMutations([
        'addCounter'
      ]),
      selfMethod () {
        return 'self method'
      }
    }
  }
</script>

4. 在 根組件 上掛載 Counter, App.vue

<template>
  <div id="app">
    <counter></counter>
  </div>
</template>

<script>
  import Counter from './components/Counter.vue'
  export default {
    name: 'app',
    components: {
      Counter
    }
  }
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

運行結果

image
image

最后

本節源碼 :

https://github.com/lonelydawn/counter

下一節我們將探討一個更復雜的案例, 實戰用戶需求

Vuex從入門到精通(三)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容