zoukankan      html  css  js  c++  java
  • vuex基本熟悉与使用

    vuex的入门与使用讲解

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

    定义:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

    使用场景?

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

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

    state: 状态的集中管理中心,本质上他就是一个对象,我们在里面定义了很多数据,使用的时候在组件的计算属性中将这个对象交给vue进行管理,实现数据的事实响应.....

    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,类似于事件

    mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:

    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')`
        ]),

    值得注意的是:官方规定mutation 必须是同步函数,如果在mutation中存在异步回调函数中修改state值,那么状态的改变是不可追踪的 ,很难调试....... 因此我们需要一个集中处理异步操作的地方Action

    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})
       },
       addCount () {
          this.$store.commit('a/increment')
       }   
    

    表单处理:使用带有 setter 的双向绑定计算属性

    严格模式中使用 Vuex 时,在属于 Vuex 的 state 上使用 v-model 会比较棘手,但是也不是不可能。。。

    html:

    <input type="text"  v-model="phone" />

    计算属性: 

      computed: {
        phone: {
          get () {
            return this.$store.state.a.phone
          },
          set (val) {
            this.$store.commit('a/updatePhone', {phone: val}) // module a
          }
        },

    store.js

    mutations: {
        updatePhone (state, payload) {
          state.phone = payload.phone
        }
  • 相关阅读:
    samtools获取uniq reads
    NSDate的比较
    UIViewAlertForUnsatisfiableConstraints布局问题
    如何将网页保存为pdf
    使用Carthage管理iOS依赖库
    输出格式
    解决问题思路
    重:将好用的控件,上次github,
    解决CocoaPods慢的小技巧
    swift开发笔记28 CoreML
  • 原文地址:https://www.cnblogs.com/evaling/p/10196406.html
Copyright © 2011-2022 走看看