什么是Vuex?

答:集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化
说人话:对于我的理解来说Vuex就是一个共享数据进行任意组件的通信,vuex你可以把他比作为单独的一个空间。其他组件有需要的时候都往这个vuex开辟的这个空间上去存取。
这个图片是非常形象的:
zdg7IU.png

Vuex的工作原理图

zdgqG4.png

如何使用Vuex

cmd npm install vuex --save安装vuex
src/main.js添加核心store配置。
zd2te0.png
在项目下面创建文件夹store->index.js

import Vuex from 'vuex'
import Vue from 'vue'
// 使用vuex 
Vue.use(Vuex)
// 创建store
const store=new Vuex.Store({
    modules:{
        countAbout:countOptions,
        personAbout:personOptions
    }
})
//暴露(导出)
export default store

如何使用Vuex

Vuex的基本使用

  1. 初始化数据state,配置actions、mutations,操作文件store.js
  2. 组件中读取vuex中的数据$store.state.数据
  3. 组件中修改vuex中的数据$store.dispatch('action中的方法名',数据)或$store.commit('mutations中的方法名',数据)
  4. 若没有网络请求或其他业务逻辑,组件中也可越过actions,即不写dispatch,直接编写commit**

简单的使用。
store/index.js

import Vue from 'vue'
import Vuex from 'vuex'    // 引入Vuex

Vue.use(Vuex)    // 应用Vuex插件

// 准备actions——用于响应组件中的动作
const actions = {
    /* jia(context,value){
        console.log('actions中的jia被调用了')
        context.commit('JIA',value)
    },
    jian(context,value){
        console.log('actions中的jian被调用了')
        context.commit('JIAN',value)
    }, */
    jiaOdd(context,value){    // context 相当于精简版的 $store
        console.log('actions中的jiaOdd被调用了')
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },
    jiaWait(context,value){
        console.log('actions中的jiaWait被调用了')
        setTimeout(()=>{
            context.commit('JIA',value)
        },500)
    }
}
// 准备mutations——用于操作数据(state)
const mutations = {
    JIA(state,value){
        console.log('mutations中的JIA被调用了')
        state.sum += value
    },
    JIAN(state,value){
        console.log('mutations中的JIAN被调用了')
        state.sum -= value
    }
}
// 准备state——用于存储数据
const state = {
    sum:0 //当前的和
}

// 创建并暴露store
export default new Vuex.Store({
    actions,
    mutations,
    state,
})

组件如何去使用vuex store

组件去使用actions。 actions作为一个服务员你要传输的数据要还要进行数据操作处理那么你最好传输给actions

自己手写的dispatch版本传输

incrementOdd(){
                this.$store.dispatch('jiaOdd',this.n)
            },

dispatch封装版本
mapActions方法:用于帮助生成与actions对话的方法,即包含$store.dispatch(xxx)的函数

methods:{
    //靠mapActions生成:incrementOdd、incrementWait(对象形式)
    ...mapActions({incrementOdd:'jiaOdd',incrementWait:'jiaWait'})

    //靠mapActions生成:incrementOdd、incrementWait(数组形式)
    ...mapActions(['jiaOdd','jiaWait'])
}

第一个值是传输到actions的哪个函数里面,第二个值是要传输过去的值(第二个可选项)
在VUEX开辟的空间index.js中先写逻辑代码最后context.commit提交给mutations

jiaOdd(context,value){    // context 相当于精简版的 $store
        console.log('actions中的jiaOdd被调用了')
        if(context.state.sum % 2){
            context.commit('JIA',value)
        }
    },

使用mutations
1.在sotre/index.js中

在 mutations函数中要做的就是一件事情将数据传输给state中。直接调用state.属性就可以存取。
const mutations={
     ADD(state,value){
            state.sum+=value
        },
} 

2.在组件中如何去传输给mutations

1.mutations原生版本
    
increment(){
            //     // this.$store.dispatch('add',this.n);
            //     this.$store.commit('ADD',this.n);
            // },
2.mutations封装版本
methods:{
    //靠mapActions生成:increment、decrement(对象形式)
    ...mapMutations({increment:'JIA',decrement:'JIAN'}),
    
    //靠mapMutations生成:JIA、JIAN(对象形式)
    ...mapMutations(['JIA','JIAN']),
}

getters

何为getters? 答:用于Vuex的数据计算 可以计算state{}里的属性 有人就问了为什么不直接写在computed里面?那是因为写在computed里面他不能直接多组件通信,你只能在computed写完再进行传输到actions上。
用法:
在store里面的使用

getters:{
        bigSum(state){
            return state.sum*10;
        }
    }

在组件里面的使用
1.原生写法

 bigSum(){
            return this.$store.getters.bigSum
        },

2.封装写法

computed: {
    //借助mapGetters生成计算属性:bigSum(对象写法一)
    ...mapGetters({bigSum:'bigSum'}),

    //借助mapGetters生成计算属性:bigSum(数组写法二)
    ...mapGetters(['bigSum'])
},

state

是vuex中的数据处理完保存的数据池。
用法:
在store里面的使用

state:{
        sum:0,
        school:'奔放',
        schoolnum:20212410614,
    },

在组件里面的使用
1.原生写法
$store.state.sum也可以在methods中封装个函数然后retuen出去将函数名放在{{插值语法}}也行。
2.封装写法
...mapState(['personList']),

...mapState({
                qiuhe:state=>state.sum,
                name:'school',
                 schoolnum:'schoolnum',
                 personList:'personList'
             }),

模块化命名空间

为什么要模块化的vuex?因为随着公共数据过多容易变得难以管理,我们最好给他分个类。
第一种简单的分类:直接在index.js中进行分类

为了解决不同模块命名冲突的问题,将不同模块的namespaced: true,之后在不同页面中引入getteractionsmutations时,需要加上所属的模块名

const countAbout = {
  namespaced: true,    // 开启命名空间
  state: {x:1},
  mutations: { ... },
  actions: { ... },
  getters: {
    bigSum(state){ return state.sum * 10 }
  }
}

const personAbout = {
  namespaced: true,    // 开启命名空间
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

const store = new Vuex.Store({
  modules: {
    countAbout,
    personAbout
  }
})

zdh1A0.png
第二种分类:是分类到store的多个文件。
zdh3NV.png
分类后的js文件中也是写一个对象,不过需要暴露一下。
zdhY3F.png
然后index.js主store文件中要记得引用一下文件。
zdhNjJ.png