有关vuex 详细使用方法

vuex 序言

鉴于我认识 的小白们不会用vuex,我引用官网对vuex的介绍,以及我整理好的使用方法,详细给大家讲解一下

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

可以理解成是一个单实例,更简单的说像是一个闭合函数,你只能使用外部的变量,内部方法来改变内部的状态,并且返回的内部处理状态,或者你干脆把vue理解成一个大对象,vuex的状态是一直存在的,你随时去用他存好的状态,并且可以跨组件的使用它里面的状态,跳路由也不会影响你存好的状态,只有你调用vuex内部方法才会改变内部状态。好的也许你已经知道他能干嘛了,我开始了解一下vuex跟你的组件之间有什么联系。

以下是一个表示“单向数据流”理念的简单示意:

在这里插入图片描述
这是官网上的一张图,我直接引用了,vuex官网教程链接

这个状态自管理应用包含以下几个部分:

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view上的用户输入导致的状态变化。

更多关于官网上也详细讲解了 为什么要是用vuex,最后你一定会知道为啥要使用vuex ,

总结:好用 + 好用 + 好用

vuex的应用

光说好用你也不知道咋就那么好用呢?
那我就用两个例子先简单说一下并且告诉你,他的好用之处,首先来了解vuex 的结构,index他的基本结构。

import Vue from "vue";
import Vuex from "vuex";
import apiUrl from "../request/apiUrl";
// 独立的模块
import contacts from "./modules/contacts"; // 联系人
import APIglobal from "@/request/api/global";
// 把所有配置的结构地址,都配置到stroe中
let apiList = {};

function setNewApiList(data) {
    for (let key in data) {
        if (typeof data[key] === "string") apiList[data[key]] = false;
        else setNewApiList(data[key]);
    }
}

setNewApiList(apiUrl);

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        Loading: { ...apiList }, // 所有接口请求状态

        // 全局信息
        global_orgclasses: [], // 行业列表
    },
    getters: {
        // 获取对应接口请求状态 true 请求中 false 请求结束
        getLoading: (state) => (url) => {
            for (let key in state.Loading) {
                if (key === url) {
                    return state.Loading[key];
                }
            }
            return false;
        },
    },
    mutations: {
        // 设置loading中对应接口的请求状态
        setLoading(state, { url, status }) {
            state.Loading[url] = status;
        },

        // 存储全局用信息
        setGloBalInfo(state, payload) {
            for (let filed in payload) {
                state[`global_${filed}`] = payload[filed]
            }
        },
    },
    actions: {
        // 触发 getLoading 设置
        setLoading({ commit }, data) {
            commit("setLoading", data);
        },

        // 请求行业信息
        getOrgclasses({ commit }, callback) {
            APIglobal.queryOrgclasses().then(res => {
                if (res.result === 0) {
                    commit("setGloBalInfo", { orgclasses: res.data });
                }
                callback(res)
            }).catch(err => {
                callback(err)
            })
        },
    },
    modules: {
        contacts,
    },
});

子模块写法

import APIenterprise from "@/request/api/contacts/enterprise";

const contacts = {
    namespaced: true, 
    // 如果希望你的模块具有更高的封装度和复用性,
    // 你可以通过添加 namespaced: true 的方式使其成为带命名空间的模块。
    // 当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。    
    state: () => ({
        orgExternalContacts: [], // 外部联系人列表
    }),
    getters: {
        getTitle(state) {
            return state.title
        }
    },
    mutations: {
        // 存储联系人模块数据
        setContactsState(state, payload) {
            for (let filed in payload) {
                state[`${filed}`] = payload[filed]
            }
        },
    },
    actions: {
        // 留下一个请求样式
        queryExternalContacts({ commit }, callback) {
            APIenterprise.queryExternalContacts().then(res => {
                if (res.result === 0) {
                    commit("setContactsState", {
                        orgExternalContacts: res.data
                    })
                }
            })
        },
	}
}

export default contacts;

如果你看过我之前写过的 vue全局下的loading设置
那么你会有点小熟悉呢,这里面部分代码出现过

  1. state:单一状态树
  2. getters:过滤属性
  3. mutations:同步改变state方法,你必须使用mutations方法改变state
  4. actions:不能直接修改state,需要借助mutations
  5. modules:子模块,如果你的模块多了,你就需要了

