Skip to content
    在 Opshell 的 Blog 中:
  • 目前已分享 70 篇文章
  • 還有 114 個坑正在填補中
  • 已有: Loading 次觀看
  • 已有: Loading 個人來過
✍️ Opshell
📆 Last Updated:8/23/2024Created:2022/09/26
👀 已被閱讀: Loading

[Day26]: 這才不是PS5 - axios & router

Day 26 Banner

Axios X Router

這才不是PS5這是Plash Speed 5────────────────── By 장삐쭈

目標:安裝 axios + router


過程:

  • axios 安裝、使用

為啥要裝?別鬧了axios捏?

yarn add axios -D

由於axios已經自帶.d.ts了, 所以你啥都不用做就可以直接用了。


  • vue router

    安裝當起手式沒問題吧?

     yarn add vue-router@next -D

    vue router本身提供了宣告檔案, 所以開箱即用~~(真是太好了)~~

  • 1. 改寫router

    src下面建立router目錄, 新增兩個檔案index.tsroutes.ts

  • index.ts

    原先JS長這樣:

    javascript
     import { createRouter, createWebHistory } from "vue-router";
     import axios from "axios";
     import store from "../store";
    
     import routes from "./routes.js"; // 路由列表
    
     const router = createRouter({
       history: createWebHistory(process.env.BASE_URL),
       routes,
     });
    
     // 在 login 頁面還不能完全做到攔截不正確登入訊息,我們必須在router.js做更進一步處理
     router.beforeEach(async (to, from) => {
       store.commit("setRouteFrom", from);
       store.commit("startLoading"); // 開啟遮罩
       // 目的路由在meta上是否有設置requireAuth: true
       if (to.meta.requireAuth) {
          const isLogin = store.state.user.isLogin;
    
          if (isLogin) {
                const token = localStorage.getItem("token");
                axios({
                   url: "/api/auth/verify",
                   method: "GET",
                   headers: { Authorization: `Bearer ${token}` },
                }).then((res) => {
                   if (res.status == 200) {
                      if (res.data.status == "Success") {
                            localStorage.setItem("token", res.data.data);
                            store.commit("setRedirect", "");
                      } else {
                            localStorage.setItem("token", "");
                            return { name: "Login" };
                      }
                   } else {
                      localStorage.setItem("token", "");
                      return { name: "Login" };
                   }
                })
                .catch(() => {
                   localStorage.setItem("token", "");
                   return { name: "Login" };
                });
          } else {
                localStorage.setItem("token", "");
                return { name: "Login" };
          }
       }
    
       store.commit("setRouteTo", to);
     });
    
     export default router;

    恩,沒錯紅通通一片, 我們把它改寫成這樣:


  • 調整store引用:

    typescript
     // @/router/index.ts
     import { store } from "@/store";

    由於/router/index.ts沒有setup也不是components 所以不能inject,要換成另一種store引用的方式。


  • 調整環境參數:

    typescript
     const router = createRouter({
       // history: createWebHistory(process.env.BASE_URL),
       history: createWebHistory(import.meta.env.BASE_URL),
       routes,
     });

    是的,Vite並不能用process.env.BASE_URL, 但是他另外提供了import.meta.env可以用,參考


  • 調整store.commit用法

    typescript
     store.commit("route/setRouteFrom", from);
     store.commit("route/startLoading"); // 開啟遮罩

    像這樣在前面加上namespace


  • 調整store/route.ts型別:

    typescript
     export interface iRouteState {
       isLoading: Boolean, // 是否處於Loading狀態
       redirect: string,
       route: {
          from: any,
          to: any
       },
       pageData: iPageData,
     }

    由於我們有安裝vue-router了, 當然馬上把any換掉:

    typescript
     import { RouteLocationNormalized } from "vue-router"; // 引用 vue-router 型別
    
     export interface iRouteState {
       isLoading: Boolean, // 是否處於Loading狀態
       redirect: string,
       route: {
          from: any,
          to: any
       },
       pageData: iPageData,
     }
    改型別

    下面兩個mutationsfromto也別忘了。


  • routes.ts

    老樣子提供原碼:

    javascript
     const routes = [
       {
          name: "Login",
          path: "/login",
          component: () => import("../views/Login.vue"),
          meta: { title: '登入' },
       },
       // ... 省略一堆
     ];
    
     export default routes;

    這時候就會警告說你用any, 但我們知道其實我們有固定的格式, 所以宣告一下:

    typescript
     interface iRoute {
       name: string,
       path: string,
       component: () => {},
       meta: {
          title?: string,
          requireAuth?: boolean,
       }
     }
    
     const routes:iRoute[] = [
       {
          name: "Login",
          path: "/login",
          component: () => import("@/views/Login.vue"),
          meta: { title: '登入' },
       }
     ];

  • 2. 修改main.ts

    typescript
     import router from './router'
    
     app.use(router)

    恩,就這樣沒問題了,是不是很簡單? 什麼? 覺得今天很空虛? 那我們多講點其他的。


  • AutoImport

    什麼? 你說這講過了? 只說怎麼安裝沒說怎麼用阿! 例如上面的axios和之前的Base64要怎麼自動載入呢? 我們來到vite.config.ts

    typescript
     export default defineConfig({
       // ... 省略一堆
       plugins: [
          vue(), vueJsx(),
          AutoImport({
             // targets to transform
             include: [
                /\.[tj]sx?$/, // .ts, .tsx, .js, .jsx
                /\.vue$/, /\.vue\?vue/, // .vue
                /\.md$/, // .md
             ],
    
             // global imports to register
             imports: [
                // presets
                'vue',
                'vue-router',
                'vuex',
                // custom
                {
                   '@vueuse/core': [
                      'useMouse', // named imports
                      ['useFetch', 'useMyFetch'], // alias
                   ],
                   'axios': [ // 整包 axios import
                      ['default', 'axios'], // import { default as axios } from 'axios',
                   ],
                   'js-base64': [ // import Base64 單一功能
                      'Base64'
                   ],
                },
             ],
          // ... 省略一堆
          }),
          Components({
             dirs: ['src/components'], // 指定组件位置,預設是src/components
             dts: 'src/types/components.d.ts', // 配置文件生成位置
             resolvers: [NaiveUiResolver()]
          })
       ],
       // ... 省略一堆
       build: {
          outDir: '../WebAdmin/', // 指定輸出位置(相對於project根目錄).
       }
    });

    像上面plugins.imports裡的這樣,就會按需自動import囉~


小結:

今天連router都處理好了, 明天應該就能正式開始寫點什麼了, 大家明天見。

Released under the MIT License.