动态加载-简化调用API

调用API

// require.context 动态加载模块文件夹下的所有 .js 文件
const modulesFiles = require.context('./modules', true, /\.js$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
	// 通过正则表达式提取每个模块文件的名称,并将这些模块加载到一个对象中
    const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
    const value = modulesFiles(modulePath)
    modules[moduleName] = value.default
    return modules
}, {})

export default {
	//  将所有加载的模块挂载到 Vue 应用实例的全局属性 $api 上
    install(app){
        app.config.globalProperties.$api = modules;
    }
}

好处:

  • 动态加载:可以自动加载指定目录下的所有模块,无需手动导入每一个模块。
  • 简化调用:在 Vue 组件内部可以直接通过 this.$api 访问到所有的 API 方法,提高了开发效率。

主应用文件 main.js

import { createApp } from 'vue'
import App from './App.vue'
import api from './api'

const app = createApp(App)
api.install(app)
// api.use(app)
app.mount('#app')

现在在任何 Vue 组件中,都可以直接使用 API 方法

methods: {
  async fetchData() {
    const homeData = await this.$api.app.fetchHomeData()
    const userInfo = await this.$api.user.fetchUserInfo(1)
    // ...
  }
}

在 Vue 中,api.install(app)api.use(app) 都是用来将自定义的功能或插件集成到 Vue 应用中的方法。虽然这两个方法在功能上非常相似,但在不同的库或框架中可能会有所不同。下面分别解释这两种用法:

  • api.install(app)

用途: install 方法通常用于 Vue 插件的安装。它接收一个 Vue 应用实例作为参数,并将插件的功能添加到该应用实例上。
示例: 在你的代码中,api.install(app) 将所有 API 方法注册到了 Vue 应用实例的全局属性 $api 上,使得这些 API 方法可以在任何 V u e 组件 Vue 组件 Vue组件中通过 this.$api 访问。

  • api.use(app)

用途: use 方法也是用于将插件或功能集成到 Vue 应用中的。它同样接收一个 Vue 应用实例作为参数,并执行相应的初始化操作。
示例: 虽然你的代码中没有使用 api.use(app),但在其他情况下,如果一个插件或库提供了 use 方法,那么它可能是用来完成类似的任务——将插件的功能集成到 Vue 应用中。

  • 总结

相同点:

install 和 use 都是用来将插件或功能集成到 Vue 应用中的方法。

不同点:

install 方法更常见于 Vue 的官方文档和社区实践中,用于插件的安装。
use 方法在某些第三方库中可能会使用,但不是 Vue 官方推荐的标准命名。

登录

        login() {
        	//  this.$refs["loginForm"].validate() 方法 验证登录表单是否有效
            this.$refs["loginForm"].validate((valid) => {
                if (valid) {
                	// 设置加载状态:如果表单验证通过,则设置 this.loginLoading 为 true,表示正在进行登录操作。
                    this.loginLoading = true;
                    // 发起登录请求: 使用 $api["system/auth"].login(this.loginForm) 发起登录请求,其中 this.loginForm 是包含登录信息的对象(如用户名和密码)。
                    this.$api["system/auth"].login(this.loginForm).then((res) => {
                    	// 处理响应
                    	// 成功响应时:
                    	// 从响应数据中获取 token,并调用 setToken 函数存储 token。
                        setToken(res.data.token);
                        // 调用 this.setUser 和 this.setNetwork 方法来更新用户信息和网络信息。
                        this.setUser(res.data.user);
                        this.setNetwork(res.data.user.network);
                        this.$router.push("/home")
                        // 显示一条消息提示,类型根据登录结果确定。
                        ElMessage({
                          type: res.data.msg === "login success" ? "success":"warning",
                          message: res.data.msg,
                        });
                    })
                    // 不管成功还是失败,最后都会调用 .finally() 方法来重置 this.loginLoading 为 false,表示登录操作已完成。
                    .finally(() => {
                        this.loginLoading = false;
                    });
                }
            });
        },

mapActions

mapActions 是 Vuex 提供的一个辅助函数,用于将 store 中定义的 actions 映射到组件的 methods 中,使得组件可以直接调用这些 actions 而不需要通过 this.$store.dispatch

  • 假设有以下 Vuex store 的结构:
// store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    modules: {
        user: {
            namespaced: true,
            actions: {
                aSetUser(context, payload) {
                    // 更新用户信息
                    context.commit('mSetUser', payload)
                }
            }
        },
        network: {
            namespaced: true,
            actions: {
                setNetwork(context, payload) {
                    // 更新网络信息
                    context.commit('mSetNetwork', payload)
                }
            }
        }
    }
})
  • 在 Vue 组件中,可以这样使用这些映射的 actions:
<template>
    <div>
        <button @click="setUser">Set User</button>
        <button @click="setNetwork">Set Network</button>
    </div>
</template>

<script>
export default {
    methods: {
        ...mapActions({
            setUser: "user/aSetUser",
            setNetwork: "network/setNetwork",
        }),
        setUser() {
            this.setUser({ name: 'John Doe', age: 30 });
        },
        setNetwork() {
            this.setNetwork('5G');
        }
    }
}
</script>

Vuex

  1. Actions 是 Vuex 中用于处理异步操作的部分。
  2. Mutations 用于直接改变状态,而 actions 通过提交 mutations 来间接改变状态。
  3. Namespaces 可以帮助组织和隔离 actions。
  4. Dispatch 用于触发 actions。
  5. mapActions 辅助函数可以简化 actions 的调用。
  • Actions 的作用
  1. 异步操作: Actions 可以包含任何异步操作,如 AJAX 请求、定时器等。
  2. 提交 Mutations: Actions 通过提交 mutations 来改变状态,而不是直接修改状态。
  3. Context: Actions 接受一个与 store 实例具有相同方法和属性的 context 对象作为第一个参数,通常可以通过 context.commit 来提交 mutations。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
  	// incrementAsync 是一个 action,它会在一秒后提交一个 increment mutation。
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  }
});
  • Namespace
    当 Vuex store 被组织成模块时,可以使用命名空间来隔离 actions
// store.js
// aSetUser 和 setNetwork 分别属于 user 和 network 模块
// 并且由于设置了 namespaced: true,所以它们的调用需要加上模块的前缀。
export default new Vuex.Store({
  modules: {
    user: {
      namespaced: true,
      actions: {
        aSetUser(context, payload) {
          // 更新用户信息
          context.commit('mSetUser', payload);
        }
      }
    },
    network: {
      namespaced: true,
      actions: {
        setNetwork(context, payload) {
          // 更新网络信息
          context.commit('mSetNetwork', payload);
        }
      }
    }
  }
});
  • this.$store.dispatch

在 Vue 组件中,可以通过 this.$store.dispatch 方法来触发 actions。

methods: {
  incrementAsync() {
    this.$store.dispatch('incrementAsync');
  },
  setUser() {
    this.$store.dispatch('user/aSetUser', { name: 'John Doe', age: 30 });
  },
  setNetwork() {
    this.$store.dispatch('network/setNetwork', '5G');
  }
}
  • mapActions

使用 mapActions 辅助函数来简化调用

methods: {
  ...mapActions([
    'incrementAsync',
    'user/aSetUser',
    'network/setNetwork'
  ]),
  incrementAsync() {
    this.incrementAsync();
  },
  setUser() {
    this.aSetUser({ name: 'John Doe', age: 30 });
  },
  setNetwork() {
    this.setNetwork('5G');
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值