八、vuex

一、概念

Vuex官网

Vuex是一个专为Vue.js应用程序开发的状态管理模式

通俗讲就是把多个组件共享的变量全部存储在一个对象里面

二、使用方式

vuex不是vue内置的,但是是官方的

使用步骤

  • 安装vuex

  • 创建store对象管理数据

  • 挂载store对象到vue实例

  • 安装vuex

npm i -S vuex
  • 创建store对象管理数据

    • 创建src/store目录,并在其中创建index.js文件用于导入并创建store对象

    • 编写src/store/index.js文件:

 1 import Vue from 'vue'
 2 import Vuex from 'vuex'
 3 
 4 Vue.use(Vuex)
 5 
 6 export default new Vuex.Store({
 7   state: {
 8   },
 9   mutations: {
10   },
11   actions: {
12   },
13   getters:{
14   },
15   modules: {
16   }
17 })
  • 挂载store对象到vue实例,main.js中编写如下代码
 1 import Vue from 'vue'
 2 import App from './App.vue'
 3 import router from './router'
 4 // 引入store
 5 import store from './store'
 6 
 7 Vue.config.productionTip = false
 8 
 9 new Vue({
10   router,
11   // 使用store
12   store,
13   render: h => h(App)
14 }).$mount('#app')

三、核心概念

1、state

state提供唯一公共数据源,所有的共享数据都要统一放到state中进行存储

1 // 在组件中访问state数据的第一种方式
2 this.$store.state.全局数据名称
1 // 在组件中访问state数据的第二种方式,按需导入mapState函数
2 // 将全局函数映射为当前组件的计算属性,数据的使用方式如同在当前组件中使用自身的data数据一样
3 import { mapState } from 'vuex'
4 computed: {
5     ...mapState(['count'])
6 }

2、mutations

mutations用于变更store中的数据

  • 在Vuex中只能通过mutation变更store中的数据,不可以直接操作store中的数据

  • 通过这种方式操作起来稍微繁琐一些,但是可以集中监控所有数据的变化

  • 不要在mutation中写异步的代码

 1 const store = new Vuex.Store({
 2   state: {
 3     count: 1
 4   },
 5   mutations: {
 6     // state是默认参数
 7     increment (state) {
 8       // 变更状态
 9       state.count++
10     }
11   }
12 })
1 // 组件中触发mutation的第一种方式
2 methods:{
3     handle(){
4         this.$store.commit('increment')
5     }
6 }
 1 // 组件中触发mutation的第二种方式
 2 import { mapMutations } from 'vuex'
 3 
 4 methods:{
 5     ...mapMutations(['increment','add']),
 6     handle1(){
 7         this.increment()
 8     },
 9     handle2(){
10         this.add([arg1,...])
11     }
12 }
  • 可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload)
1 // ...
2 mutations: {
3   increment (state, n) {
4     state.count += n
5   }
6 }
1 store.commit('increment', 10)

3、actions

action类似于mutation

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

  • action 可以包含任意异步操作

 1 // store/index.js中声明action
 2 const store = new Vuex.Store({
 3     // 省略其他代码
 4     mutations: {
 5         add(state){
 6             state.count++
 7         }
 8     },
 9     actions: {
10         addAsync(context, [arg1,...]){
11             setTimeout(() => {
12                 context.commit('add', [arg1,...])
13             },1000)
14         }
15     }
16 })

组件中使用

1 // 组件中触发action的第一种方式
2 methods: {
3     handle(){
4         this.$store.dispach('addAsync', [arg1,...])
5     }
6 }
 1 // 组件中触发action的第二种方式
 2 import { mapActions } from 'vuex'
 3 
 4 export default {
 5   // ...
 6   methods: {
 7     ...mapActions([
 8       'addAsync' // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`
 9     ])
10   }
11 }

4、getters

对store中已有的数据加工处理形成新的数据

  • 对已有的数据进行加工,类似于Vue的计算属性,getter 的返回值会根据它的依赖被缓存起来

  • store数据发生变化,则getter中的数据也会跟着变化

