前端学习笔记 5:大事件

前端学习笔记 5:大事件

本文将学习一个示例项目(大事件)的前端搭建过程。

1.准备工作

1.1.创建工程

创建一个名称为big-event的 Vue3 项目,具体可以参考这篇文章

1.2.安装插件

安装 ElementPlus:

npm install element-plus --save

安装好后还需要在main.js中导入相关模块和样式:

import './assets/main.scss'

import {
    createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'

const app = createApp(App)

app.use(ElementPlus)
app.mount('#app')

安装 Axios:

npm install axios

安装 sass:

npm install sass -D

这是一个 CSS 扩展。

1.3.调整目录

  1. 删除components目录下的内容

  2. 删除App.vue中的内容,只保留script和template标签

  3. src下新建如下目录:

​ api:存放接口调用的js文件

​ utils:存放工具js文件

​ 拷贝request.js到util目录

​ views:存放页面的.vue文件

  1. 删除assets目录中的内容, 将资料中的静态资源文件全部拷贝到该目录下

2.注册

2.1.页面

views下添加 Login.view 作为登录页,并在 App.vue 中使用:

<script setup>
import LoginVue from '@/views/Login.vue'
</script>
<template>
  <LoginVue/>
</template>

为注册表单绑定响应式数据:

<script setup>
// ...
// 注册表单的响应式数据
const registData = ref({
    username: '',
    password: '',
    repassword: ''
})
</script>
<template>
	<el-form ... :model="registData">
        <el-form-item>
            <el-input ... v-model="registData.username"></el-input>
            </el-form-item>
        <el-form-item>
            <el-input ... v-model="registData.password"></el-input>
            </el-form-item>
        <el-form-item>
            <el-input ... v-model="registData.repassword"></el-input>
        </el-form-item>
    </el-form>
</template>

为注册表单定义验证规则:

// 注册表单的验证规则
const rules = ref({
   
    username: [
        {
    required: true, message: '请输入用户名', trigger: 'blur' },
        {
    min: 5, max: 16, message: '长度应该在5~16个字符', trigger: 'blur' },
    ],
    password: [
        {
    required: true, message: '请输入密码', trigger: 'blur' },
        {
    min: 5, max: 16, message: '长度应该在5~16个字符', trigger: 'blur' },
    ],
    repassword: [{
    validator: checkPass, trigger: 'blur' }],
})

其中再次输入密码(repassword)的验证规则是自定义验证规则:

// 检查密码是否一致的验证函数
const checkPass = (rule, value, callback) => {
   
    if (value === '') {
   
        callback(new Error('请输入密码'))
    }
    else if(value !== registData.value.password){
   
        callback(new Error('密码不一致'))
    }
    else{
   
        callback()
    }
}

将验证规则绑定到表单:

<el-form ... :rules="rules">
    <!-- ... -->
    <el-form-item prop="username">
        <!-- ... -->
    </el-form-item>
    <el-form-item prop="password">
        <!-- ... -->
    </el-form-item>
    <el-form-item prop="repassword">
        <!-- ... -->
    </el-form-item>
    <!-- ... -->
</el-form>

2.2.接口调用

这里对应的服务端 jar 包是 big-event.jar,对应的数据库表结构是 big-event.sql

jar 包中登录数据库的帐号密码是root:1234,如果不符,需要手动自行修改。

可以通过以下命令运行服务端:

java -jar .\big-event-1.0-SNAPSHOT.jar

该服务端提供的接口可以查阅接口文档

/src/api/user.js下创建接口调用函数:

import request from '@/utils/request.js'

export const registService = (registData) => {
   
    return request.post("/user/register", registData, {
   
        headers: {
   
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    })
}

需要注意的是,这里通过 POST 方法传递的参数是以x-www-form-urlencoded方式传递的,也就是在方法体中以 URL 编码方式传递,并非 Axios 默认的 JSON 格式传递,所以需要添加上额外参数指定请求头信息(content-type)。

除了上述方式,也可以使用另一种方式传递 x-www-form-urlencoded 编码的 POST 参数:

export const registService = (registData) => {
   
    var params = new URLSearchParams()
    for(let key in registData){
   
        params.append(key, registData[key])
    }
    return request.post("/user/register", params)
}

两者效果上是相同的。

login.vue中使用该函数完成注册,并绑定按钮点击事件:

<script setup>
// 注册用户
import { registService } from '@/api/user.js'
const regist = async () => {
    let result = await registService(registData.value)
    if (result.code === 0) {
        alert("注册成功!")
    }
    else {
        alert(result.msg ? result.msg : "注册失败!")
    }
}
</script>
<template>
	<el-button class="button" type="primary" auto-insert-space @click="regist">
        注册
    </el-button>
</template>

2.3.跨域

上边的示例实际上是有问题的,运行后观察控制台会出现类似下面的报错信息:

Access to XMLHttpRequest at 'http://localhost:8080/user/register' from origin 'http://localhost:5173' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

该信息说明了:程序尝试从源 http://localhost:5173 进行 Ajax 请求到 http://localhost:8080/user/register,这种请求被 CORS 规则所阻止。

实际上 CORS 是一种浏览器端的 AJAX 跨域访问的安全策略,只要是对不同源(协议\域名\端口任一不同)的 AJAX 调用,都会被浏览器阻止(除非服务端允许跨域访问)。

目前我们的前端程序(Vue)是运行在 Node.js 服务上的,所以可以通过在 Node.js 服务(Vue)上添加代理,让浏览器先访问 Node.js 服务,再通过 Node.js 服务将请求转发到 Jar 包运行的服务,这样就可以规避浏览器的跨域限制。

首先,修改request.js,让所有 AJAX 调用都以/api开头:

// const baseURL = 'http://localhost:8080';
const baseURL = '/api'

其次,修改 Vue 配置文件vite.config.js

export default defineConfig({
   
  // ...
  // 代理配置
  server: {
   
    proxy: {
   
      '/api': {
   
        target: 'http://localhost:8080', // 后端服务器地址
        changeOrigin: true, // 是否改变请求域名
        rewrite: (path) => path.replace(/^\/api/, '')//将原有请求路径中的api替换为''
      }
    }
  }
})

这里的正则/^\/api/的作用是将以/api开头的路径中的/api替换为空字符串。

3.登录

3.1.实现

user.js中添加登录接口的调用函数:

export const loginService = (loginData) => {
   
    return request.post("/user/login", loginData, {
   
        headers: {
   
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    })
}

login.vue中添加登录逻辑:

// 登录
const login = async () => {
   
    let result = await loginService(registData.value)
    if (result.code === 0) {
   
        alert("登录成功!")
    }
    else {
   
        alert(result.message ? result.message : "登录失败!")
    }
}

给登录按钮绑定点击事件:

<el-button class="button" type="primary" auto-insert-space @click="login">登录</el-button>

为登录表单绑定响应式数据(与注册表单的响应式数据复用):

<el-form ... :model="registData" :rules="rules">
    <el-form-item prop="username">
        <el-input ... v-model="registData.username"></el-input>
    </el-form-item>
    <el-form-item prop="password">
        <el-input ... v-model="registData.password"></el-input>
    </el-form-item>
</el-form>

这里对验证规则也进行了复用。

最后,还需要在切换注册或登录页面时对响应式数据清空:

// 重置注册登录数据
const resetRegistData = ()=>{
   
    registData.value = {
   
        username: '',
        password: '',
        repassword: ''
    }
}
<el-link type="info" :underline="false" @click="isRegister = false; resetRegistData()">
    ← 返回
</el-link>
<!-- ... -->
<el-link type="info" :underline="false" @click="isRegister = true; resetRegistData()">
    注册 →
</el-link>

3.2.拦截器优化

一般的,接口都会用统一的返回标识符表示业务的成功和失败,比如这里的result.data.code。可以利用这一点对响应拦截器进一步优化,在响应拦截器中判断业务接口的成功和失败,如果失败,直接输出失败信息,这样就不需要在前端的业务代码中对接口失败进行逐一处理。

修改request.js,添加处理业务失败时的逻辑:

instance.interceptors
  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值