vuex 中方法的使用

## 1. 大致分为两种类型的使用方法
	1-1. 直接使用vuex index 主实例
	1-2. 使用modules子模块

#### 1-1 主实例使用方法

	使用vuex辅助函数 四大金刚
    import { mapState, mapMutations, mapActions, mapGetters } from "vuex";

    这样你就可以使用辅助函数去到state中的状态,和getters,以及触发mutation,actions,
    如需在modules使用辅助函数  下面会介绍

    》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
    mapState / mapGetters 放在computed中,自动计算store中state状态值

    computed: {
        ...mapState({ userid: "userId" }), // 通过别名 userid 调用值
        ...mapState(["userId"]), // 直接通过 userId 调用

        ...mapGetters({ meetingTitle: "getTitle" }),
        ...mapGetters(["getLoading","getName"]),

        // 如果你需要通过条件调用,getter中的过滤函数, 直接用this.$store.getters方法去调用
        loading() {
            // 获取对应接口loading状态,需要传对应接口的接口地址
            return (
                this.$store.getters.getLoading(this.apiUrl.meeting.list) ||
                this.$store.getters.getLoading(this.apiUrl.meeting.delList)
            );
        },
        
        // 第二种 在需要的地方使用 getLoading(条件)
    },
    
	》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
    mapMutations / mapActions
    注意啊!mutation 可是不支持异步操作的,action是可以异步触发mutation的

    methods: {
        ...mapMutations([
        'increment', // 将 `this.increment()` 映射为 `this.$store.commit('increment')`

        // `mapMutations` 也支持载荷:
        'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.commit('incrementBy', amount)`
        ]),
        ...mapMutations({
        add: 'increment' // 将 `this.add()` 映射为 `this.$store.commit('increment')`
        })
    }

    methods: {
        ...mapActions([
        'increment', // 将 `this.increment()` 映射为 `this.$store.dispatch('increment')`

        // `mapActions` 也支持载荷:
        'incrementBy' // 将 `this.incrementBy(amount)` 映射为 `this.$store.dispatch('incrementBy', amount)`
        ]),
        ...mapActions({
        add: 'increment' // 将 `this.add()` 映射为 `this.$store.dispatch('increment')`
        })
    }

#### 1-2 子模块使用方法
	vuex 文档中详细说明了 这些辅助函数的用法,一看便一目了然
    import { createNamespacedHelpers } from "vuex";
    const { mapState, mapMutations, mapActions, mapGetters } = createNamespacedHelpers("meeting");
    // createNamespacedHelpers(子模块名)
	
	辅助函数的使用方法都是一样的
	
	// this.$store 直接使用 不使用应用的方法
    // vuex mutation
    this.$store.commit('setLocation',{key1:"mutation"});

    // vuex module mutation
    this.$store.commit('filter/updateActiveName',"filter/mutation");

    // vuex action
    this.$store.dispatch('updateLocation',{key2:"action"});

    // vuex module actions
    this.$store.dispatch('filter/test',"filter/actions");

vuex 例子1讲解

需求:loading状态的需求,boss提出要求因为之前接口都是根据函数传参的方式来设置loading状态的,我们能不能统一管理一下,不要每次都去设置这烦人的loading状态,ok?
  1. 那么我遇到的第一个问题就是,这么多接口我需要一个地方来存啊
  2. 然后就是,我得写一个公共方法,去设置这个状态
  3. 然后你请求了,你还得告诉loading状态我去请求了,怎么搞用watch监听吗?
  4. 这些问题你都能用方法解决掉,但是操作真的有点复杂了
  5. 管理状态就成了你最大的困难了吧,你创建单实例然后通过全局混入的方式也可以认真的完成这些问题,问题就在于太繁琐了

不过没关系这些步骤你通通都能在vuex中找到方法

  1. 首先vuex提同一个统一管理状态的state
  2. 根据接口地址 getter过滤出你对应接口在state中的状态
  3. 而且你的组件之间可以随时引用vuex
  4. 在axios请求中封装好接口请求时,我设置存在state中对应接口状态,数据返回时取消state中的接口状态
  5. 在computed计算属性的特性下使用接口当前的请求状态

