Monorepo项目管理,vue3+ts+antd+pinia后台管理模板搭建记录(二)

860 阅读3分钟

写在开头

之前的连接

Monorepo项目管理,vue3+ts+antd+pinia后台管理模板搭建记录(一)

包含内容

  1. 路由搭建
  2. 两个平台复用一份路由权限配置
  3. eslint的一些配置
  4. antd等一些组件插件安装

PS

以下步骤主要在project2的文件夹下进行操作,所以project1里面的部分文件可能没有修改。

正文

eslint配置

依赖

pnpm i -D eslint eslint-plugin-vue @typescript-eslint/parser @typescript-eslint/eslint-plugin -w

.eslintrc.js 配置我直接去网上抄了一份

module.exports = {
  root: true,
  globals: {
    defineEmits: 'readonly',
    defineProps: 'readonly',
  },
  extends: [
    'plugin:@typescript-eslint/recommended',
    'plugin:vue/vue3-recommended',
  ],
  parserOptions: {
    parser: '@typescript-eslint/parser',
    ecmaVersion: 2020,
  }
}

antd安装和按需引入

pnpm i ant-design-vue unplugin-vue-components -w

antd文档上按需引入在vite下推荐使用unplugin-vue-components。

vite.config.js下添加

import Components from 'unplugin-vue-components/vite'
import {
  AntDesignVueResolver,
} from 'unplugin-vue-components/resolvers'
...
  plugins: [
    ...
    Components({
      resolvers: [
        AntDesignVueResolver(),
      ],
    })
  ]

在main.ts中全局引入message的样式,因为unplugin-vue-components按需加载不能处理非组件模块

import 'ant-design-vue/es/message/style/css';

配置路径别名

安装依赖

pnpm i @types/node -w -D

tsconfig.json下添加

"compilerOptions": {
   ...
   "baseUrl": ".",
   "paths": {
     "@/*": ["src/*"]
   }
 },

vite.config.ts下添加

import { resolve } from 'path'

...
 resolve: {
   alias: {
       "@": resolve(__dirname, 'src'), // 路径别名
   },
   extensions: ['.js', '.json', '.ts', '.vue']
 }

安装pinia和vue-router

pnpm i pinia vue-router -w

配置pinia

src下创建store文件下,新建index.ts和modules文件夹

main.ts下添加

import {createPinia} from 'pinia'

const app = createApp(App)
const pinia = createPinia()
app.use(pinia)

modules下文件的内容

import { defineStore } from 'pinia'

const userSotre = defineStore('main', {
  state: () => {
    return {
      userName: '',
      token: '',
      asyncRoutes: []
    }
  },
  getters: {},
  actions: {
    login() {
      return new Promise(resolve => {
        this.userName = 'user'
        this.token = 'token'
        resolve('')
      })
    }
  }
})

export default userSotre

index.ts下

import userStore from "./modules/auth";

export {
  userStore
}

配置router

src下创建router文件下,新建index.ts和modules文件夹,index.ts如下

import { createRouter, createWebHashHistory } from "vue-router"

import Auth from "./modules/auth"

const routes = [
  {
    path: "/404",
    component: () => import("@/views/error-page/404.vue"),
    meta: {
      title: "404"
    }
  },
  ...Auth,
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

记得在main.ts里引入router,modules主要为了更好管理分类页面。其他代码就不贴出了,直接可以在git项目中看,这边没有设置/:pathMatch(.*)的重定向到404,而是会在获取后端路由后添加。

编写router.beforeEach来控制路由

在packages下新建一个utils文件夹,并npm init初始化,连接两个项目的依赖

pnpm add @test/utils -r --filter @test/two

在utils下创建permission.ts

import { getToken } from './token'
import { Router, RouteRecordRaw } from 'vue-router'

interface VoidFun {
  ():void  
}

interface PromiseFun {
  (): Promise<RouteRecordRaw[]>
}

interface Store {
  asyncRoutes: object[],
  getUserInfo: PromiseFun,
  resetToken: VoidFun
}

function initPermission(router: Router, store: Store, whiteList: string[]) {
  router.beforeEach(async (to, from, next) => {
    document.title = <string>to.meta.title
    const hasToken = getToken()

    if (hasToken) {
      if (to.path === '/login') {
        next({ path: '/' })
      } else {
        const hasAsyncRoutes = store.asyncRoutes && store.asyncRoutes.length > 0
        if (hasAsyncRoutes) {
          next()
        } else {
          try {
            const asyncRoutes = await store.getUserInfo()
            asyncRoutes.forEach((route: RouteRecordRaw) => {
              router.addRoute(route)
            })
            next({ ...to, replace: true })
          } catch (error) {
            await store.resetToken()
            next(`/login?redirect=${ to.path }`)
          }
        }
      }
    } else {
      if (whiteList.indexOf(to.path) !== -1) {
        next()
      } else {
        next(`/login?redirect=${ to.path }`)
      }
    }
  })
}

export default initPermission

main.ts里引入initPermission

import { createApp } from 'vue'
import App from './App.vue'
import 'ant-design-vue/es/message/style/css';
import router from './router'
import { createPinia } from 'pinia'
import { userStore } from './store';
import { initPermission } from '@test/utils'
const app = createApp(App)
const pinia = createPinia()
app.use(pinia)

const store = userStore()
const whiteList = ['/login']
initPermission(router, store, whiteList)

app.use(router)

app.mount('#app')

其他依赖

pnpm i vite-plugin-vue-setup-extend -D -w

// vite.config.ts下

import VueSetupExtend from 'vite-plugin-vue-setup-extend'

...
  plugins: [
    ...
    VueSetupExtend()
  ],

结束

  1. gitee地址 依旧是非master分支,保留这篇文章结束的所有代码状态。

  2. packages/utils中涉及到的rollup打包ts没有细讲,相关配置和依赖可以直接看源码

  3. 所有操作都在packages/project2中完成的,所以project1中的代码没有改动

  4. 后续把后台模板样式搭完