浅谈Vuex

194 阅读2分钟

一. 基本概念

1. 参数概念
state       -- 数据仓库 
getter      -- 用来修饰数据 
Mutation    -- 用来是修改数据(同步方法)
Action      -- 用来提交异步提交Mutation
2. vuex主要用途
多个组件共享参数,同步变化

二. 准备工作

1. store.js
    import Vue from 'vue'
    import Vuex from 'vuex' 
    Vue.use(Vuex) 
    
    const store = new Vuex.Store({
        // 存储基本数据
        state: {
            age: 10,
            name: ‘lz’  
        },
        
        // 修改数据(同步)
        mutations: {
            setAge (state) { // vuex 中数据刷新会消失存储于localStorage中
                state.age++
                 window.localStorage.setItem('age', JSON.stringify(state.age))
            },
            setName(state, payload) {
                state.name = payload
            }
        },
        // 修饰数据
        getters: {
            getAge: state => {  // vuex 中数据刷新会消失存储于localStorage中
           
                let age = state.age
                if (!age) {
                    age = JSON.parse(window.localStorage.getItem('age') || null)
                }
                return age
            }
        },
        // 异步处理数据
        actions: {
            
        }
    }) 
    
    export default store
    
2. main.js挂载
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'  // 引用store.js

Vue.config.productionTip = false

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

三. State

1. 直接获取state中的数据
    this.$store.state.age
    this.$store.state.name
2. 在computed中获取state中的数据
    1. 第一种获取方法
    export default {
        computed: {
            ages() {
              return this.$store.state.age
            },
            name() {
              return this.$store.state.name  
            }
        }
    }
        
    2. 通过mapState方法获取
        import { mapState } from 'vuex'
        export default {
            computed: {
                ...mapState([ 'age', 'name' ])
            }
        }
        

四. Mutation(必须是同步函数)

当我们需要修改state中的值时,最好不要直接修改,而是通过store.js中的mutations中的方法修改
注意:修改时使用commit方法(第一个参数为修改方法,第二个参数为想要赋值的值)


    <template>
        <div>
          <button @click="getAge">更改age</button>
          <button @click="getName">更改name</button>
        </div>
    </template>
    export default {
        name: 'index',
        data() {
            return {
                
            }
        },
        methods: {
            getAge() {
                this.$store.commit('setAge')
            },
            getName() {
                this.$store.commit('setName', 'my name is lz')
            }
        }
    }

五. Getter

1. 定义
state中的数据进行过滤
2. 设置getters
export default new Vuex.Store({
  state: {
    list: [1, 2, 3, 4, 5, 6, 7, 8]
  },
  getters: {
    modifyArr(state) { // 获取state中list数组中的偶数
      return state.list.filter((item, index, arr) => {
        return item % 2 == 0;
      })
    },
    getLength(state, getter) { // 方法里面传getter,调用modifyArr来计算长度
      return getter.modifyArr.length;
    }
});
3. 调用getters中的方法
1. 第一种调用方法

computed: {
    list() {
      return this.$store.getters.modifyArr;
    },
}

2. 第二种调用方法(mapGetters)
import {mapGetters} from 'vuex';
computed: {
  ...mapGetter(['modifyArr', 'getLength'])
}
调用model中的getters方法(modelA中的方法)
computed: {
  ...mapGetter('A', {
      modifyArr: 'modifyArr',
      getLength: 'getLength'
  })
}

六. Action(异步操作)

1. 定义
Action 类似于 mutation,不同在于:
    Action 提交的是 mutation,而不是直接变更状态。
    Action 可以包含任意异步操作。
    Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters。
2. 注册一个简单的action
const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state) {
      state.count++
    }
  },
  actions: {
    increment (context) {
      context.commit('increment')
    }
  }
})
3. 页面调用
1. 第一种调用

this.$store.dispatch('increment')

2. 第二种调用

import { mapActions } from 'vuex'

export default {
  // ...
  methods: {
    ...mapActions([
      'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
      // `mapActions` 也支持载荷:
      'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
    ]),
    ...mapActions({
      add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
    })
  }
}

七. Module

1. 为什么使用module
Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:
2. 如何定义module
const moduleA = {
  state: {
      age: '',
      name: ''
  },
  mutations: {
  	setAge(state, data) {
        state.age = data
    }
  },
  actions: { ... },
  getters: { ... }
}

const moduleB = {
  state: {
      age: '',
      name: ''
  },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})
3. 如何获取特定module中state的值
1. 第一种方法
store.state.a // -> moduleA 的状态
store.state.b // -> moduleB 的状态
2. 第二种方法
computed: {
    ...mapState({
      age:state => state.a.age
    })
}

页面获取age
this.age

4. 如何获取特定module中mutation里面的方法,getters和actions同理

获取moduleA中的setAge方法
import { mapMutations } from 'vuex';
export default {
    data() {
        return {}
    },
    mounted() {
        this.setAgeMethod(10)
    },
    methods: {
      ...mapMutations({
          setAge: 'a/setAge'   //  module名称/方法名称
      }),
      setAgeMethod(val) {  // 给age赋值
          this.setAge(val)
      }
    }
}