当前位置: 首页 > news >正文

前后端分离项目进阶1---前端

前期项目链接:项目1

在项目1的基础上,引入element组件库,让前端代码变得更美观。

一.项目简介:

前端采用Vue3+Element组件库,后端采用Spring boot+mybatis框架+mysql数据库

项目后端:链接

运行结果:

前期准备:

1)配置组件库及自动导入

1.在cmd里输入yarn add element-plus --save下载组件库插件和yarn add @element-plus/icons-vue安装图标

2.main.js文件配置

import './assets/main.css'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
//添加中文支持
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'const app = createApp(App)app.use(router)
app.use(ElementPlus, {locale: zhCn,
})
app.mount('#app')

3.vite.config.js文件配置

import { fileURLToPath, URL } from 'node:url'import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'import AutoImport from 'unplugin-auto-import/vite';//自动导入,如果想要配置还需要下面的安装命令import Components from 'unplugin-vue-components/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
// https://vite.dev/config/
export default defineConfig({plugins: [vue(),vueDevTools(),AutoImport({imports: ['vue','vue-router'],resolvers: [ElementPlusResolver()],}),Components({resolvers: [ElementPlusResolver()],}),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))},},})

如果想要使用自动导入,不想每次调用组件和加载组件的时候导入组件,直接用可以在vite.config.js文件配置import AutoImport from 'unplugin-auto-import/vite';

接着,输入npm install -D unplugin-vue-components unplugin-auto-import命令来安装自动导入所依赖的插件。就可以了。

2)导入sql文件

我的项目就是一个简单的测试,只写了一张Admin表,就只有账号,密码和名称三个字段。


