Vuex

118 阅读2分钟

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

//main.js入口文件引入注册
import Vue from 'vue'
//引入
import Vuex from 'vuex'
//注册
Vue.use(vuex)
//实例化
const store = new Vuex.Store({
       state:{
         count:0, 
        },
})

//挂载
new Vue({
  store,
  render: h => h(App),
}).$mount('#app')
/*
 使用state
 1.原始形式--插值表达式
  组件中可以使用this.$store获取到vuex中的store对象实例,可以通过state属性获取count
*/
<div>state的数据:{{$store.state.count}}</div>

/*
2.计算属性-将tate属性定义在计算属性中
*/
computed:{
   count(){
     return this.$store.state.count
   }
 }
 <div>state的数据:{{count}}</div>
 
 //3.辅助函数-mapState 
 //导入mapState
 import { mapState } from 'vuex'
 //采用数组形式引入state属性
 mapState(['count'])
 count(){
    return this.$store.state.count
  }
  //利用展开运算符将导出的状态映射给计算属性
  computed:{
    ...mapState(['count'])
   }
   //---------------------------------------------------------------------
   /*
   mutations
   state数据的修改只能通过mutations,并且mutations必须式同步更新,目的是形成数据快照
   */
   //实例化
const store = new Vuex.Store({
       state:{
         count:0, 
        },
        //定义mutations,
        //mutations是一个对象,对象中存放修改state的方法
     //方法里参数 第一个参数是当前store的state属性
     //payload 荷载,运输参数,调用mutations的时候,可以传递参数,传递载荷
       mutations:{
       addCount(state){
          state.count+=1
            }
       },
})
/*
使用mutations
1.原始形式-$store
新建组件,内容为一个button按钮,点击按钮调用mutations
2.辅助函数
*/
<template>
<button @click="addCount">点击我修改vuex的数据</button>
</template>
<script>
//导入mapMutations
import { mapMutations } from 'vuex'
export default{
   methods:{
    //调用方法
    addCount(){
      //调用store中的mutations  提交给mutations
      //commit('mutations名称',参数)
      this.$store.commit('addCount',10)//直接调用mutations
     }
   },
   //带参数的传递
addCount(state,payload){
    state.count+=payload
 },
// this.$store.commit('addCount',10)

//采用数组形式引入mutations
//利用展开运算符将导出的状态映射给methods
...mapMutations(['addCount'])
 }

</script>

3.actions

state是存放数据的,mutations是同步更新数据,actions则是负责进行异步操作

//actions是一个对象,对象中存放着方法
actions:{
 //获取异步的数据.context表示当前的store的实例,可以通过context.state获取状态,也可以通过context.commit来提交mutations,也可以context.dispatch调用其他的actions
 getAsyncCount(context) {
  setTimeout(function(){
     //一秒钟之后,要给一个数去修改state
     context.commit('addCount',233)
    },1000)
  }
 }
 //--------------------------------------------------------
 //使用actions
 //原始形式--$store
 addAsyncCount(){
    this.$store.dispatch('getAsyncCount')
  }
  //传递参数
  addAsyncCount(){
    this.$store.dispatch('getAsyncCount',233)
  }
  //-------------------------------
  //辅助函数--mapActions
  //导入mapActions
  import { mapActions } from 'vuex'
  /*
  采用数组形式引入actions
  利用展开运算符将导出的状态映射给methods
  */
  methods:{
        ...mapActions(['getAsyncCount'])
   }

4.getters

除了state之外,有时害需要从state中派生出一些状态,这些状态时以来state的,此时会用到getters

/*
例如state中定义了list 为1~10的数组
组件中,需要娴熟所有大于5的数据,正常的方式,时需要list在组件中进行在一步的处理,但是getters可以帮助我们实现它
*/
state:{
  list:[1,2,3,4,5,6,7,8,9,10]
 }
 getters:{
       //getters函数的第一个参数是state
       //必须有返回值
       filterList: state => state.list.filter(item => item > 5)

  }
  //------------------------------------------------
  //使用getters
  //原始形式--$store
  <div> {{$store.getters.filterList}} </div>
  //辅助函数--mapGetters
  //导入
  import { mapGetters } from 'vuex'

  computed:{
     ...mapGetters(['filterList'])
   }
   <div> {{filterList}} </div>

模块化--module

由于使用单一状态树,应用的所有状态会集中到一个比较大的对象state当中。当应用变得非常复杂时,就又肯变得相当臃肿。Vuex会变得越来越难以维护,由此,又又了Vuex的模块化

Snipaste_2022-04-04_22-04-43.png

模块化的简单应用

/*
定义两个模块,user和setting
user中管理用户的状态 token
setting中管理应用的名称name
定义child-b组件,分别显示用户的token和应用名称name
*/
const store = new Vuex.Store({
  modules:{
    user:{
       state:{
         token:'12345'
          }
      }
   },
   setting:{
      state:{
        name:'Vuex实例'
        }
     }
 })
 //------------------------------------------------
 <template>
    <div>
     //主要,此时要获取子模块的状态 需要通过$store.state.模块名.属性名来获取
        <div> 用户token {{$store.state.user.token}} </div>
        <div> 网站名称 {{$store.state.setting.name}} </div>
    </div>
 </template>
//---------------------------------------------------------------
//看着获取有点麻烦,可以通过getters改变一下
getters:{
  token: state => state.user.token,
  name: state => state.setting.name
 }
 //这个getters是根级别的getters
 computed:{
   ...mapGetters(['token','name'])
  }
  /*
  默认情况下,模块内部的actions,mutations和getters是注册在全局命名空间
  这样使得多个模块能够对同一mutations或actions做出响应
  如果向保证内部模块的高封闭性,可以采用namespaced来进行设置
  */
   user:{
   namesoaced:true,  //命名空间锁
       state:{
         token:'12345'
          }
      }
   },
  mutations:{
  //这里的state表示的是user的state
      updateToken(state):{
      state.token = 9527
        }
     }

image.png

//直接调用--带上模块的属性名路径
this.$store.dispatch('user/updateToken')
//辅助函数-带上模块名
methods:{
     ...mapMutations('user',['updateToken'])
  }