小言_互联网的博客

vue状态管理——Vuex

296人阅读  评论(0)

 vuex官方解释

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

简单理解 

 vuex就是把组件共享状态抽取出来以一个全局单例模式管理,把共享的数据函数放进vuex中,任何组件都可以进行使用。

什么时候我们该使用它?

Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。

如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。

 使用

1、 安装Vex 

npm install --save vuex

2、配置Vuex文件

新建文件夹 store 新建文件 index.js ,在index.js文件进行配置vuex文件——相当于数据库,只不过是在前端。所有状态(数据都放在state中)比如:counter就相当于数据库的一个字段,0就是字段值。


  
  1. import { createStore } from "vuex";
  2. // const store = createStore({
  3. // })
  4. // export default store;
  5. //或者简写如下
  6. export default createStore({
  7. state:{
  8. counter: 0
  9. }
  10. })

3、在全局进行引入,在main.js文件添加以下代码,重点是引入和挂载。


  
  1. import store from './store'
  2. const app = createApp( App);
  3. app. use(store)
  4. app. mount( '#app')

4、在组件中读取状态,在任意一个组件页面中使用,都可以获取到存储在state下的值

第一种

 <p> counter = {{$store.state.counter}} </p>

 第二种 在任意一个组件页面中使用以下代码,只不过是放在了computed下,computed专门读取vuex的数据。


  
  1. <template>
  2. <p>{{ counter }} </p>
  3. </template>
  4. <script>
  5. import { mapState } from "vuex"
  6. export default {
  7. computed:{
  8. //专门读取vuex的数据
  9. //如有多个 则: ...mapState(["counter",“age"])
  10. ... mapState([ "counter"])
  11. }
  12. }
  13. </script>
  14. <style>
  15. </style>

 核心概念

vuex中一共有五个状态 State  Getter  Mutation   Action   Module 

▣State

提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data

 在vuex中state中定义数据,可以在任何组件中进行调用


  
  1. import Vue from 'vue'
  2. import Vuex from 'vuex'
  3. Vue. use( Vuex)
  4. export default new Vuex. Store({
  5. //数据,相当于data
  6. state: {
  7. name: "张三",
  8. age: 12,
  9. count: 0
  10. },
  11. })

 调用:

方法一:

在标签中直接使用


  
  1. <p>{{$store.state.count}} </p>
  2. <p>{{$store.state.name}} </p>
  3. <p>{{$store.state.age}} </p>

方法二:

this.$store.state.全局数据名称

方法三:从vuex中按需导入mapstate函数

注意:当前组件需要的全局数据,映射为当前组件computed属性


  
  1. <template>
  2. <p>{{ counter }} </p>
  3. </template>
  4. <script>
  5. import { mapState } from "vuex"
  6. export default {
  7. computed:{
  8. //专门读取vuex的数据
  9. //如有多个 则: ...mapState(["counter",“age"])
  10. ... mapState([ "counter"])
  11. }
  12. }
  13. </script>
  14. <style>
  15. </style>

▣ Mutation

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


  
  1. import { createStore } from "vuex";
  2. // const store = createStore({
  3. // })
  4. // export default store;
  5. //或者简写如下
  6. export default createStore({
  7. state:{
  8. //所有状态(数据都放在state中)
  9. counter: 0
  10. },
  11. getters:{
  12. getCount( state){
  13. return state. counter > 0 ?state. counter : "此时的counter<=0"
  14. }
  15. },
  16. mutations:{
  17. addCount( state){
  18. state. counter=state. counter+ 1;
  19. }
  20. }
  21. })

 调用方法:


  
  1. <template>
  2. <h1>主页 </h1>
  3. <p>counter : {{$store.state.counter}} </p>
  4. <p>counter : {{$store.getters.getCount}} </p>
  5. <p>{{getCount}} </p>
  6. <button @click="add">counter++操作 </button>
  7. </template>
  8. <script>
  9. import { mapGetters } from "vuex"
  10. export default {
  11. computed:{
  12. ... mapGetters([ "getCount"])
  13. },
  14. methods:{
  15. add( ){
  16. //固定调用方式
  17. this. $store. commit( "addCount")
  18. }
  19. }
  20. }
  21. </script>
  22. <style>
  23. </style>

 分析:任何对counter引入的组件都会得到相同的变化,即counter值相同。但新开一个页面,counter不会得到相同的变化,依旧从index文件中获取到初始值:0 。

