【Vuex】状态管理机制

发布于:2022-12-28 ⋅ 阅读:(630) ⋅ 点赞:(0)

vuex

在这里插入图片描述

什么是Vuex

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。如果您的应用够简单,最好不要使用Vuex。

使用Vuex管理数据优势

  • 能够在vuex中集中管理共享的数据,便于开发和后期进行维护

  • 能够高效的实现组件之间的数据共享,提高开发效率

  • 存储在vuex中的数据是响应式的,当数据发生改变时,页面中的视图也会同步更新

  • vuex中的数据操作可以在开发阶段通过开发调试工具来进行追踪,便于开发

  • 如果说组件中数量过多,且公用的数据和数据操作也多,就考虑使用统一的数据管理工具。例如登录后都会用到用户的此状态
    在这里插入图片描述


vuex核心概念

vuex对象中通过state来存储状态,除了state以外还有用来操作state中数据的方法集,以及当我们需要对state中的数据需要加工的方法集等等成员。
成员列表:

  • state 存放状态(全局状态数据) 必填项

  • mutations 对于state成员进行同步修改操作(调试工具)

  • getters 获取state中的数据,类似于组件中的计算属性

  • actions 进行异步操作,异步得到结果后通知mutation修改state成员

  • modules 模块化状态管理,多状态文件管理时使用 开发项目时多为多模块项目

  • 在多模块vuex中会有配置 namespaced:true ->开启命名空间
    在这里插入图片描述
    首先,Vue组件如果调用某个VueX的方法过程中需要向后端请求时或者说出现异步操作时,需要dispatch VueX中actions的方法,以保证数据的同步。可以说,action的存在就是为了让mutations中的方法能在异步操作中起作用。

    如果没有异步操作,那么我们就可以直接在组件内提交状态中的Mutations中自己编写的方法来达成对state成员的操作。不建议在组件中直接对state中的成员进行操作,这是因为直接修改(例如:this.$store.state.name = ‘hello’)的话不能被VueDevtools所监控到。最后被修改后的state成员会被渲染到组件的原位置当中去。


安装与配置

方案1:在使用vue-cli命令创建项目时,勾选上vuex选项,即安装上vuex插件(推荐)
方案2:通过后续的npm来进行安装

npm i -S vuex@3

建立store/index.js文件

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);/* 以插件的方式注入到Vue类中 */

const store = new Vuex.Store({/* 得到Vuex的Store对象 */
    /* 全局状态 必写选项*/
    state:{
        num:100
    }

})

export default store;

然后在main.js中导入Vue配置项当中。
然后在各个组件devtools的vuex中,就可以看见这个数据。

this.$store.state.num
可以利用计算属性来完成对于在vuex中获取state数据的简写


组件中:
<h2>我从vuex中读取数据——————{{$store.state.num}}</h2>
<h2>我从vuex通过计算属性读取数据——————{{data}}</h2>
操作这个数据:
methods:{
    add(){
        this.$store.state.num++
    }
}

通过 Vuex中的计算属性getters获取数据

专门用于获取state状态中的数据,有缓存,只要依赖项不发生改变,那么他就读取缓存。

const store = new Vuex.Store({/* 得到Vuex的Store对象 */
    /* 全局状态 必写选项*/
    state:{
        num:100
    },
    getters:{/* 专门获取state数据 */
        getNum(state){//这里的state就是状态数库
            return state.num>103?"超过103":state.num;
        }
    }
})


使用:
 <h2>我从vuex的getters中读取数据——————{{$store.getters.getNum}}</h2>

操作Vuex中的数据

同步操作mutations

  • state 中的数据,是可以直接写方法methods修改的,注意:是不推荐这种方式修

    • 直接修改,就会不安全 this.$store.state.num++
    • 每个组件实例,都可以通过 this.$store 来访问store对象里的共享数据
  • 修改操作state的数据,要通过mutations中配置的方法,在里面写方法【同步操作】

    • 所有的数据的操作,不要都在外面操作,放在vuex里面操作
    • 第二个也是为了同步操作使得这个devtools开发工具好去捕获数据操作。
    • 在组件中修改,就要通知这个mutations中的方法来操作,通过commit通知,也是同步方式;
