路由和API自动导入

路由和API自动导入

路由自动导入

路由 routes 目录结构为

  • src
    • routes
    • index.js
    • modules
      • layout
        • index.js
      • main
        • index.js

在layout/index.js里面的路由写法

// routes/modules/layout/index.js
import Layout from '@/views/Layout/Layout.vue'
import Home from '@/views/Layout/Home.vue'
import Cart from '@/views/Layout/Cart.vue'
import Category from '@/views/Layout/Category.vue'
import MySpace from '@/views/Layout/MySpace.vue'

export default [
  {
    path: '/',
    redirect: 'home',
    component: Layout,
    children: [
      {path:'/home', component: Home},
      {path:'/category', component: Category},
      {path:'/cart', component: Cart},
      {path:'/myspace', component: MySpace}
    ]
  },
]

将路由按业务逻辑和功能划分分成模块后,就所有模块的路由都进行拆分到了 modules/ 文件夹下,每个文件中只需要导出当前模块用到的路由配置。这个时候我们只需要导入所有模块的内容汇总到 index.js 中即可
在这里插入图片描述

但是我们会发现我们在 index.js 中会反复的进行 import ... from ... 导入所有配置的路由模块,模块一多那么这些的 import 语句也就越多。

所以就需要用到路由的自动导入。由于项目用的是vite,所以就使用vite自带的 import.meta.glob 批量导入路由。

首先,定义路径模式,常见的路径模式有

  • 匹配某个文件夹下的所有 .js 文件:./path/*.js
  • 匹配某个文件夹及其子文件夹下的所有 .vue 文件:./path/**/*.vue
  • 排除某个文件夹下的某个文件:./path/!(*.md)

再调用 import.meta.glob 方法来导入匹配的模块,下面是导入同一文件路径 routes 下 modules 文件夹及其嵌套的全部子文件夹下的所有 index.js 文件。

该方法返回一个对象,其中每个键都是匹配到的模块路径,每个 js 文件中导出的内容(包括 default),在这里是路由对象。

 // routes/index.js
 // route模块自动导入
const routeModules = import.meta.glob('./modules/*/*.js', { eager: true })
 
 // 通过 reduce 去搜集所有的模块的导出内容
 const configRoutes = Object.keys(routeModules).reduce((routes, filepath) => {
   // 导出的对象中有一个属性:default,可以获取到默认导出的所有内容
   const value = routeModules[filepath].default;
 
   // 我们判断导出的是不是数组,是则进行拓展解构
   if (Array.isArray(value)) {
     routes.push(...value); 
   } else {
     // 否则直接加到routes中
     routes.push(value);
   }
   return routes;
 }, []);

// 直接导出所有模块配置的路由
export const router = createRouter({
  history: createWebHistory(),
  routes: configRoutes
})

export default router

所得到的 configRoutes 是一个数组包对象,其中数组中的对象就代表了每一个路由:

在这里插入图片描述

API自动导入

同样将API按照业务逻辑划分为模块,但这就需要在最外层的index.js中会反复的进行 import ... from ... 导入所有模块。所以我们同样利用 vite 自带的 import.meta.glob 批量导入API。

接口 apis ,目录结构为

  • src
    • apis
    • index.js
    • modules
      • user
        • index.js

apis文件user/index.js的文件结构和内容为:

import { request } from '../../request'

export default {
  login: async query => {
    return await request('post', '/v1_0/authorizations', query)
  }
}

第一步,先在request.js中引入axios,并设置默认请求拦截器和响应拦截器:

// request.js
import axios from 'axios'
import Storage from '@/storage/index.js'

const http = axios.create({
  baseURL: 'http://geek.itheima.net',
  timeout: 5000
})

// 添加请求拦截器
http.interceptors.request.use((config)=> {
  // 在config中的请求头注入token数据
  const token = Storage.user.getToken()
  if (token) {
    config.headers.Authorization = `Bearer ${token}`
  }
    return config
  }, (error)=> {
    return Promise.reject(error)
})

// 添加响应拦截器
http.interceptors.response.use((response)=> {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response.data
  }, (error)=> {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error)
})

const request = (method, url, query) => {
  return http({
    method,
    url,
    data: query
  })
}

export { request }

第二步,在index.js文件里面通过调用 import.meta.glob 方法来导入匹配的模块,导入同一文件路径 apis 下 modules 文件夹及其嵌套的全部子文件夹下的所有 index.js 文件

// api模块自动导入
const apiModules = import.meta.glob('./modules/*/index.js', { eager: true })

const Service = {}
Object.keys(apiModules).forEach(path => {
  const key = path.split('/')[2]
  Service[key] = apiModules[path].default
})

export default Service

apiModules的键还是路径名,值每个模块中 export 的内容,在这里是包含着 api 函数的对象。最终得到的 Service 是一个对象,键为模块名称,值为模块对应的包含 api 函数的对象。

所以在页面和组件中调用 api 可以

  1. 通过 导入 Service :import Service from '@/apis/index.js’;
  2. 然后在 js 代码中 await Service.user.xxx(query) 来调用服务端接口
  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值