1 // 定义getter
2 ....
3 getters: {
4     showNum: state => {
5         return '当前最新的数量是【' + state.count + '】'
6     }
7 }

使用

1 // 在组件中访问getters数据的第一种方式
2 this.$store.getters.全局数据名称
1 // 在组件中访问getters数据的第二种方式,按需导入mapGetters函数
2 import {mapGetters} from 'vuex'
3 // 将全局函数映射为当前组件的计算属性
4 export default {
5   // ...
6   computed: {
7     ...mapGetters(['showNum'])
8   }
9 }
  • Getter 也可以接受其他 getter 作为第二个参数:
 1 getters: {
 2   // ...
 3   getters: {
 4     doneTodos: state => {
 5       return state.todos.filter(todo => todo.done)
 6     }
 7   },
 8   doneTodosCount: (state, getters) => {
 9     return getters.doneTodos.length
10   }
11 }

5、modules

  • 当应用变得非常复杂时,store 对象就有可能变得相当臃肿

  • 因此Vuex 允许我们将 store 分割成模块(module)

  • 每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块 ===> 从上至下进行同样方式的分割

 1 const moduleA = {
 2   state: () => ({ ... }),
 3   mutations: { ... },
 4   actions: { ... },
 5   getters: { ... }
 6 }
 7 
 8 const moduleB = {
 9   state: () => ({ ... }),
10   mutations: { ... },
11   actions: { ... }
12 }
13 
14 const store = new Vuex.Store({
15   modules: {
16     a: moduleA,
17     b: moduleB
18   }
19 })
20 
21 store.state.a // -> moduleA 的状态
22 store.state.b // -> moduleB 的状态
  • module中的mutations
 1 const moduleA = {
 2   state: () => ({
 3     name: 'zhangsan'
 4   }),
 5   mutations: {
 6     updateName (state, payload) {
 7       // 这里的 `state` 对象是模块的局部状态
 8       state.name = payload
 9     }
10   }
11 }
1 // 组件中使用
2 methods: {
3   updateName() {
4     this.$store.commit('updateName', 'lisi')
5   }
6 }

module中的getters

 1 const moduleA = {
 2   state: () => ({
 3     name: 'zhangsan'
 4   }),
 5   mutations: {
 6     updateName (state, payload) {
 7       // 这里的 `state` 对象是模块的局部状态
 8       state.name = payload
 9     }
10   },
11   getters: {
12     fullName(state) {
13       return state.name + '1111'   
14     },
15     // 第二个参数用来操作getters中的getter
16     fullName2(state, getters) {
17       return getters.fullName + '2222'   
18     },
19     // 第三个参数操作根state
20     fullName3(state, getters, rootState) {
21       return getters.fullName2 + rootState.count   
22     }
23   }
24 }
 1 // 组件中使用
 2 <div>{{$store.getters.fullName}}</div>
 3 <div>{{$store.getters.fullName2}}</div>
 4 <div>{{$store.getters.fullName3}}</div>
 5 // 或者
 6 methods: {
 7   updateName() {
 8     this.$store.getters.fullName()
 9   }
10 }
  • module中的actions
 1 const moduleA = {
 2   state: () => ({
 3     name: 'zhangsan'
 4   }),
 5   mutations: {
 6     updateName (state, payload) {
 7       // 这里的 `state` 对象是模块的局部状态
 8       state.name = payload
 9     }
10   },
11   actions: {
12     aUpdateName() {
13       setTimeout(() => {
14           context.commit('updateName', 'wangwu')
15         }, 1000)
16     }
17   }
18 }
1 // 组件内使用
2 methods: {
3   asyncUpdateName() {
4     this.$store.dispatch('aUpdateName')
5   }
6 }

 

 

 

posted @ 2022-07-21 22:10  大米饭盖饭  阅读(34)  评论(0)    收藏  举报