手把手Vue3專案(二)——安裝配置 json-server 、 json-server-auth ,模擬後端服務,測試註冊和登入功能
本文包含:
json-server 的安裝 配置 驗證
json-server-auth 的安裝 配置 驗證
註冊和登入頁面
涉及知識點:axios,router,http請求,跨域,vue3,ts 等等
歡迎小夥伴,加入微信群,在文末,如果二維碼過期,可以在公眾號裡獲取。
json-server
安裝配置 json-server
安裝
pnpm add json-server -D
配置
// 直接看下面驗證的時候如何使用,以及使用的時候遇到的問題
驗證
一、基本使用大家參考 json-server Github
簡單來說分了三步
- 建立一個 json 檔案當作你要訪問的資料庫,在你安裝好
json-server
- 啟動 json-server 伺服器,直接執行
json-server --watch db.json
,終端會提示現在這個資料庫存在的資源 - 在瀏覽器地址輸入啟動終端中提示你擁有的資源地址,如:
http://localhost:3000/posts/1
,就可以訪問到一組json資料。這裡的資料是真實的資料,可以在開發者工具的 network 中訪問到,不像 mock 的資料會被劫持,在瀏覽器開發者工具中看不到請求的資料。
二、專案中的簡單使用
- 準備一個專案放在專案中的 json 檔案,作為我們專案的資料庫 database,這裡我建立在
./src/service/json-server/data.json
testdata
。
{ "testdata": { "status": 200, "message": "請求成功!", "data": [ { "id": 1, "title": "json-server", "author": "typicode" }, { "id": 2, "title": "json-server", "author": "typicode" } ] } }
- 在 package.json 中配置啟動 json-server 的命令,只需更改我們存放資料的 json 檔案地址就可以了。
"scripts": {
"jsondb": "json-server --watch ./src/service/json-server/data.json"
}
- 理解專案 API 的訪問機制
-
我們啟動 json-server,
npm jsondb
,我這裡專案一直使用的pnpm
作為包管理器,所以使用pnpm jsondb
來啟動, -
Home可以理解為後端伺服器的地址,當我們直接在輸入http://localhost:3000/users,
-
現在我們ctrl+c停止,json-server 的服務,讓後啟動我的使用vite搭建的 Vue 專案,發現預設地址,也是 http://localhost:3000,現在我的頁面是在訪問http://localhost:3000時,重定向到
/home
頁面。我們在訪問瀏覽器地址的時候一方面,我要通過路由轉跳到當前頁面,還需要當前頁面能夠獲取到資料,但是同時啟動 vue 專案和 json-server 兩個地址就衝突,後啟動的地址會被預設更改到http://localhost:3001,但是我們要通過訪問http://localhost:3000/users 來獲取到使用者資訊,這個時候就和我們實際工作中專案的開發非常類似了。
我們一般把前端專案部署到nginx,訪問前端頁面,獲取資料又是從另一個伺服器來獲取,這個時候兩個域名不一樣,但是我們要拿到我們想要的資料,就需要規定好介面的地址、引數等一些資訊,通過本地跨域,或者nginx轉發來訪問伺服器。
啟動 json-server 圖
瀏覽器中訪問資料庫圖
啟動專案圖
- 前端跨域代理的配置,在
vite.config.ts
中- 這裡我們更改專案等啟動埠到3030
- 現在我們前端專案路徑為
http://localhost:3030
,需要代理所有以/api
開頭的 API 請求,把它轉發到http://localhost:3000
,並且後端的 API 路徑中不帶/api
字首,需要自動去掉/api
字首
server: {
// host: 'localhost',
port: 3030,
proxy: {
//這裡是通過請求/api 來轉發到 https://api.pingping6.com/
//假如你要請求https://api.*.com/a/b
//那麼axios的url,可以配置為 /api/a/b
'^/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
// configure: (proxy, options) => {
// // proxy 是 'http-proxy' 的例項
// }
}
}
},
- 下面我們配置一下 API ,axios 的配置,可以到 Gitee 程式碼裡看一下 /service/index.ts 檔案,裡面有註釋,寫的也通俗易懂。
/**
* * 在具體模組中匯入具體的 config 型別,配置通用的 config 型別,方便複用
*/
import http from '@/service'
enum Api {
testData = '/api/testdata',
testPost = '/api/postTestList',
testPatch = '/api/patchTestList',
testPut = '/api/putTestList',
testDelete = '/api/deleteTestList'
}
export const testData = (params?: any) => {
return http.get<any>(Api.testData, params)
}
export const testPost = (data: any) => {
return http.post<any>(Api.testPost, data)
}
- 下面寫個頁面,測試一下,src/modules/components/test/json-server.vue
<template>
<h1>通過測試頁面通過json-server,獲取資料</h1>
</template>
<script lang="ts">
import { defineComponent, onMounted } from 'vue'
import { testData } from '@/api/test/index'
export default defineComponent({
name: 'json-server',
components: {},
setup() {
const testJsonServer = () => {
testData().then((res) => {
console.log('testData', res.data.data)
})
}
onMounted(() => {
console.log('mounted')
testJsonServer()
})
return {
testJsonServer
}
}
})
</script>
<style lang="less" scoped></style>
- 開啟頁面可以訪問到資料
安裝配置 json-server-auth
安裝
pnpm add json-server-auth -D
配置
// 直接進入驗證
驗證
1. 註冊
POST /register
POST /signup
POST /users
email
和 password
必填,且在請求體中,除了必填之外,自己也可以根據需要新增其他的資料username,age等等
POST /register
{
"email": "[email protected]",
"password": "bestPassw0rd"
}
返回結果
// 201 Created
{
"accessToken": "xxx.xxx.xxx",
"user": {
"id": 1,
"email": "[email protected]"
}
}
2. 登入
POST /login
// 我用login的時候Apifox可以請求到,在專案中就login
就不行,換成signin
就可以請求通,很奇怪POST /signin
POST /login
{
"email": "[email protected]",
"password": "bestPassw0rd"
}
返回結果
200 OK
{
"accessToken": "xxx.xxx.xxx",
"user": {
"id": 1,
"email": "[email protected]",
"firstname": "Olivier",
"lastname": "Monge"
}
}
3. 使用 postman 或者 Apifox,配置之後,測試一下,register新增兩組資料,再使用這兩組資料登入,可以之後就在專案中繼續
4. 具體程式碼中實踐,順便鞏固一下 Vue3、 TS 和 Ant Design Vue 3.0
下面是簡單寫的註冊和登入頁面,切換註冊的時候,還有一點問題,後面我再看一下,大家也可以看一下程式碼,可以一起交流,
目前登入功能是可以測試的,介面也是通的
下面的程式碼沒有樣式,樣式有很多行,影響閱讀,大家可以 clone Gitee 程式碼下來看。
<template>
<div class="login">
<div class="content">
<a-tabs animated :tabBarGutter="-1" type="card" v-model:activeKey="activeKey">
<a-tab-pane key="login" tab="賬號密碼登入">
<div class="login-form">
<a-form
ref="formRef"
:model="formState"
:rules="rules"
layout="vertical"
labelAlign="right"
>
<a-form-item label="" name="email">
<a-input
size="large"
v-model:value="formState.email"
placeholder="請輸入郵箱"
allowClear
/>
</a-form-item>
<a-form-item label="" name="password">
<a-input
size="large"
v-model:value="formState.password"
type="password"
placeholder="請輸入密碼"
allowClear
/>
</a-form-item>
</a-form>
<div class="login-button">
<a-button v-if="switchBtn" size="large" type="primary" @click="login">登入</a-button>
<a-button v-else size="large" type="primary" @click="register">註冊</a-button>
</div>
<div class="login-footer">
<a-button type="link" @click="handleChange">{{ buttonTitle }}</a-button>
</div>
</div>
</a-tab-pane>
<a-tab-pane key="register" tab="掃碼登入">
<div class="login-form">
<div class="login-qrcode">
<div class="qrcode-image"></div>
</div>
<div class="login-footer">
<div class="primary-color">二維碼失效時間 5 秒</div>
</div>
</div>
</a-tab-pane>
</a-tabs>
</div>
<!-- <div class="login-button">-->
<!-- <a-button type="primary" @click="register">註冊</a-button>-->
<!-- <a-button type="primary" @click="login">登入</a-button>-->
<!-- </div>-->
<!-- <div>-->
<!-- <a>忘記密碼?</a>-->
<!-- </div>-->
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, UnwrapRef, ref, toRaw } from 'vue'
import { toLogin, toRegister } from '@/api/login/index'
import { ValidateErrorEntity } from 'ant-design-vue/es/form/interface'
import { message } from 'ant-design-vue'
interface FormState {
email: string
password: string
}
export default defineComponent({
name: 'login',
components: {},
setup() {
// tab 欄預設選擇 login
const activeKey = ref('login')
// 登入與註冊切換
let switchBtn = ref(true)
let buttonTitle = ref<string>('新使用者註冊')
const handleChange = () => {
switchBtn = ref(!switchBtn.value)
buttonTitle = ref(switchBtn.value ? '新使用者註冊' : '已有賬號登入')
console.log('change', switchBtn.value)
console.log('text', buttonTitle)
}
// form 表單部分
const formRef = ref()
// UnwrapRef 單層解包, https://juejin.cn/post/6844904126283776014
const formState: UnwrapRef<FormState> = reactive({
email: '',
password: ''
})
const rules = {
email: [{ required: true, message: '請輸入正確的郵箱格式', trigger: 'blur' }],
password: [
{ required: true, message: '請輸入密碼!', trigger: 'blur' },
{
min: 8,
max: 16,
message: '密碼長度需8-16位密碼!',
trigger: 'blur'
}
]
}
const validFlag = ref(false)
const register = () => {
valid()
if (validFlag) {
toRegister(formState)
.then((res) => {
console.log(res)
validFlag.value = false
})
.catch((err) => {
console.log(err)
validFlag.value = false
})
}
return
}
const login = () => {
console.log('登入')
valid()
if (validFlag) {
toLogin(formState)
.then((res) => {
console.log(res)
validFlag.value = false
})
.catch((err) => {
console.log(err)
validFlag.value = false
// message.warn('請輸入使用者名稱或密碼!')
})
}
return
}
const valid = () => {
formRef.value
.validate()
.then(() => {
console.log('values', formState, toRaw(formState))
validFlag.value = true
console.log('validFlag', validFlag)
})
.catch((error: ValidateErrorEntity<FormState>) => {
validFlag.value = false
console.log('error', error)
message.warn('請輸入使用者名稱或密碼!')
})
}
const resetForm = () => {
formRef.value.resetFields()
}
return {
activeKey,
switchBtn,
buttonTitle,
handleChange,
formRef,
formState,
rules,
validFlag,
login,
register,
valid,
resetForm
}
}
})
</script>
Find me
Gitee:https://gitee.com/heyhaiyon/vite-vue-ts-antd.git
微信公眾號:heyhaiyang
掘金:heyhaiyang
部落格園:heyhaiyang
頭條號:heyhaiyang
微信群:歡迎小夥伴加入