美文网首页技术资料前端开发那些事儿vue
vue3 + vite + ts + antdv 搭建后台管理基

vue3 + vite + ts + antdv 搭建后台管理基

作者: 前端_逗叔 | 来源:发表于2021-06-29 15:19 被阅读0次
    文章封面.jpg

    最近公司官网需要一个后台管理系统,一直在看vue3,但是都没有在实际项目中使用过,正好就借此机会来踩踩坑。

    点击这里查看源码

    环境准备

    • Node.js v14.9.0
    • npm v6.14.8
    • vscode

    搭建 Vite 项目

    Vite中文网 (vitejs.cn)
    Vite 需要 Node.js 版本 >= 12.0.0

    // 安装vue-ts 模板
    npm init @vitejs/app vue3-template --template vue-ts
    
    npm run dev  // 启动开发服务器
    npm run build // 为生产环境构建产物
    npm run serve // 本地预览生产构建产物
    

    启动项目的第一感觉就是一个字 ,还没反应过来就已经跑起来了

    安装 vue-router

    起步 | Vue Router (vuejs.org)

    npm install vue-router@4
    
    1. 首先在 src 目录下创建 router 文件夹, 为了项目后期更好的可读性和维护,这里将路由进行模块化管理, 对开发和调试都会有很大帮助,目录结构如下:

      image.png
    2. index.ts文件

    import { createRouter, createWebHashHistory } from "vue-router"
    
    import Common from "./modules/common"
    import Movie from "./modules/movie"
    
    const routes = [
      Movie,
      ...Common
    ]
    
    const router = createRouter({
      history: createWebHashHistory(),
      routes
    })
    
    export default router
    
    1. common.ts 文件
    /**
     * @description 公共的一些路由,不属于功能模块的都放这里统一管理
     * @author 逗叔 */
    
    import Layout from "@/layout/index.vue";
    
    //首页路由
    const Home = {
      path: "/",
      component: Layout,
      meta: {
        title: "首页"
      },
      redirect: { name: "Home" },
      children: [
        {
          path: "/home",
          name: "Home",
          component: () => import("@/views/home/index.vue"),
          meta: {
            title: "首页"
          }
        }
      ]
    };
    
    //登录、快速登录、选择应用
    const Login = [
      {
        path: "/login",
        name: "Login",
        component: () => import("@/views/login/index.vue"),
        meta: {
          title: "登录"
        }
      }
    ];
    
    //其他路由、无权限、日志、404
    const Others = [
      {
        path: "/401",
        name: "Error401",
        component: () => import("@/views/error-page/401.vue"),
        meta: {
          title: "无权限"
        }
      },
      {
        path: "/404",
        name: "Error404",
        component: () => import("@/views/error-page/404.vue"),
        meta: {
          title: "404"
        }
      },
      {
        path: "/500",
        name: "Error500",
        component: () => import("@/views/error-page/500.vue"),
        meta: {
          title: "500"
        }
      },
      {
        path: "/:pathMatch(.*)",
        redirect: '/404'
      }
    ];
    
    let Common = [Home, ...Login, ...Others];
    
    export default Common;
    
    

    这里需要注意的是 * 通配符 需要改为 /:pathMatch(.*)

    1. 修改 main.ts 文件

      image.png
    2. 使用

    import { useRouter } from "vue-router";
    setup() {
        const router = useRouter();
        router.push({ name: "Home" });
    }
    

    安装 Vuex

    安装 | Vuex (vuejs.org)

    npm install vuex@next --save
    
    1. src 目录下创建 store 文件夹

      image.png
    2. index.ts 文件

    import { InjectionKey } from 'vue'
    import { createStore, Store } from 'vuex'
    import getters from './getters'
    
    export const key: InjectionKey<Store<any>> = Symbol()
    
    import common from './modules/common'
    
    // 创建一个新的 store 实例
    export const store = createStore({
      modules: {
        common
      },
      getters
    })
    
    1. getters.ts 文件
    const getters = {
      token: (state:any) => state.common.token
    }
    
    export default getters
    
    1. modules/common.ts 文件
    export default {
      namespaced: true,
      state: {
        token: ''
      },
      mutations: {
        //存储token
        setToken(state: { token: string }, token: string) {
          state.token = token
          localStorage.token = token
        }
      },
      getters: {
        //获取token方法
        getToken(state: { token: string | null }) {
          if (!state.token) {
            state.token = localStorage.getItem('token')
          }
          return state.token
        }
      }
    }
    
    1. 修改 main.ts 文件

      image.png
    2. 使用

    import { useStore } from 'vuex'
    import { key } from '../../store'
    setup() {
        const store = useStore(key)
        store.commit("common/setToken",res.data)
    }
    

    这里需要注意 useStore 要传一个 key,不然获取不到的 store,网上的教程一大堆都是获取不到的

    安装 Antdv

    起步 | Ant Design Vue (antdv.com)

    npm i --save ant-design-vue@next
    

    按需加载组件

    1. 安装 vite-plugin-style-import
    npm i vite-plugin-style-import -D
    
    1. 修改 vite.config.ts 文件
      image.png
     styleImport({
          libs: [{
            libraryName: 'ant-design-vue',
            esModule: true,
            resolveStyle: (name) => {
              return `ant-design-vue/es/${name}/style/css`;
            },
          }]
        })
    
    1. src 目录下创建 plugins 文件夹
      image.png

    ant-design-vue/index.ts 内容

    import type { App } from "vue"
    
    import { Layout, Menu, Breadcrumb, Form, Result, Button, Input, Checkbox, message } from 'ant-design-vue';
    
    const antdComponents = [
      Layout,
      Menu,
      Breadcrumb,
      Form,
      Result,
      Button,
      Input,
      Checkbox,
    ]
    
    // 应用组件
    export function useAntd(app: App) {
      // 循环应用
      antdComponents.forEach(com => {
        app.use(com)
      })
      app.config.globalProperties.$message = message;
    }
    
    1. 修改 main.ts 文件
      image.png

    封装 Axios

    npm install axios
    
    1. src 目录下创建 utils 文件夹 和 api 文件夹

      image.png
    2. utils/request.ts文件

    /**axios封装
     * 请求拦截、相应拦截、错误统一处理
     */
    import axios from "axios";
    import { message } from "ant-design-vue";
    
    // 创建axios实例
    const instance = axios.create({
      // baseURL:"",
      // timeout: 10 * 1000,
      // withCredentials: true,
      headers: {
        "Content-Type": "application/json"
      }
    });
    
    // 请求拦截器
    instance.interceptors.request.use(
      config => {
        // 全局添加token
        // config.headers["Authorization"] = token;
        return config;
      },
      error => {
        return Promise.reject(error);
      }
    );
    
    // 响应拦截器
    instance.interceptors.response.use(
      response => {
        const data = response.data;
        // code 是后端返回的业务状态码 {code:0,data:{},message:"成功"}
        if (data.code !== 0) {
          message.error(data.message)
          return Promise.reject(new Error(data.message || "Error"));
        } else {
          return data;
        }
      },
      error => {
        const { response } = error;
        switch (response.status) {
          //404 资源不存在
          case 404:
            message.error("网络请求不存在");
            break;
          // 系统错误
          case 500:
            message.error(response.data.errorMessage || "服务器异常,请稍后重试")
            break;
          // 其他错误,直接抛出错误提示
          default:
            message.error(response.data.errorMessage || "请求出现未知错误,请稍后重试")
        }
        return Promise.reject(error);
      }
    );
    
    export default instance;
    
    
    1. api/base.ts
    /**
     * 接口域名的管理
     * 解决多域名接口的情况
     */
    const base = {
      baseUrl: "/api/vue3-template",
      //继续写其他域名的接口
    };
    
    export default base;
    
    1. api/common.ts
    /**
     * 测试接口列表
     */
    
    import base from "./base"; // 导入接口域名列表
    import axios from "../utils/request"; // 导入request中创建的axios实例
    
    const common = {
      /**
       * 登录
       * @param params 
       */
      login(params: any) {
        return axios.post(`${base.baseUrl}/login`, params)
      }
    };
    
    export default common;
    
    
    1. api/index.ts
    /**
     * api接口的统一出口
     */
    
    // 测试接口
    import common from "./common";
    
    export default {
      common,
    };
    
    1. api挂载到全局
      image.png
    import Api from "./api"
    //全局挂载 Api接口
    app.config.globalProperties.$api = Api;
    
    1. 使用
    import { reactive, ref, defineComponent, toRaw, getCurrentInstance } from "vue";
    // @ts-ignore
    const { proxy } = getCurrentInstance();
    const api = proxy.$api;
    // 调用登录接口
    api.common.login(toRaw(loginForm))
              .then((res: any) => {
                  message.success("登录成功");
                  store.commit("common/setToken",res.data)
                  router.push({ name: "Home" });
                })
                .catch((err: any) => {
                  message.error("登录失败");
                });
    

    相关文章

      网友评论

        本文标题:vue3 + vite + ts + antdv 搭建后台管理基

        本文链接:https://www.haomeiwen.com/subject/jfaqyltx.html