真的崇拜大神们是啥脑回路把这玩意设计的这么好用 哈哈
言归正传啊,vuex主入口上面我已经展示过了,下面我们来看看他们之间的管理状态的流程吧,
在index入口中我已经把所有接口,都存入到state中了

现在你需要的是,如何在请求中触发action的方法改变state的状态

#### 准备程序
## main.js中需要吧vuex挂载到vue实例上

	import store from './store';
	
	// 把apiUrl接口地址,全局混入到每个组件中
	Vue.mixin({
	    data() {
	        return {
	            apiUrl,
	        }
	    }
	})
	new Vue({
	    router,
	    store,
	    render: h => h(App)
	}).$mount('#app')



## axios请求拦截中 引入store 也就是你的vuex啊

	import store from '../store/index';
	let instance = axios.create({
	    // 生产开发环境不固定使用浏览器默认截取到的
	    // baseURL: process.env.VUE_APP_API_URL, // 域名
	    timeout: 1000 * 6,
	    withCredentials: true,
	    transformResponse: [function transformResponse(data) {
	        return jsonlint.parse(data)
	    }],
	});
	
	然后在你axios请求中拦截中,以及返回拦截中 使用触发action方法的 dispatch 触发 setLoading 去改变你接口的状态
	
	instance.interceptors.request.use(
	    config => {
	    	// 省略的很多代码......
		    store.dispatch("setLoading", {
		        url: `${config.url}`, // 接口地址
		        status: true,
		    });
		    // 省略的很多代码......
		}error => Promise.error(error)
	)
	
	返回拦截中 response ,设置接口的状态false
	
	store.dispatch("setLoading", {
        url: `${config.url}`,
        status: false,
    });

到此为止你已经完成改变state状态中对应接口状态了

现在在你的组件中获取你的接口状态

<template>
    <a-spin tip="加载中,请稍后..." :spinning="Loading">
    	<div>你的内容</div>
    </a-spin>
</template>

<script>
export default {
	computed: {
	    // 加载状态
	    Loading() {
	        return (
	            this.$store.getters.getLoading(this.apiUrl.account) || false
	            // this.apiUrl 是我在main.js混入接口,所以以后的每个子组件中都可以直接访问this.apiUrl里的所有接口状态
	        );
	    },
	},
	methods:{
		APi接口方法,请求触发你封装好的改变状态的方法,
		如果请求中接口状态一直是true,
		直到接口返回或者发生错误接口状态改变为false
	}
}
<script>

好了到这里你就完成例子1的需求了

vuex 例子2讲解

因为时间原因我明天继续改进,更新出第二个例子,如果你觉得有帮助了,帮忙点赞收藏谢谢各位前端小伙伴了

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我很乐意为您解释一下Vuex使用方法。 首先,Vuex是一个专门为Vue.js应用程序开发的状态管理模式。它有助于在应用程序中管理和共享状态,例如用户信息、购物车、主题等。Vuex将状态存储在一个单一的对象中,称为“store”。 在Vuex中,我们可以使用以下概念: 1. State:存储应用程序状态的对象。 2. Getter:用于从存储中获取状态的函数。 3. Mutation:更改存储状态的函数。 4. Action:处理异步操作的函数。 下面是Vuex使用方法: 1. 安装Vuex: 在Vue.js项目中,可以使用npm安装Vuex,如下所示: ``` npm install vuex --save ``` 2. 创建一个store: 在应用程序中,使用Vuex.store创建一个单一的状态存储对象。在store中定义一个状态,并在其中定义getter、mutation和action函数。 ``` import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0 }, getters: { getCount: state => { return state.count } }, mutations: { increment (state) { state.count++ } }, actions: { incrementAsync ({ commit }) { setTimeout(() => { commit('increment') }, 1000) } } }) ``` 3. 在组件中使用store: 在Vue.js组件中,可以使用Vuex的mapState、mapGetters、mapMutations和mapActions函数连接store中的状态、getter、mutation和action函数。 ``` <template> <div> <p>Count: {{ count }}</p> <button @click="increment">Increment</button> <button @click="incrementAsync">Increment Async</button> </div> </template> <script> import { mapState, mapMutations, mapActions } from 'vuex' export default { computed: { ...mapState(['count']) }, methods: { ...mapMutations(['increment']), ...mapActions(['incrementAsync']) } } </script> ``` 以上就是Vuex的基本使用方法,希望能对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值