go17/vblog/web/README.md

6.0 KiB
Raw Blame History

web

Vblog 前端项目

清理模版代码

  • 清理组件
  • 清理样式
  • 清理js文件

添加登录页面

  • LoginPage.vue
<template>
  <div>登录页面</div>
</template>

<script setup></script>

<style lang="css" scoped></style>
  • 添加路有
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/login',
      name: 'login',
      component: () => import('../views/common/LoginPage.vue'),
    },
  ],
})
  • App组件添加路由视图入口
<script setup></script>

<template>
  <RouterView></RouterView>
</template>

<style scoped></style>

安装UI插件

https://gitee.com/infraboard/go-course/blob/master/day20/vue3-ui.md

// 加载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)

Login Page开发

<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客户端

npm install axios

后端API

export const client = axios.create({
  baseURL: 'http://127.0.0.1:8080',
  timeout: 3000,
})
import { client } from './client'

export const LOGIN = (data) =>
  client({
    url: '/api/vblog/v1/tokens',
    method: 'POST',
    data: data,
  })

页面使用

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
    }
  }
}
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

    1. 服务端 允许跨越访问, 服务端需要配置一个CROS 中间件,返回 允许的 origin列表, 允许 origin localhost 访问
    1. 前端使用代码, 前端先访问 -- proxy -- backend

推荐: 前端使用代理 , 最终的效果是 前端和后端部署在一起

前端如何配置代理: (vite)

// 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配置

export const client = axios.create({
  baseURL: '',
  timeout: 3000,
})

API 访问报错处理

添加一个响应拦截器来进行响应的处理

// 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)
  },
)