当前位置: 首页 > 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.dtcms.com/a/290290.html

相关文章:

  • 对称加密技术详解:原理、算法与实际应用
  • 在本地WSL中的CentOS 7子系统中部署Ewomail邮件服务器
  • 面试150 全排列
  • Claude Code 启动提示 Note: Claude Code might not be available in your country. 解决
  • mac安装node的步骤
  • 线程池与ThreadPoolExecutor源码解析(上)
  • Consumer<T>
  • Chatbox AI使用指南与功能详解:打造你的专属智能工作平台
  • Zabbix企业级分布式监控
  • OpenCV学习(二)-二维、三维识别
  • 技术演进中的开发沉思-41 MFC系列:定制 AppWizard
  • 【爬虫】06 - 自动化爬虫selenium
  • Zabbix 企业级分布式监控系统深度解析
  • 计算机发展史:人工智能时代的智能变革与无限可能
  • Laravel 后台登录 403 Forbidden 错误深度解决方案-优雅草卓伊凡|泡泡龙
  • NVM的安装使用:nvm管理多个 Node.js 版本的工具
  • gRPC深度解析:原理、实践与性能优化指南
  • 将 RustFS 用作 GitLab 对象存储后端
  • uniapp使用uni-ui怎么修改默认的css样式比如多选框及样式覆盖小程序/安卓/ios兼容问题
  • 测量误差溯源:系统误差与随机误差的数学建模与分离方法
  • 大模型——Prompt 优化还是模型微调
  • 【PTA数据结构 | C语言版】求单源最短路的Dijkstra算法
  • AI学习--本地部署ollama
  • 6.String、StringBuffer、StringBuilder区别及使用场景
  • 第3章通用的服务可用性治理手段——3.1 微服务架构与网络调用
  • Tomcat的部署、单体架构、session会话、spring
  • ARC学习(6)arc 编译器overlap 地址重叠方式使用
  • stm32mp157f-dk2安装镜像并且部署qt全流程
  • 基于uniapp的餐厅在线选餐小程序的设计与实现
  • 信息整合注意力IIA,通过双方向的轻量级注意力机制强化目标关键特征并抑制噪声,提升特征融合的有效性和空间位置信息的保留能力。