vuex 通俗易懂

587 阅读3分钟

vuex是vue的一个状态管理工具,可以管理vue中的数据,可以解决组件通信的问题。

核心概念

  • state 用来数据共享数据存储
  • mutation 用来注册改变数据状态
  • getters 用来对共享数据进行过滤操作
  • action 解决异步改变共享数据
  • module 模块

特点

1,Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。

2,你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。

配置目录

1,在store文件夹分别创建,这样我们可对四种特性进行分文件,这样可以更加明确,清楚

mutations.js,state.js,getters.js,actions.js

2,我们分别把这四个特性放入index.js中进行store的实列化

state的用法

state用于存放数据的,所有组件都能访问 this.$store.state

1,首先我们在state里面声明数据,title这个数据已经在全局被共享了

export default {
  title: '购物车'
}

2,在任意组件中,我们在computed里进行数据监听,此时我们就可以从store里拿到state.title

computed: {
    title () {
      return this.$store.state.title
    }
}

mutation的用法

mutations用于存放方法操作数据的,必须是同步函数,第一个参数都是state,需在事件中提交一个方法this.$store.commit('方法名')

可以是单个参... 如果是多个参数,我们则用对象放入,如果你写两个参数,会报错

1,首先在mutations里面定义好方法

export default {
  getParam (state, str) {
    state.title = str
  }
}

2,在组件事件中提交一个方法

methods: {
    change () {
      this.$store.commit('getParam', 'hello')
    }
}

getters的使用

getters派生属性(计算属性),存放一些基于state数据的一些派生属性。

1,比如在state里面有这样一组数据

people: [
    { name: '张三', age: 40 },
    { name: '李四', age: 50 },
    { name: '王五', age: 30 },
    { name: '赵六', age: 80 },
    { name: '田七', age: 10 }
  ]

2,如果我们定义这些数据,然后我们要从,这些数据中筛选出年纪大于30的人,再进行返回,我们就可以用到getter,这里的getter的意思就是对vuex顶层数据进行过滤,而不改动state里原本的数据。

export default {
  changePeople: (state) => {
    return state.people.filter(item => item.age > 30)
  }
}

3,在任意组件中,我们在computed里进行数据监听,此时我们就可以从store里拿到state.getters

computed : {
	changePeople () {
      return this.$store.getters.changePeople
    }
},

action的使用

actions用于处理一些异步函数,actions不能直接操作state。只能提交mutation来操作,再通过mutation来改变state,第一个参数就是context,context.commit('方法名') 指的就是store仓库,在事件中提交一个actions,this.$store.dispatch

1,首先在actions里面定义好方法

export default {
  getParamSync (context, str) {
    setTimeout(() => {
      context.commit('getParam', str)
    }, 3000)
  }
}

注意:提交的方法需在mutation里面定义好

2,在组件事件中提交一个方法,此时你会发现3秒以后才改变参数

methods: {
    change () {
      this.$store.dispatch('getParamSync', 'hello')
    }
}

3,我们有时候向后台请求时,要通过AJAX返回值来进行下一步。我们可以用promise来进行异步处理

export default {
  getParamSync (context, str) {
    return new Promise((reslove, _reject) =>
      setTimeout(() => {
        context.commit('getParam', str)
        reslove('成功')
      }, 2000)
    )
  }
}

在组件中提交这个方法,拿到返回值

methods: {
    async change () {
      const res = await this.$store.dispatch('getParamSync', 'hello')
      console.log(res)
    }
}

module的使用

Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter

1,同样为了更加明确,清楚。我们在一个模块新建以下文件

2,在当前模块index.js中进行统一导出

3,引入模块在index.js中进行store的实列化

3,模块里面的state ,mutations,actions,getters用法和上面一样

???>>>如果A,B两个仓库的mutations方法的命名是一样的。执行的是哪一个呢?

A仓库的mutation

export default {
  getParam (state, str) {
    console.log('我是A仓库')
  }
}
B仓库的mutation

export default {
  getParam (state, str) {
    console.log('我是A仓库')
  }
}

我们在组件中调用会打印什么呢?

答案是两个都调用了,显然这不是我们想要的结果。

*模块化管理数据的时候,我们要开启命名空间。导出的时候命名

import actions from './actions'
import mutations from './mutations'
import state from './state'
import getters from './getters'

export default {
  namespaced: true, // 模块化管理数据请不要忘了命名空间的开启
  state,
  actions,
  mutations,
  getters
}
// 使用的时候带上模块名
this.$store.commit('user/getParam', '你好')

辅助函数的用法

mapState

在使用的组件中引入state辅助函数

  使用辅助函数 mapState
  import { mapState } from 'vuex'
  computed: {
    // 1, 使用对象展开运算符将此对象混入到外部对象中
    ...mapState({
        // 1, 使用箭头函数
        title: state => state.title
        // 2, 传字符串参数 'title' 等同于 `state => state.title`
        title: 'title'
    })
    
    
    //2, 当映射的计算属性的名称与 state 的子节点名称相同时,我们也可以给 mapState 传一个字符串数组。
    // ...mapState(['title'])
  },

mapGetters

在使用的组件中引入mapGetters辅助函数

使用辅助函数 mapGetters
  import { mapGetters } from 'vuex'
  computed: {
    1, 传一个字符串数组
    ...mapGetters([
      'title',
      // ...
    ])
    
    2, 如果你想将一个 getter 属性另取一个名字,使用对象形式(一般这种情况用于不同模块)
    ...mapGetters({
      // 把 `this.title` 映射为 `this.$store.getters['user/title']`
      title: 'user/title'
    })
  },

mapMutations

使用辅助函数 mapMutations 
  import { mapMutations  } from 'vuex'
  methods: {
    1, 传一个字符串数组
    ...mapMutations ([
      'getParam',
      // ...
    ])
    
    2, 如果你想将一个 mutation 属性另取一个名字,使用对象形式(一般用于不同模块)
    ...mapMutations ({
      // 把 `this.add()` 映射为 `this.$store.commit('user/getParam')
      add: 'user/getParam'
    })
    
    3, 不同模块还可以这样写,意思是用的user仓库的方法
    ...mapMutations('user', ['getParam']),
  },

mapActions

import { mapActions } from 'vuex'
methods: {
    1, 传一个字符串数组
    ...mapActions  ([
      'getParamSync',
      // ...
    ])
    
    2, 如果你想将一个 action 属性另取一个名字,使用对象形式(一般用于不同模块)
    ...mapActions  ({
      // 把 `this.add()` 映射为 `this.$store.dispatch('user/getParamSync')
      add: 'user/getParamSync'
    })
  },