1. 404 頁面實作 1.1. 新增views\404.vue
404.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <template> <div class ="not-found" > <img src ="../assets/404-error.png" alt ="error" > <el-button class ="goback" @click ="$router.push('/')" > The page you are looking for can’t be found. Go home by clicking here!</el-button > </div > </template > <script lang ="ts" > export default {} </script > <style scoped > .not-found { width : 100% ; height : 100% ; overflow : hidden; } .not-found img { width : 100% ; height : 100% ; } .goback { position : absolute; z-index : 9999 ; top : 80% ; left : 31% ; background-color : #fff ; color : rgb (48 , 173 , 211 ); font-size : 1.5rem ; padding : 10px 30px ; border-radius : 5px ; outline : none; border : none; } </style >
1.2. 修改router\index.ts
使用path/:catchAll(.*)
,只要是找不到的都會指向到這
1 2 3 4 5 6 7 8 9 10 11 12 const routes : Array <RouteRecordRaw > =[ { path :"/" , name :"Login" , component :() => import ("../views/Login.vue" ) }, { path :"/:catchAll(.*)" , name :"404" , component :() => import ("../views/404.vue" ) } ]
1.3. 最後結果
2. 登入頁實作 在登入頁實作跳轉到後台介面過程,就必須與後端進行串接工作,而在現行主流前後端分離架構下,Mock Server 的準備是前端工程師開發流程非常重要的技能之一。之前就知道的Mock Server 工具是JSON-Server
,這是一套運行在node js
環境底下的工具。
今天想嘗試另一套「POSTMAN
」軟體,其中也支援這樣的功能,有機會再寫一篇介紹,使用方式與介紹先跳過…總之最後可以取得一個對外的URL提供使用。
2.1. 使用vite.config.ts
進行代理 2.1.1. 修改\vite.config.ts
這邊增加了 server proxy
,其中target
填上了POSTMAN
產生的URL,rewrite
部分也請記得改寫
vite.config.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig ({ plugins : [vue () , AutoImport ({ resolvers : [ElementPlusResolver ()], }), Components ({ resolvers : [ElementPlusResolver ()], }), ], server :{ proxy : { '/api' : { target : 'https://c37e652f-46f8-4272-a694-85e33c3766b1.mock.pstmn.io' , changeOrigin : true , rewrite : (path ) => { return path.replace ('/api' , '' ) } } }, } })
2.1.2. 修改src\views\Login.vue
實際上登入驗證的URL路徑為https://c37e652f-46f8-4272-a694-85e33c3766b1.mock.pstmn.io/login
,因為我們使用了代理的關係,這邊填的URL就會以api
為開頭:
1 const { data } = await axios.post ("/api/login" ,formData);
Login.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 <template> <div class="container"> <h1>英語字典管理系統</h1> <el-divider style="border-color:black" /> <el-row class="row" justify="center" style="margin-bottom:1.2rem;"> <div class="flex items-center"> <el-radio-group v-model="rdoRole"> <el-radio label="admin" size="large">管理員</el-radio> <el-radio label="student" size="large">考生</el-radio> </el-radio-group> </div> </el-row> <el-row class="row" justify="center"> <el-col :span="12"> <el-form :label-position="labelPosition" label-width="100px" :model="formData" style="max-width: 560px"> <el-form-item label="帳號"> <el-input v-model="formData.account" placeholder="請輸入帳號" /> </el-form-item> <el-form-item label="密碼"> <el-input v-model="formData.password" type="password" placeholder="請輸入密碼" show-password /> </el-form-item> <div style="text-align:center"> <el-button @click="btnLogin" type="info" round style="text-align:center;width:150px;font-size:1.5rem;background: #4A4A4A;padding:1.5rem">登入 </el-button> </div> </el-form> </el-col> </el-row> </div> </template> <script lang="ts" setup> import { reactive, ref } from 'vue' import axios from "axios"; const rdoRole = ref('admin') const labelPosition = ref('top') const formData = reactive({ account: '', password: '', }) const btnLogin = async () => { console.log(rdoRole.value); console.log(formData); if (formData.account != '' && formData.password != '') { console.log('ajax'); const { data } = await axios.post("/api/login",formData); console.log(data); } else { console.log('data 不完整'); } } </script> <style scoped> .container { width: 800px; margin: 10% auto; } h1 { text-align: center; font-size: 2rem; } </style>
2.1.3. 最後結果 觀查request console log ,的確有收到server 的response data
觀查request URL值為http:127.0.0.1:5173/api/login
,顯然代理成功,但還是對我感到好奇…實際上是怎麼做到的?有機會回來再了解一下
2.2. 設定axios.defaults.baseURL
這個部分其實還有很多issue,就是如何做到產品階段設定
、開發階段設定
吃不一樣的設定檔,這個部分後續花時間回來補一下。
先記錄一下簡單的版本,在有使用axios的地方,起頭就先宣告baseURL
:
src\view\Login.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <script lang="ts" setup> import { reactive, ref } from 'vue' import axios from "axios"; axios.defaults.baseURL="https://c37e652f-46f8-4272-a694-85e33c3766b1.mock.pstmn.io"; const rdoRole = ref('admin') const labelPosition = ref('top') const formData = reactive({ account: '', password: '', }) const btnLogin = async () => { console.log(rdoRole.value); console.log(formData); if (formData.account != '' && formData.password != '') { console.log('ajax'); const { data } = await axios.post("/login",formData); console.log(data); } else { console.log('data 不完整'); } } </script>
3. 伺服器回傳後,前端繼續驗證與處理 接續使用代理方式進行開發,下段程式碼透過localStorage
先儲存回傳的token
值,element plus
套件的ElMessage
元件呈現登入成功的效果(toast notification)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const btnLogin = async ( ) => { console .log (rdoRole.value ); console .log (formData); if (formData.account != '' && formData.password != '' ) { const { data } = await axios.post ("/api/login" ,formData); const { token } = data.data ; console .log (data); if (data.status == 'success' ) { localStorage .setItem ("token" ,token); ElMessage ({ showClose : true , message : '登入成功.' , type : 'success' , }); router.push ('/Main' ); } else { alert ('帳密錯誤' ); } } else { console .log ('data 不完整' ); } }
效果如下:
其中有一個ts-ignore
要特別說明,因為稍早我們使用的是自動載入
的方式,所以在開發階段的智能提示,會誤以為沒有進行import動作。要消除這個錯誤提示,我們可以在ElMessage
上方加上ts-ignore
寫法,錯誤就消失囉!
4. 參考資料