使用二 :带参数传递

例子:点击一次,增加15

 例子升级:调用方法使用mapMutations获取,即修改methods方法中如下:效果一样。


  
  1. <template>
  2. <p>counter : {{$store.state.counter}} </p>
  3. <p>counter : {{$store.getters.getCount}} </p>
  4. <p>{{getCount}} </p>
  5. <button @click="add">counter+15操作 </button>
  6. </template>
  7. <script>
  8. import { mapGetters, mapMutations} from "vuex"
  9. export default {
  10. computed:{
  11. ... mapGetters([ "getCount"])
  12. },
  13. methods:{
  14. ... mapMutations([ "addCount"]),
  15. add( ){
  16. this. addCount( 15)
  17. }
  18. }
  19. }
  20. </script>
  21. <style>
  22. </style>

Action

Action和Mutation相似,Mutation 不能进行异步操作,若要进行异步操作,就得使用Action

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


  
  1. import axios from "axios";
  2. import { createStore } from "vuex";
  3. export default createStore({
  4. state:{
  5. //所有状态(数据都放在state中)
  6. counter: 0
  7. },
  8. getters:{
  9. getCount( state){
  10. return state. counter > 0 ?state. counter : "此时的counter<=0"
  11. }
  12. },
  13. mutations:{
  14. addCount( state,num){
  15. state. counter += num;
  16. }
  17. },
  18. actions:{
  19. //({}) 加上花括号代表对象结构赋值
  20. asyncAdd( {commit}){
  21. axios. get( "http://iwenwiki.com/api/FingerUnion/list.php")
  22. . then( res => {
  23. commit( "addCount",res. data[ 0])
  24. })
  25. }
  26. }
  27. })

调用方法一:


  
  1. <template>
  2. <p>counter : {{$store.state.counter}} </p>
  3. <p>counter : {{$store.getters.getCount}} </p>
  4. <p>{{getCount}} </p>
  5. <button @click="add">counter+15操作 </button>
  6. <button @click="addAsyn">异步增加counter操作 </button>
  7. </template>
  8. <script>
  9. import { mapGetters, mapMutations} from "vuex"
  10. export default {
  11. computed:{
  12. ... mapGetters([ "getCount"])
  13. },
  14. methods:{
  15. ... mapMutations([ "addCount"]),
  16. addAsyn( ){
  17. this. $store. dispatch( "asyncAdd")
  18. },
  19. add( ){
  20. //固定调用方式
  21. // this.$store.commit("addCount",15)
  22. this. addCount( 15)
  23. }
  24. }
  25. }
  26. </script>
  27. <style>
  28. </style>

 调用方法二:使用mapMutations获取,即引入后修改methods方法中如下:效果一样

tips:  ({}) 加上花括号代表对象结构赋值

Getter 

对vuex中数据进行过滤。

类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据。

 第一种


  
  1. import { createStore } from "vuex";
  2. // const store = createStore({
  3. // })
  4. // export default store;
  5. //或者简写如下
  6. export default createStore({
  7. state:{
  8. //所有状态(数据都放在state中)
  9. counter: 0
  10. },
  11. getters:{
  12. getCount( state){
  13. return state. counter > 0 ?state. counter : "此时的counter<=0"
  14. }
  15. }
  16. })

 调用方法一:

 <p> counter : {{$store.getters.getCount}} </p>

 调用方法二:    使用mapGetters


  
  1. <template>
  2. <p>{{getCount}}</p>
  3. </template>
  4. <script>
  5. import { mapGetters } from "vuex"
  6. export default {
  7. computed:{
  8. ... mapGetters([ "getCount"])
  9. }
  10. }
  11. </script>
  12. <style></style>

结果:

Modules

当遇见大型项目时,数据量大,store就会显得很臃肿

为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割:

 引用:

this.$store.state.cityModules.cityname

转载:https://blog.csdn.net/qq_45947664/article/details/127660917
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场