iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 11
0
Modern Web

實作小範例入門 Vue & Vuex 2.0系列 第 11

vue & vuex 11 - 計數器 - I (vuex 職權與流程說明)

  • 分享至 

  • xImage
  •  

今天目標:

  1. 使用者需要一個計數器預設值是 0
  2. 有一個 + 的按鈕,按下時會幫我把現在的數值 +1
  3. 有一個 - 的按鈕,按下時會幫我把現在的數值 -1

如果我們單純使用 Vue 來實作這個功能,範例如下:

<template>
  <div class="container">
    <h2>count:<span class="count"> {{ count }}</span></h2>
    <button @click="increase"> + </button>
    <button @click="decrease"> - </button>
  </div>
</template>

<script>
export default {
  data () {
    return {
      count: 0,
    }
  },
  methods: {
    increase () {
      this.count += 1;
    },
    decrease () {
      this.count -= 1;
    },
  }
}
</script>

<style>
  .count {
    color: red;
  }
</style>

超簡單的,今天到這裡,收工。 :D


套用 vuex 框架:

資料結構:

我們要在 src 下,新增一個 store 的資料夾,裡面分別有 5 隻 .js 檔案。

├─src
│  ├─components
│  ├─pages
│  └─store
│     ├─actions.js
│     ├─getter.js
│     ├─index.js
│     ├─mutations.js
│     └─mutations_type.js

檔案職權

檔案 實作 vuex 與負責職權
action.js 存放 action 函式
getter.js 存放 getter 函式,只負責取 state 供元件使用
index.js vuex init (形同 vuex 的 main.js)
mutations.js 存放 statemutation 函式
mutations_type.js 存放 mutation key

還記得嗎?一切都是從 action 開始的!

actions.js

import Vue from 'vue'
import mutations from './mutations'
// 引入 mutations_type (引用同一個 key)
import * as types from './mutations_type.js'

export const actionIncrease = ({ commit }) => {
  console.log('actionIncrease');
  commit(types.INCREASE);
}

export const actionDecrease = ({ commit }) => {
  console.log('actionDecrease');
  commit(types.DECREASE);
}

mutations_type.js

export const INCREASE = 'INCREASE';
export const DECREASE = 'DECREASE';

圖解 mutations_type:

vue mutations type

mutations_type 雖然是非必要的檔案,主要作為 action 與 mutation 中間溝通的對應表,這隻檔案的存在,是當系統成長到一定的程度,防止 mutation key 重複,造成不可預期情況發生,也有防呆作用 。


mutations.js (mutation & state)

import * as types from './mutations_type.js'
import Vue from 'vue'

// state
export const state = {
  count: 0
}

// mutations
export const mutations = {
  // action 發出 commit 會對應到 mutation 使用的是 Object key 方式
  [types.INCREASE] (state) {
    // 在 mutation 改變 state(只有 mutation 可以改變!)
    state.count += 1;
  },
  [types.DECREASE] (state) {
    state.count -= 1;
  },
}

getter.js

export const getCount = state => { return state.count }

getter 很單純,只需要設計函式返回需要的 state
設計不同函式,就可以拿到不同資料型態的 state


index.js(檔案名不可改)

import Vue from 'vue'
import Vuex from 'vuex'
import { state, mutations } from './mutations.js'
import * as getters from './getters.js'
import * as actions from './actions.js'

Vue.use( Vuex );


export default new Vuex.Store({
  state,
  mutations,
  getters,
  actions,

  // 嚴格模式,禁止直接修改 state
  strict: true
});

指揮挺組合的概念。


main.js

// 引入 store 資料夾(上面五隻 js )
// 預設會去找 index.js  如果沒有的話會報錯!
// 我們在上一個範例已經組合所有指揮挺了!!
import store from './store'

( 中間略.. )

new Vue({
  el: '#app',
  router,

  // 加入 store
  store,

  render: h => h( App )
});

count.vue

<template>
  <div class="container">
    <h2>count:<span class="count"> {{ count }}</span></h2>
    <button @click="actionIncrease"> + </button>
    <button @click="actionDecrease"> - </button>
  </div>
</template>

<script>
// 引用 vuex
// mapActions 在 computed 中使用,提取 action 函式的方法,使用函式名稱
// mapGetters 在 methods 中使用,提取 getter 函式的方法,可以利用物件 key: value 方式取別名
import { mapGetters, mapActions } from 'vuex'

export default {
  computed: {
    // ...mapGetters 為 ES7 寫法
    ...mapGetters({
      // getCount return value 將會存在別名為 count 的 data 上
      count: 'getCount',
    }),
  },
  methods: {
    ...mapActions([
      'actionIncrease',
      'actionDecrease',
    ]),
    // 其他 method call action 的方法
    callAction() {
      // example
      this.actionIncrease;
    }
  },
}
</script>

vuex 學習心得:

一開始會比較難掌握整個流程,而且一開始學習 example 都是用看的,很難真的理解這樣的流程有什麼好處..。

  • 利用最簡單的範例,跑幾次流程會比較有印象。
  • 個人會使用 console.log 去測試 action 有無觸發?或者 log 資料是否正確?這樣的測試對流程了解很有幫助。(當然可以使用 devtool..)

github 完整範例:

實作小範例入門 Vue & Vuex 2.0 - github 完整範例

使用 git checkout 切換每天範例。


上一篇
vue & vuex 10 - 什麼是 vuex?
下一篇
vue & vuex 12 - 計數器 - II (action, mutation 傳遞資料)
系列文
實作小範例入門 Vue & Vuex 2.030
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Tsai-jimmy
iT邦新手 5 級 ‧ 2017-03-03 18:21:44

不好意思想詢問
Q:在actions.js裡面為什麼要import mutations from './mutations'?
我看似乎在這支js檔裡面不會用到mutations,甚至是不是少打.js

Jacky iT邦新手 5 級 ‧ 2017-03-03 18:26:02 檢舉

hi,

中間有一張圖 圖解 mutations_type 看一下滿清楚的

mutations_type 非必要檔案,主要用來 reference 同一個 String

避免打錯字,系統長大的時候避免命名重複,好管理

hi Jacky 是不是我誤會了什麼
我想問的是action.js 裡的第二行
那關於mutations_type你講得很清楚喔!沒有疑慮!謝謝你

0
garrodran99
iT邦新手 5 級 ‧ 2017-10-20 15:00:57

檔名 getter.js 應該是有s 的, 應該是 getters.js

Jacky iT邦新手 5 級 ‧ 2017-10-20 15:10:49 檢舉

hi garrodran99,
感謝勘誤,目前 ithelp 文章不能編輯,晚點在試試看,謝謝。

我要留言

立即登入留言