2025-01-05 11:41:11 +08:00
# web
Vblog 前端项目
## 清理模版代码
- 清理组件
- 清理样式
- 清理js文件
2025-01-05 15:09:34 +08:00
## 添加登录页面
- LoginPage.vue
```vue
< template >
< div > 登录页面< / div >
< / template >
< script setup > < / script >
< style lang = "css" scoped > < / style >
```
- 添加路有
```js
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/login',
name: 'login',
component: () => import('../views/common/LoginPage.vue'),
},
],
})
```
- App组件, 添加路由视图入口
```vue
< script setup > < / script >
< template >
< RouterView > < / RouterView >
< / template >
< style scoped > < / style >
```
## 安装UI插件
https://gitee.com/infraboard/go-course/blob/master/day20/vue3-ui.md
```js
// 加载UI组件
import ArcoVue from '@arco -design/web-vue'
import '@arco -design/web-vue/dist/arco.css'
// 额外引入图标库
import ArcoVueIcon from '@arco -design/web-vue/es/icon'
app.use(ArcoVue)
app.use(ArcoVueIcon)
```
2025-01-05 16:09:35 +08:00
## Login Page开发
```vue
< template >
< div class = "content" >
< div class = "login-container" >
< div class = "login-title" > 欢迎登录博客系统< / div >
< div class = "login-form" >
< a-form size = "large" :model = "loginForm" @submit =" handleSubmit " >
< a-form-item
field="username"
hide-label
hide-asterisk
:rules="{ required: true, message: '请输入用户名' }"
>
< a-input
style="background-color: #fff ;"
v-model="loginForm.username"
placeholder="请输入用户名"
>
< template #prefix >
< icon-user / >
< / template >
< / a-input >
< / a-form-item >
< a-form-item
style="margin-top: 12px"
field="password"
hide-label
hide-asterisk
:rules="{ required: true, message: '请输入密码' }"
>
< a-input-password
style="background-color: #fff ;"
v-model="loginForm.password"
placeholder="请输入密码"
allow-clear
>
< template #prefix >
< icon-lock / >
< / template >
< / a-input-password >
< / a-form-item >
< a-form-item field = "remember_me" hide-label hide-asterisk >
< a-checkbox style = "margin-left: auto;" v-model = "loginForm.remember_me" value = "boolean"
>记住< /a-checkbox
>
< / a-form-item >
< a-form-item hide-label hide-asterisk >
< a-button type = "primary" style = "width: 100%;" html-type = "submit" > 登录< / a-button >
< / a-form-item >
< / a-form >
< / div >
< / div >
< / div >
< / template >
< script setup >
import { reactive } from 'vue'
const loginForm = reactive({
username: '',
password: '',
remember_me: false,
})
const handleSubmit = (data) => {
if (data.errors === undefined) {
console.log(data.values)
}
}
< / script >
< style lang = "css" scoped >
.content {
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
display: flex;
background-color: rgb(243, 238, 238);
}
.login-container {
width: 460px;
height: 320px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.3);
/* 增加透明度 */
border-radius: 15px;
backdrop-filter: blur(15px);
/* 增加模糊程度 */
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2);
}
.login-title {
margin-top: 12px;
margin-bottom: 12px;
font-size: 20px;
font-weight: 500;
color: var(--color-neutral-8);
}
.login-form {
padding: 20px;
height: 100%;
width: 100%;
}
< / style >
```
## 对接后端
调用后端的Restful接口, 需要一个http客户端
- XMLHTTPRequest
- fetch
- axios: https://www.axios-http.cn/docs/intro
```shell
npm install axios
```
### 后端API
```js
export const client = axios.create({
baseURL: 'http://127.0.0.1:8080',
timeout: 3000,
})
```
```js
import { client } from './client'
export const LOGIN = (data) =>
client({
url: '/api/vblog/v1/tokens',
method: 'POST',
data: data,
})
```
### 页面使用
```js
const summitLoading = ref(false)
const handleSubmit = async (data) => {
if (data.errors === undefined) {
try {
summitLoading.value = true
await LOGIN(data.values)
} catch (error) {
console.log(error)
} finally {
summitLoading.value = false
}
}
}
```
```sh
Access to XMLHttpRequest at 'http://127.0.0.1:8080/api/vblog/v1/tokens' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```
### 如何处理CORS
2025-01-05 17:15:05 +08:00
- 1. 服务端 允许跨越访问, 服务端需要配置一个CROS 中间件,返回 允许的 origin列表, 允许 origin localhost 访问
- 2. 前端使用代码, 前端先访问 -- proxy -- backend
推荐: 前端使用代理 , 最终的效果是 前端和后端部署在一起
前端如何配置代理: (vite)
```js
// https://vite.dev/config/
export default defineConfig({
plugins: [vue(), vueJsx(), vueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
server: {
proxy: {
'/api': 'http://localhost:8080',
},
},
})
```
http client在请求的时候, 不能指定baseURL: http://127.0.0.1:8080/api/vblog/v1/tokens,
```
http://localhost:5173/api/vblog/v1/tokens --> http://localhost:8080/vblog/v1/tokens
```
移除baseURL配置
```js
export const client = axios.create({
baseURL: '',
timeout: 3000,
})
```
### API 访问报错处理
添加一个响应拦截器来进行响应的处理
```js
// http 客户端配置一个拦截器
client.interceptors.response.use(
// 请求成功的拦截器
(value) => {
return value
},
// 请求失败
(error) => {
let msg = error.message
try {
msg = error.response.data.message
} catch (error) {
console.log(error)
}
Message.error(msg)
},
)
```