Vuex

2022-04-19  本文已影响0人  迷失的信徒

一、Vuex是什么?

官方解释为:Vuex是一个转为Vue.js应用程序开发的状态管理模式

  • 它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • Vuex也集成了Vue官方调试工具devtools extension,提供了诸如零配置的time-travel调试、状态快照导入导出等高级调试功能。

通俗点来说,他就是个单例,任何一个用到单例中同一变量的地方,只要有一处修改了变量的值,其他的地方也会响应式的变化,最终保持一致。

我们把需要共享的状态(变量)抽取出来,交给Vuex统一管理,然后我们按照规定好的规则,进行访问和修改等操作;这就是Vuex背后的基本思想。

Backend API.png

二、Vuex的引入和使用

这里以webpack@3.6.0为例

import Vue from "vue"
import Vuex from 'vuex'

//1、安装插件
Vue.use(Vuex)
//2、创建对象
const store = new Vuex.Store({
  state:{
  },
  //修改state对象的话,至少要经过mutations中的方法
  mutations:{
  },
  //异步延时操作
  actions:{
  },
  getters:{//类似于计算属性
  },
  modules:{
  }
})
//3、导出store对象
export default store
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

注意:这里的store好像一定要取这个名,我试了一下其他的,好像拿不到值;很奇怪!!!

三、Vuex核心概念

1、State-单一状态树

单一状态树:英文名称Single Source of Truth,也可以翻译成单一数据源。
Vuex使用了单一状态树来管理应用层级的全部状态。
单一状态树能够让以我们最直接的方式找到某个状态的片段,而且在之后的维护和调试过程中,也可以非常方便的管理和维护。

state:{
    counter:200,
    students:[
      {id:100,name:'zhangsan',age:18},
      {id:101,name:'lisi',age:10},
      {id:102,name:'wangwu',age:23},
      {id:103,name:'zhaoliu',age:33}
    ]
  },

这里以展示counter为例
组件中使用为:$store.state.counter

2、Getters

可以把他的作用理解成计算属性。

powerCounter(state){
      return state.counter * state.counter
    },

并在相应的组件中使用:$store.getters.powerCounter

more15stu(state){
      return state.students.filter(s => s.age > 15)
    },

组件中使用:$store.getters.more15stu

more15stulength(state,getters){
      return getters.more15stu.length
    },

使用:$store.getters.more15stulength

moreagestu(state){//传参
      return age => {
        return state.students.filter(s => s.age > age)
      }
    }

注意:传递参数时,返回一个带有入参的函数。

使用:$store.getters.moreagestu(19)

3、Mutations

Vuex的store状态的状态更新唯一方式:提交mutations
通常情况下,Vuex要求我们Mutations中方法必须是同步函数。

  • 主要原因是当我们使用devtools时,devtools可以帮助我们捕捉mutations的快照。
  • 但是如果是异步操作,那么devtools将不能很好的追踪这个操作什么时候被完成。
3.1、基本用法

如在App.vue组件中通过点击按钮来加减counter

    increment(state){
      state.counter++
    },
    decrement(state){
      state.counter--
    }
<template>
  <div id="app">
    <button @click="addition">+</button>
    <button @click="subraction">-</button>
  </div>
</template>

<script>
export default {
  name: 'App',
  methods:{
    addition(){
      this.$store.commit('increment')
    },
    subraction(){
      this.$store.commit('decrement')
    }
  }
}
</script>

<style>
</style>

通过事件来调用this.$store.commit('increment')

3.2、带参

参数被称为是mutations的载荷(payload)

  mutations:{
    incrementCount(state,count){
      state.counter += count
    }
  },

使用:

addition(){
      this.$store.commit('incrementCount',10)
    },
  mutations:{
    addStudent(state,stu){
      state.students.push(stu)
    }
  },

用法:

addition(){//方法名可以随便哈,我这里只是懒的写了
      const stu = {id:144,name:'kk',age:49}
      this.$store.commit('addStudent',stu)
    },
3.3、特殊提交风格

提交

this.$store.commit({
  type:'changeCount',
  count
})

将整个commit对象作为payload来使用

changeCount(state,payload){
  state.count += payload.count
}
3.4、响应规则
  state:{
    info:{id:120,name:'kk',age:33}
  },
  //修改state对象的话,至少要经过mutations中的方法
  mutations:{
    addprops(state){//添加属性
      Vue.set(state.info,'address','开封')
    },
    delectprops(state){//删除属性
      Vue.delete(state.info,'age')
    }
  },
3.5、mutations常量类型

在store文件目录下,创建mutations-type.js

export const INCREMENT = 'increment'

在index.js中引入、定义

import {INCREMENT} from './mutations-types.js'
[INCREMENT](state){
      state.counter++
    },

在组件中使用

import {INCREMENT} from './mutations-types.js'
addition(){
      this.$store.commit(INCREMENT)
    },

4、Action

Action类似于Mutations,但是是用来替代Mutations进行异步操作的。
一段时间后再做某项操作

  mutations: {
    [INCREMENT](state) {
      state.counter++
    },
  },
  //异步操作
  actions: {
    asyAdd(context) {
      setTimeout(() => {
        content.commit(INCREMENT)
      },1000)
    }
  },

这里的context对应的就是store对象
通过this.$store.dispatch('asyAdd')调用。

带参:asyAdd(context,payload)his.$store.dispatch('asyAdd',abc)

asyAdd(context,payload) {
      return new Promise((resolve,reject) => {
        content.commit(INCREMENT)
        console.log(payload);
        resolve()
      })
    }
this.$store.dispatch('asyAdd','我是携带的参数').then(res => {
        console.log('异步操作已完成');
        console.log(res);
      })

5、Modules

项目越大、store对象管理的状态也会越来越多,从而会变得很臃肿,module就是将store分割成不同的模块,有着自己的state、mutations、actions、getters.

const moduleA = {
  state:{
    name:'abc'
  },
  mutations:{
    updataName(state,payload){
      state.name = payload
    }
  },
  actions:{
    aupNname(context){
      setTimeout(() => {
        context.commit('updataName','lisi')//
      },1000)
    }
  },
  getters:{
    fullname(state){
      return state.name + '1111'
    },
    fullname1(state,getters,rootState){
      return getters.fullname + rootState.counter
    }
  },
}
modules: {
    a:moduleA
  }
  • 通过$store.state.a.name获取a中state里面name的值。
  • 同样是通过this.$store.commit('updataName','lisi')来修改name的值
  • 同样是通过$store.getters.fullname来展示;但可以多了rootState参数。
  • actions还是以this.$store.dispatch('aupNname')调用;但是这里面的context和rootState里面actions里面的context是不一样的。
上一篇 下一篇

猜你喜欢

热点阅读