vuex的入门与使用讲解

官网:https://vuex.vuejs.org/zh/guide/state.html

使用场景?

如果我们在项目中有很多状态需要管理,但是storage,cookie等一些常见的存储技术不足以管理的时候,这个时候你需要考虑是需要引进vuex了

几个重要概念: State, Mutation,Getter, Mutation, Action, Module

state: 状态的集中管理中心

1)简单例子

 computed: {
   count () {
      return this.$store.state.count
   },
   age () {
       return this.$store.state.age
   },
   name () {
       return this.$store.state.name
   }
 }

2)mapSate: 状态太多,每一个申明很麻烦(例如上面),于是可以使用mapSate做处理,可以是数组,对象的形式

  computed: {
    ...mapState({
      count: 'count',
      name (state) {
        return state.name.toUpperCase()
      },
      age: 'age'
    })
  },
  // 或者
  computed: {
    ...mapState([
      'count',
      'name',
      'age'
    ])
  },
getter: 对state的统一处理,不需要每个组件中单独进行处理【em: 对state中的每个状态进行过滤的操作】,类似一种公共函数。

em:在state 中有一个状态为name:‘tom jackson’,默认小写字母

现在的要求是在每个组件的中展示的时候都name变成大写的字母,方法有很多种(过滤器等其他方式),可以在每个组件中进行单独处理,如下:

 computed: {
    ...mapState({
      count: 'count',
      name (state) {
        return state.name.toUpperCase(); //每个组件内部的自行处理
      }
    })
  },

但是这里是使用getter进行操作怎么做呢?

1)首先在store中定义一个getters对象,进行需求处理

new Vuex.Store({
   state: {
    count:0,
    name:'tomJack',
    age:32,
    phone: 13712553098
  },
 ..........
 ..........
  getters: { // 类似于一种被抽离出去的fun
    upperName: state => {
      return  typeof (state.name) === 'string' ? state.name.toUpperCase() : '非字符串'
    }
  },
})
​

2)mapGetters: 在使用组件中computed属性中,使用如下(mapGetters也可以是array, object形式)

  computed: {
    ...mapState({
      count: 'count',
      name () {
        return this.$store.getters.upperName
      }
    })
  },
  // 或者直接使用getters
  computed: { // getters是state 的补充
    ...mapGetters({
      name: ‘upperName’
    })
  },

截止目前为止以上都只是从store中被动的获取状态数据,还没尝试过组件内部修改store中的状态。

值得注意的是在vuex中是不允许直接修改store的状态值,例如一下操作是不被接受的

methods:{
    increment () {
        this.$store.state.age ++
    }
}

我们须要提交mutation的方式进行修改操作。

mutation: 更改 Vuex 的 store 中的状态的唯一方法是提交 mutation,类似于事件

1)在组件内部通过调用方法的形式this.$store.commit('xxx'),commit一个mutation 去触发handler

组件内部代码:

 <button @click="addCount">增加count</button>
 methods: {
    addCount () {
      this.$store.commit('increment',{n:2})
    }
  }

store.js

export default new Vuex.Store({
  state: {
    count:0,
  },
  mutations: {
    increment (state, payload) {
      state.count += payload.n
    }
  }

2)使用mapMutations辅助函数映射store.commit

组件内部:

   <button @click="increment">减少count</button>
   methods: {
    ...mapMutations([
      'increment' // 将 `this.increment()` 映射为 `this.$store.commit('increment')`
    ]),
Action: 类似于 mutation

不同点:

  • Action 提交的是 mutation,而不是直接变更状态。

  • Action 可以包含任意异步操作。

举出一个简单例子:通过 store.dispatch 方法触发一个action

store.js

actions: {
    decrementAsync ({ commit},{amount}) { // 与 store 实例具有相同方法和属性的 context 对象
      setTimeout(() => {
         commit('decrement',{amount}) // mutation
      },2000)
      commit('decrement')
    }
}
mutations: {
    decrement (state, payload) {
        state.count -= (payload && payload.amount? payload.amount: 1);
    }
}

组件中的函数:

html: <button @click="decActionCount">减少count</button>
js: methods: {
       decActionCount () {
         this.$store.dispatch('decrementAsync',{amount:10})
       }
    }

使用 mapActions 辅助函数将组件的 methods 映射为 store.dispatch 调用

 methods: {
    ...mapActions([
      'decrementAsync'
    ]),
    decrementAsynce () {
      this.decrementAsync({amount:20})
    },

目前为止基本上你已经掌握了vuex的基本使用方法。

思考一个问题,有的时候我们的状态会很多,多到我们想分模块进行处理,这个时候我们就需要用到Module????

 

Module:将 store 分割成模块(module),每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。

store.js

const moduleA = {
  namespaced: true,
  state : {
    count:0,
    name:'tomJack',
    age:32,
    phone: 13712553098
  },
  mutations: {
    increment (state) {
      state.count++
    },
    decrement (state, payload) {
      state.count -= (payload && payload.amount? payload.amount: 1);
    }
  }
}
export default new Vuex.Store({
  modules: {
    a: moduleA
  }
})
​

组件内部使用:

 computed: {
    ...mapState('a' ,[// 带上模块名,如果是嵌套的则要嵌套表明 a/b/c
      'count',
      'name',
      'age',
      'upperName'
    ]),
    ...mapGetters('a',{ // 带上模块名,如果是嵌套的则要嵌套表明 a/b/c
      name: 'upperName'
    })
  },
  methods: {
   ...mapMutations('a',[ // 带上模块名,如果是嵌套的则要嵌套表明 a/b/c
     'increment'
   ]),
   ...mapActions('a',[ // 带上模块名,如果是嵌套的则要嵌套表明 a/b/c
     'decrementAsync'
   ]),
   decrementAsynce () {
        this.decrementAsync({amount:20})
   },
[参看文章​]  https://www.jb51.net/article/150673.htm 
12-29 22:40