Vuex的使用

68 阅读4分钟

Vuex

Vuex是什么?

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

简单来说vuex就是一个全局状态的管理,和全局变量有很多相似之处。

那么它和全局变量有什么区别呢?

​ Vuex的核心就是store,它里面存贮着你的项目中的大部分state。并且它以一定的规则约束你去修改这些变量,而不是像全局变量一样随意修改,不安全。

安装

​ 我个人推荐用npm或者yarn进行安装

npm install vuex@next --save //npm安装
yarn add vuex@next --save //yarn安装

核心概念(state,getter,mutations,actions,modules)

state

​ state就是一个全局状态的初始化,里面可以定义你想定义的全局状态量,他们都储存在store中并且Vuex的状态储存都是响应式的。比如:

state: {
    count: 1,
    num:2
}

​ 如果我们想在其他的vue文件中获取这个count的值,我们就要这样写:

import {useStore} from "vuex";
    const store = useStore()
    const count = store.state.count  
    console.log(store.state.count)  // 1

同样想获取num也是一个道理。

mutation

​ 提交mutation是更新store中state的唯一方法。每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,比如我们定义了一个mutations:

mutations: {
    setCount(state, num) {
        state.count = num;
    }
}

​ 此时我们的回调函数是setCount。但是呢,我们无法直接调用这个函数。此时我们就要提交mutation(也就是commit mutation),从store中调用我们的setCount:

image-20230313122438682.png

setCount就是我们的事件类型,10就是向store中传入的额外参数,即mutation的荷载(payload)。

​ 这里我做了一个@click的事件并在store.commit前后都打印值,来更好地理解这个值的变化。

​ 第一次点击打印:

image-20230313124841692.png

​ 第二次点击打印:

image-20230313125028057.png

​ 我们可以清楚的看到第一次打印时,原来是1,然后经过更改后变成了10,第二次打印两次都是10。说明此时store里面存储的状态的count发生了改变,并再次存入store中。

我们还可以以对象的风格提交

store.commit({
  type:'setCount',
  amount:100
})

​ 我们可以猜一下,我们再次打印store.state.count会发生什么?

image-20230313130819689.png

​ 此时它返回的是一个proxy对象,我们必须还得在后面加个.count才能获取到我们100这个值。假如我们先写的普通方式提交,再写对象风格的提交,store里面最后也会变成对象的形式,就如同上图。

action

1、类似于mutation,但是action可以异步操作,更改数据还是到mutations中更改。我们来写个简单的action:

actions: {
  setCountPromise(context,num){
    return new Promise((resolve, reject)=>{
      if (num>100){
        reject("值不能大于100")
      }else {
        context.commit("setCount",num)
        resolve('111')
      }
    })
  }
}

​ 我们这里返回了一个promise来校验num的值是否大于100。action函数有一个context对象,此对象和store实例差不多,具有相同的方法和属性,因此我们可以调用context.commit提交一个mutation。肯定很多人好奇context是什么我们来打印一下context

image-20230313145927387.png

​ 可以看到里面有许多的方法和对象。因此我们可以通过context.state和context.getters来获取state 和 getters。

2、分发Action

Action 通过 store.dispatch 方法触发:

store.dispatch('setCountPromise', 100).then(res => {
  alert('修改成功'+ res)
}).catch(err => {
  alert(err)
})

大家可能会很好奇这个和mutation不是没什么区别吗?区别就在于它可以异步实现啊,这就是我们为什么写了一个promise来作为示例。

getter

getter的作用就是计算state,来获取我们想要的值。

直接上例子:

getters: {
    countState(state){
        return state.count>=1
    }
},

我们这边写一个countstate的方法来计算state.count的值是否大于1,大于1就返回true,否则为false,并在分发action前后都打印一下countstate的值:

console.log(store.getters.countState)
const handelLogin = () => {
  store.dispatch('setCountPromise', 100).then(res => {
    alert('修改成功'+ res)
  }).catch(err => {
    alert(err)
  })
  console.log(store.getters.countState)

此时我们把值修改为100,返回的肯定就是true。如果我们把100修改为-100,返回的就是false。这边比较简单就不演示给大家看了。

modules

modules就是当我们的数据比较多的时候,我们要把数据分模块来写,每个模块有自己的state、mutation、action 和getter,这样比较方便读写,也方便我们管理我们的代码,不至于代码臃肿。

这边我们先在store中创建一个目录,再在目录中创建一个js文件,我们把之前写的state、mutation、action 和getter都存在里面。记得导出就行。之后我们再在源文件中导入我们新建的文件。

import user from "./state/numState"
	modules: {
        user
    }
})

此时如果我们想要获取count的值就要写成store.state.user.count,因为我们之前在state里面储存的数据都被放到了state.user里面,如图:

image-20230315160640665.png

然而获取getter里面countstate的值还是直接写store.count。

如有错误与修改意见欢迎大家指正。