mutations:{
	addNum(state,arg=1){//这里的state就是状态数库不变,arg调用时传入的参数,负荷
		state.num += arg;
		//setTimeout(()=>{
        //       state.num += arg;
        //},1000)
	}
}
=============
methods:{
    add(){
        this.$store.commit("addNum",2)/* c参数1:mutations中的那个方法,参数2:传入的参数*/
    }
}

特别需要注意的是store的方法传入为多个参数的时候必须先利用对象的传参方法!!!!

异步操作actions

actions:{
    async addDate(store,arg){
        console.log(arg);
        let data = await get("/mock/data.json");
        /*public是静态资源根目录*/
        /*webpack 中的 devServer 中的express 把public设置为静态资源了*/
    }
}
=======
通过dispath通知actions里执行那个异步方法;
methods:{
    addasync(){
        this.$store.dispatch("addDate","加油你是最棒的");
    }
}

但是我们最终的目的是为了将异步得到的值,传给mutations做同步响应式处理,所以在通过commit通知mutations,执行相应的操作。
伪代码处理:

    state:{
        data:{}
    },
    mutations:{
        addDATA(state,data){
            state.data = data;
        }
    },
    actions:{
        async addDate(store,arg){
            let data = await get("/mock/data.json");
            store.commit("addDATA",data);
        }
    }

mock假数据,我写nodejs服务器;15-mock模拟数据备份


modules模块化

模块化,把state数据拆分到不同的模块中(不同文件中),把原来也在Vue.stroe实例配置中的代码,提取到不同的业务文件中。

export default{
    state:{
        num:100,
    },
    getters:{
        getNum(state){
            return state.num;
        }
    },
    mutations:{},
    actions:{}
}
import count from '@/store/modules/count.js'
import data from '@/store/modules/data.js'
export default{
   modules: {
        count,
        data
    }
}

在这里插入图片描述
命名空间就是这样的做法,将这个空间名放在组件中进行调用。
如果在组件中是:直接调用这个vux状态管理的数据的话,那就需要添加一个模块名或者空间名:
$store.state.count.num
this.$store.state.count.num
但是对于

getters、mutations、actions不会有影响

vuex强制开始命名空间

因为但虽然在不同的模块中,但是状态管理最终是添加在一起的,所以有方法有同名的话仍然会执行这个同名函数:为了避免这种错误,vuex开启了命名空间。

namespaced:true,
export default{
    namespaced:true,
    state:{
        num:100,
    },
    getters:{
        getNum(state){
            return state.num;
        }
    },
}

这样就对getters、mutations、actions三个起到空间作用。
需要加上空间名才能调用:
他在getNum之前加上了空间名:
在这里插入图片描述

 <h2>我从vuex的getters中读取数据——————{{$store.getters["count/getNum"] }}</h2>

this.$store.getters["count/getNum"]
this.$store.commit("count/addNum", 2)

这样就不会发生冲突。


辅助函数mapState、mapGetters、mapActions、mapMutations

使用场景:

  • mapState =》 computed
  • mapGetters =》computed
  • mapMutations =》methods
  • mapActions =》 methods

 在没有强制开启命名空间时的辅助函数写法

mapState

mapState返回的是一个对象,对象里面有一个方法。
computed: {
	...mapState({
	   data:state=>state.count.num
	})
	//或者
	...mapState(["count"])
}
数组中的元素,如果有模块化,则为modules中key的名称。
......mapState(["count"])
返回值是一个:{ "num": 100 }对象
如果要用它的话:

<h2>我从vuex中读取数据——————{{ $store.state.count.num }}</h2>
<h2>我从vuex通过计算属性读取数据——————{{ data }}</h2>
<h2>我从vuex的getters中读取数据——————{{$store.getters["getNum"] }}</h2>
<h2>我从vuex的mapState中读取数据——————{{count.num }}</h2>

mapGetters

这个方法在未强制开启命名空间时这样使用。

...mapGetters(["getNum"])
返回一个vux里的getters里的方法:这个方法也就是参数指向的getter对象的方法名称。

...mapGetters({
    getnum:"getNum"
 })
这种对象写法就可以将getters里的计算属性重新命名为key值,而这个value值就是:getters配置方法名称。

 有命名空间的写法
注:模块化后,开启了namespaced:true 配置后,注意方法的调用有2个参数

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到