/*Navicat Premium Data TransferSource Server         : 8.1Source Server Type    : MySQLSource Server Version : 80100 (8.1.0)Source Host           : localhost:3306Source Schema         : mybaitistestTarget Server Type    : MySQLTarget Server Version : 80100 (8.1.0)File Encoding         : 65001Date: 07/07/2025 10:35:02
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for admin
-- ----------------------------
DROP TABLE IF EXISTS `admin`;
CREATE TABLE `admin`  (`Account` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,`Password` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,`Name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,PRIMARY KEY (`Account`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;

二.前端设计

1) 目录结构

2) 关键代码解析:

1.admin.js

import axios from 'axios'const API_URL = 'http://localhost:8080/api/admins'export default {getAllAdmins() {return axios.get(API_URL)},getAdmin(account) {return axios.get(`${API_URL}/${account}`)},addAdmin(admin) {return axios.post(API_URL, admin)},updateAdmin(account, admin) {return axios.put(`${API_URL}/${account}`, admin)},deleteAdmin(account) {return axios.delete(`${API_URL}/${account}`)}
}

解析:

这里的代理地址(指向后端控制器的统一资源地址)为'http://localhost:8080/api/admins'。

后端

  @GetMappingpublic List<Admin> getAllAdmins() {return adminMapper.findAll();}

@GetMapping里没有设置地址,默认为根地址api/admins

@RequestMapping("/api/admins")

axios.get用来访问后端接口地址。

2.AdminManagement.vue

<template><div class="admin-management"><h2>管理员管理</h2><!-- 添加管理员表单 --><el-form :model="form" label-width="120px" style="margin-bottom: 20px;"><el-form-item label="账号"><el-input v-model="form.account" style="width: 200px;"></el-input></el-form-item><el-form-item label="密码"><el-input v-model="form.password" style="width: 200px;"></el-input></el-form-item><el-form-item label="姓名"><el-input v-model="form.name" style="width: 200px;"></el-input></el-form-item><el-form-item><el-button type="primary" @click="addAdmin">添加</el-button></el-form-item></el-form><!-- 管理员列表 --><el-table :data="admins" border style="width: 100%"><el-table-column prop="account" label="账号" width="180"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column label="操作"><template #default="scope"><el-button size="small" @click="handleEdit(scope.row)">编辑</el-button><el-button size="small" type="danger" @click="handleDelete(scope.row.account)">删除</el-button></template></el-table-column></el-table><!-- 编辑对话框 --><el-dialog v-model="dialogVisible" title="编辑管理员"><el-form :model="editForm"><el-form-item label="账号"><el-input v-model="editForm.account" disabled></el-input></el-form-item><el-form-item label="密码"><el-input v-model="editForm.password"></el-input></el-form-item><el-form-item label="姓名"><el-input v-model="editForm.name"></el-input></el-form-item></el-form><template #footer><el-button @click="dialogVisible = false">取消</el-button><el-button type="primary" @click="updateAdmin">确定</el-button></template></el-dialog></div>
</template><script>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import adminApi from '../api/admin'export default {setup() {const admins = ref([])const form = ref({account: '',password: '',name: ''})const editForm = ref({account: '',password: '',name: ''})const dialogVisible = ref(false)const fetchAdmins = async () => {try {const response = await adminApi.getAllAdmins()admins.value = response.data} catch (error) {ElMessage.error('获取管理员列表失败')}}const addAdmin = async () => {try {await adminApi.addAdmin(form.value)ElMessage.success('添加成功')form.value = { account: '', password: '', name: '' }fetchAdmins()} catch (error) {ElMessage.error('添加失败')}}const handleEdit = (row) => {editForm.value = { ...row }dialogVisible.value = true}const updateAdmin = async () => {try {await adminApi.updateAdmin(editForm.value.account, editForm.value)ElMessage.success('更新成功')dialogVisible.value = falsefetchAdmins()} catch (error) {ElMessage.error('更新失败')}}const handleDelete = async (account) => {try {await adminApi.deleteAdmin(account)ElMessage.success('删除成功')fetchAdmins()} catch (error) {ElMessage.error('删除失败')}}onMounted(() => {fetchAdmins()})return {admins,form,editForm,dialogVisible,addAdmin,handleEdit,updateAdmin,handleDelete}}
}
</script><style scoped>
.admin-management {padding: 20px;
}
</style>

解析:

1.这里的表格用的是elemt组件库里面的表格标签。这里的导入:
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import adminApi from '../api/admin'

可以删去,因为我设置了自动导入。

2.当点击编辑按钮的时候,会触发handleEdit方法,弹出编辑对话框。当点击删除按钮的时候,会触发handleDelete方法,删除一行数据。当点击添加按钮时,就会触发addAdmin方法。

当使用 <el-table> 的 scoped-slot(作用域插槽)时,Element UI 会自动向插槽传递一个 scope 对象

   <template #default="scope"><el-button size="small" @click="handleEdit(scope.row)">编辑</el-button><el-button size="small" type="danger" @click="handleDelete(scope.row.account)">删除</el-button></template>
  • #default:Vue 3 的简写语法,等同于 v-slot:default,表示默认插槽。

  • ="scope":将插槽传递的属性对象命名为 scope(可自定义为其他名称,如 slotProps)。

  • 这样就可以用scope.row来访问当前行数据了,scope是响应式数据,修改scope.row会直接修改表格数据源。

3.editForm 是一个 响应式对象,用于临时存储和编辑表格中某一行的数据。它的本质是

一个普通的 JavaScript 对象(Plain Object),但通过 Vue 的 ref 或 reactive 包装后成为响应式对象。admins,form,dialogvisible同理。

4.dialogVisible 控制对话框显示/隐藏的逻辑是 Element Plus 组件库(基于 Vue 3)的内置功能。
  • 控制显示:当 dialogVisible 为 true 时,<el-dialog> 组件会显示;为 false 时隐藏。

  • 双向绑定:通过 v-model 与 <el-dialog> 绑定,无论是代码修改 dialogVisible 还是用户点击对话框的关闭按钮,都会自动同步状态。

这里采用的是Composition API 的标准用法,如果使用setup语法糖,就可以不需要手动return了,这里没用语法糖,return的作用是将数据暴露给模块,让模块可以访问。

5.:data="admins" 绑定的数据来源于 Vue 组件的响应式状态,具体是通过 setup() 函数中定义的 admins 变量。

在 <script> 部分的 setup() 函数中,admins 通过 ref 创建并初始化:

import { ref } from 'vue';
const admins = ref([]); // 初始化为空数组

ref([]):创建一个响应式引用,初始值为空数组。

value:在 JavaScript 中访问时需要 admins.value,但在模板中直接写 admins 即可(Vue 自动解包)。

在 fetchAdmins 方法中,通过 API 请求获取数据并赋值给 admins

const fetchAdmins = async () => {
  try {
    const response = await adminApi.getAllAdmins(); // 调用API
    admins.value = response.data; // 将返回数据赋值给 admins
  } catch (error) {
    ElMessage.error('获取管理员列表失败');
  }
};

adminApi.getAllAdmins():访问后端接口( GET /api/admins),返回管理员列表。

response.data:接口返回的 JSON 数据格式为:

[
  { "account": "admin1", "name": "张三" },
  { "account": "admin2", "name": "李四" }
]

3.index.js

import { createRouter, createWebHistory } from 'vue-router'
import AdminManagement from '../components/AdminManagement.vue'const routes = [{path: '/',name: 'AdminManagement',component: AdminManagement}
]const router = createRouter({history: createWebHistory(),routes
})export default router

解析:

配置路由。Vue Router 支持 三种主要的路由历史管理方式,这里采用的是html5模式。

对比总结

特性createWebHistory()createWebHashHistory()createMemoryHistory()
URL 美观度高 (/path)低 (/#/path)无 URL 变化
服务器配置必需无需无需
SEO 支持友好不友好不适用
浏览器兼容性IE10+全兼容全兼容
典型使用场景生产环境 (SPA/SSR)静态托管/旧浏览器SSR/测试

如何选择?

  1. 优先选 createWebHistory()
    如果控制服务器且需要专业部署(配置 Fallback 到 index.html)。

  2. 备选 createWebHashHistory()
    如果是静态网站托管(如 GitHub Pages)或需要兼容 IE9。

  3. 特殊场景用 createMemoryHistory()
    仅用于测试或 SSR 框架内部。

path: '/'表示当用户访问网站的根路径时,会匹配这个路由,表示默认访问的根路径路由。

4.App.vue

<template><div id="app"><router-view></router-view></div>
</template><script>
export default {name: 'App'
}
</script><style>
#app {font-family: Avenir, Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;color: #2c3e50;margin: 20px;
}
</style>

解析:

<router-view> 会根据当前浏览器地址栏的 URL 路径,动态渲染匹配的路由组件

http://www.xdnf.cn/news/1162369.html

相关文章:

  • Ubuntu 22.04 使用 Docker 安装 Redis 5 (安装包形式)
  • 设备虚拟化技术-IRF
  • 电子数据取证领域的双轮驱动——手工分析 vs 自动化分析
  • SpringSecurity 详细介绍(认证和授权)
  • 复制docker根目录遇到的权限问题
  • C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(二)
  • docker磁盘空间不足解决办法
  • MongoDB 查询时区问题
  • linux定时器使用
  • 3、Spring AI_DeepSeek模型-多轮对话
  • 江苏思必驰科技25Java实习面经
  • HTTP,HTTPS
  • 服务器系统时间不准确怎么办?
  • 图论基本算法
  • 部署Zabbix企业级分布式监控
  • 【Unity基础】Unity中2D和3D项目开发流程对比
  • Unity 插件Resize Pro 最快的 Texture2D 调整大小工具
  • Elasticsearch 是 NVIDIA Enterprise AI Factory 验证设计中推荐的向量数据库
  • 数据结构堆的实现(C语言)
  • Web3.0 能为你带来哪些实质性的 改变与突破
  • Vue 脚手架——render函数
  • 【算法笔记】树状数组
  • Linux学习之Linux系统权限
  • 《C++》函数内联,auto关键字
  • 用基础模型构建应用(第十章)AI Engineering: Building Applications with Foundation Models学习笔记
  • 探索无广告音乐世界:MusicFree 免费播放器
  • 海康威视视觉算法岗位30问及详解
  • BERT 的“池化策略”
  • 【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 主页布局实现
  • Three.js 立方体贴图(CubeMap)完全指南:从加载到应用