当前位置:   article > 正文

Vue+element-plus+SpringBoot搭建管理系统_基于spring boot + mybatis plus + vue & element的支持各种图

基于spring boot + mybatis plus + vue & element的支持各种图表与组件的后台管理

文章目录


目录

文章目录

前言

一、大致页面

二、工程结构

二、创建步骤

1.安装Vue

2.安装/引入element-plus

 三、部分代码

1.main.js

2.App.vue

3.布局框架文件layout.vue

4.头部栏components/Header.vue

5.左侧导航栏components/Asid.vue

6.布局框架Layout.vue

7.路由配置router/index.js

8.封装axios工具 utils/reques.js

四、功能页面

1.登陆页面 views/LoginView.vue

2.注册页面views/RegisterView.vue

3.用户管理页面views/UserView.vue

 五、一些技术点

1.前端解决跨域访问问题 vue.config.js文件

2.使用 element-puls  icon图标

3.点击导航栏选项跳转视图页面

4.前端登录状态拦截 utils/reques.js 文件

六、后端工程

1.SpringBoot工程结构

2.Maven文件/依赖

3.application.yml配置文件

4.实体类User

5.封装统一返回对象Result

6.UserMapper层

7.UserController控制层

七、后端技术点

1.MybatisPlus分页插件配置



前言

Vue+element-plus的管理系统模板有很多,其开发步骤类似


一、大致页面

二、工程结构

二、创建步骤

1.安装Vue

全局安装@vue/cli(仅第一次执行)
注意:要以管理员的身份打开cmd

1.如果出现下载缓慢可以先配置淘宝镜像:

npm config set registry https://registry.npm.taobao.org
npm install -g @vue/cli

创建脚手架工程

在目录位置打开cmd,运行命令行:

       

 vue create xxxx

选择Vue版本

运行项目:

1.先进入创建的文件夹的路径:

cd vue_text


2. 然后输入 :

npm run serve

2.安装/引入element-plus

在项目中打开cmd命令窗口,输入命令

npm install element-plus --save

安装成功,在main.js将其引入到自己的项目中

 三、部分代码

1.main.js

  1. import { createApp } from 'vue'
  2. import App from './App.vue'
  3. import router from './router'
  4. import 'element-plus/dist/index.css'
  5. import store from './store'
  6. import '@/assets/css/global.css'
  7. import ElementPlus from 'element-plus'
  8. createApp(App).use(store).use(router).use(ElementPlus).mount('#app')

2.App.vue

  1. <template>
  2. <div>
  3. <el-config-provider :locale="locale">
  4. <router-view />
  5. </el-config-provider>
  6. </div>
  7. </template>
  8. <script>
  9. import locale from "element-plus/lib/locale/lang/zh-cn";
  10. export default {
  11. name: 'App',
  12. components: {
  13. },
  14. setup() {
  15. return { locale };
  16. }
  17. }
  18. </script>
  19. <style>
  20. </style>

3.布局框架文件layout.vue

  1. <!--用作框架-->
  2. <template>
  3. <div>
  4. <el-config-provider :locale="locale">
  5. <!-- 头部-->
  6. <Header/>
  7. <!-- 主体-->
  8. <div style="display: flex">
  9. <!-- 侧边栏-->
  10. <Aside/>
  11. <!-- 主体内容区域-->
  12. <router-view style="flex: 1"/>
  13. </div>
  14. </el-config-provider>
  15. </div>
  16. </template>
  17. <script>
  18. import Header from "../components/Header";
  19. import Aside from "../components/Aside";
  20. import locale from "element-plus/lib/locale/lang/zh-cn";
  21. export default {
  22. name: "Layout",
  23. components:{
  24. Header,
  25. Aside,
  26. },
  27. setup() {
  28. return { locale };
  29. }
  30. }
  31. </script>
  32. <style scoped>
  33. </style>

4.头部栏components/Header.vue

  1. <!--头部导航栏-->
  2. <template>
  3. <div class="topNavigation">
  4. <div class="headerMenu">后台管理</div>
  5. <div style="flex: 1"></div>
  6. <div style="width: 100px">
  7. <el-dropdown>
  8. <el-button>{{user.nickname}}<el-icon><arrow-down /></el-icon></el-button>
  9. <template #dropdown>
  10. <el-dropdown-menu>
  11. <el-dropdown-item>个人信息</el-dropdown-item>
  12. <el-dropdown-item @click="quit">退出系统</el-dropdown-item>
  13. </el-dropdown-menu>
  14. </template>
  15. </el-dropdown>
  16. </div>
  17. </div>
  18. </template>
  19. <script>
  20. import { ArrowDown } from '@element-plus/icons-vue'
  21. import router from "../router";
  22. export default {
  23. name: "Header",
  24. components:{
  25. ArrowDown
  26. },
  27. data(){
  28. return{
  29. user:{},
  30. }
  31. },
  32. created() {
  33. this.user = JSON.parse(sessionStorage.getItem("user")||"{}");
  34. },
  35. methods:{
  36. quit(){
  37. sessionStorage.clear();
  38. router.push("/login");
  39. },
  40. }
  41. }
  42. </script>
  43. <style>
  44. .topNavigation {
  45. height: 50px;
  46. line-height: 50px;
  47. border-bottom: 1px solid #f6eaff;
  48. display: flex;
  49. }
  50. .headerMenu {
  51. width: 200px;
  52. padding-left: 30px;
  53. font-weight: bold;
  54. color: dodgerblue;
  55. }
  56. </style>

5.左侧导航栏components/Asid.vue

  1. <!--左侧边栏-->
  2. <template>
  3. <nav>
  4. <el-row class="tac">
  5. <!-- 加入outer实现导航栏点击跳转,index项值为对应的路由-->
  6. <el-menu
  7. router
  8. style="width: 200px ; min-height: 90vh"
  9. active-text-color="#ffd04b"
  10. class="el-menu-vertical-demo"
  11. default-active="user"
  12. text-color="black"
  13. :default-openeds="['数据管理']"
  14. >
  15. <el-sub-menu index="系统管理">
  16. <template #title>
  17. <el-icon>
  18. <user/>
  19. </el-icon>
  20. <span>系统管理</span>
  21. </template>
  22. <el-menu-item index="user">用户管理</el-menu-item>
  23. <el-menu-item index="book">图书管理</el-menu-item>
  24. </el-sub-menu>
  25. <el-sub-menu index="数据管理">
  26. <template #title>
  27. <el-icon>
  28. <grid/>
  29. </el-icon>
  30. <span>登录与注册</span>
  31. </template>
  32. <el-menu-item index="login">登录</el-menu-item>
  33. <el-menu-item index="register">注册</el-menu-item>
  34. </el-sub-menu>
  35. </el-menu>
  36. </el-row>
  37. </nav>
  38. </template>
  39. <script>
  40. import {Location, Grid, Document, Setting,User} from '@element-plus/icons-vue'
  41. export default {
  42. name: "Aside",
  43. components: {
  44. Location,
  45. Grid,
  46. Document,
  47. Setting,
  48. User
  49. }
  50. }
  51. </script>
  52. <style scoped>
  53. </style>

6.布局框架Layout.vue

用以控制各个组件在页面中的布局

  1. <!--用作框架-->
  2. <template>
  3. <div>
  4. <el-config-provider :locale="locale">
  5. <!-- 头部-->
  6. <Header/>
  7. <!-- 主体-->
  8. <div style="display: flex">
  9. <!-- 侧边栏-->
  10. <Aside/>
  11. <!-- 主体内容区域-->
  12. <router-view style="flex: 1"/>
  13. </div>
  14. </el-config-provider>
  15. </div>
  16. </template>
  17. <script>
  18. import Header from "../components/Header";
  19. import Aside from "../components/Aside";
  20. import locale from "element-plus/lib/locale/lang/zh-cn";
  21. export default {
  22. name: "Layout",
  23. components:{
  24. Header,
  25. Aside,
  26. },
  27. setup() {
  28. return { locale };
  29. }
  30. }
  31. </script>
  32. <style scoped>
  33. </style>

7.路由配置router/index.js

  1. // 路由
  2. import { createRouter, createWebHistory } from 'vue-router'
  3. import Layout from "../layout/Layout";
  4. const routes = [
  5. {
  6. path: '/', //当访问根路径时,会转向访问Layout界面
  7. name: 'Layout',
  8. component: Layout,
  9. redirect: 'user',//重定向,访问根目录重定向到/home
  10. // 嵌套路由配置
  11. children: [
  12. { path: 'user', name: 'User', component:()=>import("../views/UserView") },
  13. { path: 'book', name: 'Book', component:()=>import("../views/BookView") },
  14. ]
  15. },
  16. {
  17. path: '/login',
  18. name: 'Login',
  19. component: ()=>import("../views/LoginView")
  20. },
  21. {
  22. path: '/register',
  23. name: 'Register',
  24. component: ()=>import("../views/RegisterView")
  25. }
  26. ];
  27. const router = createRouter({
  28. history: createWebHistory(process.env.BASE_URL),
  29. routes
  30. });
  31. export default router

8.封装axios工具 utils/reques.js

  1. // 封装axios
  2. import axios from 'axios'
  3. import router from "@/router";
  4. const request = axios.create({
  5. baseURL: '/api', // 注意!! 这里是全局统一加上了 '/api' 前缀,也就是说所有接口都会加上'/api'前缀在,页面里面写接口的时候就不要加 '/api'了,否则会出现2个'/api',类似 '/api/api/user'这样的报错,切记!!!
  6. timeout: 5000
  7. })
  8. // request 拦截器
  9. // 可以自请求发送前对请求做一些处理
  10. // 比如统一加token,对请求参数统一加密
  11. request.interceptors.request.use(config => {
  12. config.headers['Content-Type'] = 'application/json;charset=utf-8';
  13. // config.headers['token'] = user.token; // 设置请求头
  14. //判断用户是否登录,没有登陆就跳转到login界面
  15. let userJson = sessionStorage.getItem("user");
  16. if(!userJson){
  17. router.push("/login");
  18. }
  19. return config
  20. }, error => {
  21. return Promise.reject(error)
  22. });
  23. // response 拦截器
  24. // 可以在接口响应后统一处理结果
  25. request.interceptors.response.use(
  26. response => {
  27. let res = response.data;
  28. // 如果是返回的文件
  29. if (response.config.responseType === 'blob') {
  30. return res
  31. }
  32. // 兼容服务端返回的字符串数据,如果返回的是String,就转换一下
  33. if (typeof res === 'string') {
  34. res = res ? JSON.parse(res) : res
  35. }
  36. return res;
  37. },
  38. error => {
  39. console.log('err' + error) // for debug
  40. return Promise.reject(error)
  41. }
  42. )
  43. export default request

四、功能页面

1.登陆页面 views/LoginView.vue

  1. <template>
  2. <div class="contanier">
  3. <div class="loginArea">
  4. <h2 style="text-align: center;padding: 10px 0">系统登录</h2>
  5. <el-form :model="loginForm" :rules="rules" ref="ruleForm">
  6. <el-form-item label="用户名:" prop="username">
  7. <el-input v-model.trim="loginForm.username" clearable></el-input>
  8. </el-form-item>
  9. <el-form-item label="密 码:" prop="password">
  10. <el-input type="password" v-model.trim="loginForm.password" show-password clearable></el-input>
  11. </el-form-item>
  12. <el-form-item>
  13. <el-button @click="loginBut('ruleForm')" style="width: 40%" type="primary">登 录</el-button>
  14. <el-button @click="registerBut" style="width: 40%;margin-left: 80px" type="primary">注 册</el-button>
  15. </el-form-item>
  16. </el-form>
  17. </div>
  18. </div>
  19. </template>
  20. <script>
  21. import {User, Key, Lock} from '@element-plus/icons-vue'
  22. import request from "../utils/reques";
  23. export default {
  24. name: "LoginView",
  25. components: {
  26. User, Key, Lock
  27. },
  28. data() {
  29. return {
  30. loginForm: {
  31. username: '',
  32. password: '',
  33. },
  34. // 表单校验
  35. rules: {
  36. username: [
  37. {required: true, message: '请输入账号', trigger: 'blur'},
  38. {min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  39. ],
  40. password: [
  41. {required: true, message: '请输入密码', trigger: 'blur'},
  42. {min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  43. ]
  44. }
  45. }
  46. },
  47. methods: {
  48. //登录按钮
  49. loginBut(formName) {
  50. /**
  51. * 配置axios请求,请求的url和请求参数
  52. * .then()链式操作,前一步完成后,结果传入
  53. */
  54. //表单校验
  55. this.$refs[formName].validate((valid) => {
  56. if (valid) {
  57. request.post("/user/login", this.loginForm).then(res => {
  58. if (res.code == "0") {
  59. this.$message({
  60. message: '登录成功o(* ̄▽ ̄*)ブ',
  61. type: 'success'
  62. });
  63. //缓存用户信息,将登录的用户信息存入到sessionStorage
  64. sessionStorage.setItem("user",JSON.stringify(res.data));
  65. //登陆成功页面跳转,跳转到到根目录
  66. this.$router.push("/")
  67. } else {
  68. this.$message({
  69. message: "登录失败,,ԾㅂԾ,,"+res.msg,
  70. type: 'error'
  71. });
  72. }
  73. });
  74. } else {
  75. this.$message({
  76. message: '请确认信息(ˉ▽ˉ;)...',
  77. type: 'warning'
  78. });
  79. return false;
  80. }
  81. });
  82. },
  83. //注册按钮
  84. registerBut() {
  85. this.$router.push("/register")
  86. },
  87. }
  88. }
  89. </script>
  90. <style scoped>
  91. .contanier {
  92. width: 100%;
  93. height: 100%;
  94. overflow: hidden;
  95. }
  96. .loginArea {
  97. width: 400px;
  98. border-radius: 30px;
  99. background-clip: border-box;
  100. margin: 200px auto;
  101. padding: 15px 35px 15px 35px;
  102. background: #d6e8ee;
  103. border: 3px solid #e6fffc;
  104. box-shadow: 0 0 30px #c5c7ff;
  105. }
  106. </style>

2.注册页面views/RegisterView.vue

  1. <template>
  2. <div class="contanier">
  3. <div class="loginArea">
  4. <h2 style="text-align: center;padding: 10px 0">用户注册</h2>
  5. <el-form :model="registerForm" :rules="rules" ref="ruleForm">
  6. <el-form-item label="用户名:" prop="username">
  7. <el-input v-model.trim="registerForm.username" clearable></el-input>
  8. </el-form-item>
  9. <el-form-item label="密 码:" prop="password">
  10. <el-input type="password" v-model.trim="registerForm.password" show-password clearable></el-input>
  11. </el-form-item>
  12. <el-form-item label="确认密码:" prop="againPassword">
  13. <el-input type="password" v-model.trim="registerForm.againPassword" show-password
  14. clearable></el-input>
  15. </el-form-item>
  16. <el-form-item label="昵 称:" prop="nickname">
  17. <el-input type="text" v-model.trim="registerForm.nickname" clearable></el-input>
  18. </el-form-item>
  19. <el-form-item label="年 龄:" prop="age">
  20. <el-input type="number" v-model.trim="registerForm.age" clearable></el-input>
  21. </el-form-item>
  22. <el-form-item label="性 别:" prop="sex">
  23. <el-checkbox-group v-model="registerForm.sex">
  24. <el-radio label="男" v-model="registerForm.sex"/>
  25. <el-radio label="女" v-model="registerForm.sex"/>
  26. <el-radio label="未知" v-model="registerForm.sex"/>未知
  27. </el-checkbox-group>
  28. </el-form-item>
  29. <el-form-item label="地 址:" prop="address">
  30. <el-input v-model.lazy="registerForm.address" type="textarea"></el-input>
  31. </el-form-item>
  32. <el-form-item>
  33. <el-button @click="registerSure('ruleForm')" style="width: 100%" type="primary">确 认</el-button>
  34. </el-form-item>
  35. </el-form>
  36. </div>
  37. </div>
  38. </template>
  39. <script>
  40. import {User, Key, Lock} from '@element-plus/icons-vue'
  41. import request from "../utils/reques";
  42. export default {
  43. name: "RegisterView",
  44. components: {
  45. User, Key, Lock
  46. },
  47. data() {
  48. return {
  49. registerForm: {
  50. username: '',
  51. password: '',
  52. againPassword: '',
  53. nickname: '',
  54. age: '',
  55. sex: '',
  56. address: ''
  57. },
  58. // 表单校验
  59. rules: {
  60. username: [
  61. {required: true, message: '请输入账号', trigger: 'blur'},
  62. {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  63. ],
  64. password: [
  65. {required: true, message: '请输入密码', trigger: 'blur'},
  66. {min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  67. ],
  68. againPassword: [
  69. {required: true, message: '请再次输入密码', trigger: 'blur'},
  70. {min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  71. ],
  72. nickname: [
  73. {required: true, message: '请输入昵称', trigger: 'blur'},
  74. {min: 2, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  75. ],
  76. age: [
  77. {required: true, message: '请输入年龄', trigger: 'blur'},
  78. {min: 1, max: 3, message: '长度在 3 到 5 个字符', trigger: 'blur'}
  79. ],
  80. sex: [
  81. {required: true, message: '请选择性别', trigger: 'change'}
  82. ],
  83. address: [
  84. {required: true, message: '请输入地址', trigger: 'blur'},
  85. {min: 2, message: '长度要大于2个字符', trigger: 'blur'}
  86. ]
  87. }
  88. }
  89. },
  90. methods: {
  91. //登录按钮
  92. registerSure(formName) {
  93. if (this.registerForm.password != this.registerForm.againPassword) {
  94. this.$message({
  95. message: '两次密码不一致(ˉ▽ˉ;)..',
  96. type: 'warning'
  97. });
  98. return;
  99. }
  100. /**
  101. * 配置axios请求,请求的url和请求参数
  102. * .then()链式操作,前一步完成后,结果传入
  103. */
  104. //表单校验
  105. this.$refs[formName].validate((valid) => {
  106. if (valid) {
  107. request.post("/user/register", this.registerForm).then(res => {
  108. if (res.code == "0") {
  109. this.$message({
  110. message: '注册成功o(* ̄▽ ̄*)ブ',
  111. type: 'success'
  112. });
  113. //注册成功,跳转到登陆界面
  114. this.$router.push("/login")
  115. } else {
  116. this.$message({
  117. message: "注册失败,,ԾㅂԾ,," + res.msg,
  118. type: 'error'
  119. });
  120. }
  121. });
  122. } else {
  123. this.$message({
  124. message: '请确认信息(ˉ▽ˉ;)...',
  125. type: 'warning'
  126. });
  127. return false;
  128. }
  129. });
  130. },
  131. }
  132. }
  133. </script>
  134. <style scoped>
  135. .contanier {
  136. width: 100%;
  137. height: 100%;
  138. overflow: hidden;
  139. }
  140. .loginArea {
  141. width: 400px;
  142. border-radius: 30px;
  143. background-clip: border-box;
  144. margin: 200px auto;
  145. padding: 15px 35px 15px 35px;
  146. background: #d6e8ee;
  147. border: 3px solid #e6fffc;
  148. box-shadow: 0 0 30px #c5c7ff;
  149. }
  150. </style>

3.用户管理页面views/UserView.vue

  1. <template>
  2. <div style="width: 100%">
  3. <!-- 操作区域-->
  4. <div style="margin: 10px 5px">
  5. <el-button type="primary" @click="addUser">新增</el-button>
  6. <el-button type="primary" @click="importUser">导入</el-button>
  7. <el-button type="primary" @click="exportUser">导出</el-button>
  8. </div>
  9. <!-- 搜索区域-->
  10. <div style="margin: 10px 5px">
  11. <el-input v-model="search" clearable type="text" placeholder="请输入关键字" style="width: 200px"></el-input>
  12. <el-button @click="load" type="primary" style="margin: 0 5px">
  13. <el-icon>
  14. <search/>
  15. </el-icon>
  16. </el-button>
  17. </div>
  18. <el-table v-model:data="tableData"
  19. stripe
  20. border
  21. style="width: 100%"
  22. >
  23. <el-table-column prop="id" label="id"/>
  24. <el-table-column prop="username" label="用户名"/>
  25. <el-table-column prop="nickname" label="昵称"/>
  26. <el-table-column prop="age" label="年龄"/>
  27. <el-table-column prop="sex" label="性别"/>
  28. <el-table-column prop="address" label="地址"/>
  29. <el-table-column label="操作">
  30. <template #default="scope">
  31. <el-button size="mini" @click="updateUser(scope.row)">编辑</el-button>
  32. <el-popconfirm title="你确定要删除该数据吗?" @confirm="deleteUser(scope.row.id)">
  33. <template #reference>
  34. <el-button size="mini" type="danger">删除</el-button>
  35. </template>
  36. </el-popconfirm>
  37. </template>
  38. </el-table-column>
  39. </el-table>
  40. <div class="demo-pagination-block">
  41. <el-pagination
  42. v-model:currentPage="currentPage"
  43. v-model:page-size="pageSize"
  44. :page-sizes="[5, 10, 20]"
  45. :small="small"
  46. :disabled="disabled"
  47. :background="background"
  48. layout="total, sizes, prev, pager, next, jumper"
  49. :total="totals"
  50. @size-change="handleSizeChange"
  51. @current-change="handleCurrentChange"
  52. />
  53. </div>
  54. <div>
  55. <el-dialog
  56. v-model="dialogVisible"
  57. title="新增数据"
  58. width="60%">
  59. <el-form :model="form" :rules="rules" ref="ruleForm" label-width="140px">
  60. <el-form-item label="用户名:" prop="username">
  61. <el-input v-model.trim="form.username" style="width: 80%"/>
  62. </el-form-item>
  63. <el-form-item label="昵 称:" prop="nickname">
  64. <el-input v-model.trim="form.nickname" style="width: 80%"/>
  65. </el-form-item>
  66. <el-form-item label="密 码:" prop="password">
  67. <el-input type="password" show-password v-model.trim="form.password" style="width: 80%"/>
  68. </el-form-item>
  69. <el-form-item label="年 龄:" prop="age">
  70. <el-input type="number" v-model.trim="form.age" style="width: 80%"/>
  71. </el-form-item>
  72. <el-form-item label="性 别:" prop="sex">
  73. <el-checkbox-group v-model="form.sex">
  74. <el-radio label="男" v-model="form.sex"/>
  75. <el-radio label="女" v-model="form.sex"/>
  76. <el-radio label="未知" v-model="form.sex"/>未知
  77. </el-checkbox-group>
  78. </el-form-item>
  79. <el-form-item label="地址:" prop="address">
  80. <el-input v-model.lazy="form.address" type="textarea" style="width: 80%"></el-input>
  81. </el-form-item>
  82. </el-form>
  83. <template #footer>
  84. <span class="dialog-footer">
  85. <el-button @click="dialogVisible = false">取消</el-button>
  86. <el-button type="primary" @click="addFormSave('ruleForm')">确定</el-button>
  87. </span>
  88. </template>
  89. </el-dialog>
  90. </div>
  91. </div>
  92. </template>
  93. <script>
  94. import {Search} from '@element-plus/icons-vue'
  95. import request from "../utils/reques";
  96. export default {
  97. name: 'HomeView',
  98. components: {
  99. Search
  100. },
  101. data() {
  102. return {
  103. search: '',
  104. totals: 0,
  105. currentPage: '',
  106. pageSize: 10,
  107. dialogVisible: false,
  108. tableData: [],
  109. form: {
  110. username: '',
  111. password: '',
  112. nickname: '',
  113. age: 0,
  114. sex: '',
  115. address: '',
  116. },
  117. // 表单校验
  118. rules: {
  119. username: [
  120. { required: true, message: '请输入用户名', trigger: 'blur' },
  121. { min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
  122. ],
  123. nickname: [
  124. { required: true, message: '请输入昵称', trigger: 'blur' },
  125. { min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
  126. ],
  127. password: [
  128. { required: true, message: '请输入密码', trigger: 'blur' },
  129. { min: 3, max: 11, message: '长度在 3 到 5 个字符', trigger: 'blur' }
  130. ],
  131. age: [
  132. { required: true, message: '请输入年龄', trigger: 'blur' }
  133. ],
  134. sex: [
  135. {required: true, message: '请选择性别', trigger: 'change' }
  136. ],
  137. address: [
  138. { required: true, message: '请输入地址', trigger: 'blur' },
  139. ]
  140. }
  141. }
  142. },
  143. created() {
  144. this.load()
  145. },
  146. methods: {
  147. // 加载初始数据
  148. load(){
  149. request.get("user/",{
  150. params:{
  151. pageNum: this.currentPage,
  152. pageSize: this.pageSize,
  153. search: this.search
  154. }
  155. }).then(res => {
  156. this.tableData = res.data.records;
  157. this.totals = res.data.total;
  158. })
  159. },
  160. //新增数据按钮
  161. addUser() {
  162. this.dialogVisible = true;
  163. this.form = {};
  164. },
  165. // 点击新增按钮后在弹出的表单点击确定按钮
  166. addFormSave(formName) {
  167. /**
  168. * 配置axios请求,请求的url和请求参数
  169. * .then()链式操作,前一步完成后,结果传入
  170. */
  171. //表单校验
  172. this.$refs[formName].validate((valid) => {
  173. if (valid) {
  174. request.post("/user",this.form).then(res=>{
  175. if (res.code=="0"){
  176. this.$message({
  177. message: '操作成功o(* ̄▽ ̄*)ブ',
  178. type: 'success'
  179. });
  180. this.dialogVisible = false;
  181. this.load();
  182. }else {
  183. this.$message({
  184. message: '操作失败,,ԾㅂԾ,,',
  185. type: 'error'
  186. });
  187. this.dialogVisible = false;
  188. }
  189. });
  190. } else {
  191. this.$message({
  192. message: '请确认表单(ˉ▽ˉ;)...',
  193. type: 'warning'
  194. });
  195. return false;
  196. }
  197. });
  198. },
  199. //删除数据按钮
  200. deleteUser(userId) {
  201. request.delete("user/"+userId,).then(res =>{
  202. if (res.code=="0"){
  203. this.$message({
  204. message: '操作成功o(* ̄▽ ̄*)ブ',
  205. type: 'success'
  206. });
  207. this.load();
  208. }else {
  209. this.$message({
  210. message: '操作失败,,ԾㅂԾ,,',
  211. type: 'error'
  212. });
  213. }
  214. });
  215. },
  216. //编辑信息按钮
  217. updateUser(row) {
  218. this.form = JSON.parse(JSON.stringify(row));
  219. this.dialogVisible = true;
  220. this.load();
  221. },
  222. //导出数据按钮
  223. exportUser() {
  224. this.load();
  225. },
  226. //导入数据按钮
  227. importUser() {
  228. },
  229. // 改变当前每页数据个数触发
  230. handleSizeChange() {
  231. this.load();
  232. },
  233. // 改变当前页码触发
  234. handleCurrentChange() {
  235. this.load();
  236. }
  237. }
  238. }
  239. </script>

 五、一些技术点

1.前端解决跨域访问问题 vue.config.js文件

  1. // 解决跨域访问
  2. // 跨域配置
  3. module.exports = {
  4. devServer: { //记住,别写错了devServer//设置本地默认端口 选填
  5. port: 8089,
  6. proxy: { //设置代理,必须填
  7. '/api': { //设置拦截器 拦截器格式 斜杠+拦截器名字,名字可以自己定
  8. target: 'http://localhost:8090', //代理的目标地址
  9. changeOrigin: true, //是否设置同源,输入是的
  10. pathRewrite: { //路径重写
  11. '/api': '' //选择忽略拦截器里面的内容
  12. }
  13. }
  14. }
  15. }
  16. }

2.使用 element-puls  icon图标

引入icon:

//{Location, Grid, Document, Setting,User}为所使用的icon图标名称

import {Location, Grid, Document, Setting,User} from '@element-plus/icons-vue'
export default {
    name: "Aside",
    components: {
        Location,
        Grid,
        Document,
        Setting,
        User
    }
}

使用:

<el-icon>
    <user/>
</el-icon>

3.点击导航栏选项跳转视图页面

在导航栏属性加入 router

选项的 index值为配置好的路由

4.前端登录状态拦截 utils/reques.js 文件

六、后端工程

1.SpringBoot工程结构

2.Maven文件/依赖

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>2.6.7</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.example</groupId>
  12. <artifactId>demo</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>springbootdemo</name>
  15. <description>Demo project for Spring Boot</description>
  16. <properties>
  17. <java.version>11</java.version>
  18. </properties>
  19. <dependencies>
  20. <!-- web-->
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-starter-web</artifactId>
  24. </dependency>
  25. <!--mysql-->
  26. <dependency>
  27. <groupId>mysql</groupId>
  28. <artifactId>mysql-connector-java</artifactId>
  29. <scope>runtime</scope>
  30. </dependency>
  31. <!-- lombok-->
  32. <dependency>
  33. <groupId>org.projectlombok</groupId>
  34. <artifactId>lombok</artifactId>
  35. <optional>true</optional>
  36. </dependency>
  37. <!-- mybatis-->
  38. <dependency>
  39. <groupId>org.mybatis.spring.boot</groupId>
  40. <artifactId>mybatis-spring-boot-starter</artifactId>
  41. <version>2.2.2</version>
  42. </dependency>
  43. <!-- MybatisPlus依赖-->
  44. <dependency>
  45. <groupId>com.baomidou</groupId>
  46. <artifactId>mybatis-plus-boot-starter</artifactId>
  47. <version>3.4.3.1</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>org.springframework.boot</groupId>
  51. <artifactId>spring-boot-starter-test</artifactId>
  52. <scope>test</scope>
  53. </dependency>
  54. </dependencies>
  55. <build>
  56. <plugins>
  57. <plugin>
  58. <groupId>org.springframework.boot</groupId>
  59. <artifactId>spring-boot-maven-plugin</artifactId>
  60. <configuration>
  61. <excludes>
  62. <exclude>
  63. <groupId>org.projectlombok</groupId>
  64. <artifactId>lombok</artifactId>
  65. </exclude>
  66. </excludes>
  67. </configuration>
  68. </plugin>
  69. </plugins>
  70. </build>
  71. </project>

3.application.yml配置文件

  1. server:
  2. port: 8090
  3. spring:
  4. datasource:
  5. driver-class-name: com.mysql.cj.jdbc.Driver
  6. url: jdbc:mysql://localhost:3306/springboot-vue
  7. username: root
  8. password: 123456

4.实体类User

  1. package com.example.demo.pojo;
  2. import com.baomidou.mybatisplus.annotation.IdType;
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5. import lombok.Data;
  6. /**
  7. * 用户实体类
  8. */
  9. @TableName("user")//与数据库表明对应
  10. @Data//lombok 的Data注解,不用写get/set方法
  11. public class User {
  12. @TableId(type = IdType.AUTO)//主键id自动生成
  13. private Integer id;
  14. private String username;
  15. private String password;
  16. private String nickname;
  17. private Integer age;
  18. private String sex;
  19. private String address;
  20. }

5.封装统一返回对象Result

  1. package com.example.demo.pojo;
  2. /**封装的统一返回对象
  3. * @param <T>
  4. */
  5. public class Result<T> {
  6. private String code;
  7. private String msg;
  8. private T data;
  9. public String getCode() {
  10. return code;
  11. }
  12. public void setCode(String code) {
  13. this.code = code;
  14. }
  15. public String getMsg() {
  16. return msg;
  17. }
  18. public void setMsg(String msg) {
  19. this.msg = msg;
  20. }
  21. public T getData() {
  22. return data;
  23. }
  24. public void setData(T data) {
  25. this.data = data;
  26. }
  27. public Result() {
  28. }
  29. public Result(T data) {
  30. this.data = data;
  31. }
  32. public static Result success() {
  33. Result result = new Result<>();
  34. result.setCode("0");
  35. result.setMsg("成功");
  36. return result;
  37. }
  38. public static <T> Result<T> success(T data) {
  39. Result<T> result = new Result<>(data);
  40. result.setCode("0");
  41. result.setMsg("成功");
  42. return result;
  43. }
  44. public static Result error(String code, String msg) {
  45. Result result = new Result();
  46. result.setCode(code);
  47. result.setMsg(msg);
  48. return result;
  49. }
  50. public static Result error() {
  51. Result result = new Result<>();
  52. result.setCode("1");
  53. result.setMsg("失败");
  54. return result;
  55. }
  56. }

6.UserMapper层

  1. package com.example.demo.mapper;
  2. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  3. import com.example.demo.pojo.User;
  4. import org.springframework.stereotype.Controller;
  5. /**
  6. * User的持久层
  7. */
  8. @Controller
  9. //继承BaseMapper接口
  10. public interface UserMapper extends BaseMapper<User> {
  11. }

7.UserController控制层

  1. package com.example.demo.controller;
  2. import com.baomidou.mybatisplus.core.toolkit.Wrappers;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.example.demo.mapper.UserMapper;
  5. import com.example.demo.pojo.Result;
  6. import com.example.demo.pojo.User;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.transaction.annotation.Transactional;
  9. import org.springframework.web.bind.annotation.*;
  10. /**
  11. * User控制器
  12. */
  13. @RestController
  14. @RequestMapping("/user")
  15. public class UserController {
  16. @Autowired
  17. private UserMapper userMapper;
  18. /**
  19. * 登陆方法
  20. * @param user
  21. * @return
  22. */
  23. @PostMapping("/login")
  24. public Result login(@RequestBody User user){
  25. //在数据库中查询与传来的用户名和密码系统的数据
  26. User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername,user.getUsername()).eq(User::getPassword,user.getPassword()));
  27. if (res==null){
  28. return Result.error("-1","用户名或密码错误");
  29. }else {
  30. return Result.success(res);
  31. }
  32. }
  33. /**
  34. * 注册方法
  35. * @param user
  36. * @return
  37. */
  38. @PostMapping("/register")
  39. public Result Register(@RequestBody User user){
  40. //在数据库中查询与传来的用户名和密码系统的数据
  41. User res = userMapper.selectOne(Wrappers.<User>lambdaQuery().eq(User::getUsername,user.getUsername()));
  42. if (res!=null){
  43. return Result.error("-1","用户名重复");
  44. }else {
  45. userMapper.insert(user);
  46. return Result.success(res);
  47. }
  48. }
  49. /**
  50. * 新增数据操作
  51. *
  52. * @param user
  53. * @return
  54. */
  55. @Transactional
  56. @PostMapping
  57. //@RequestBody注解,将传入的json数据转换为对象
  58. public Result saveUser(@RequestBody User user) {
  59. if (user.getId() != null) {
  60. userMapper.updateById(user);
  61. } else {
  62. userMapper.insert(user);
  63. }
  64. return Result.success();
  65. }
  66. /**
  67. * 根据ID删除数据
  68. * @param
  69. * @return
  70. */
  71. @Transactional
  72. @DeleteMapping("/{userId}")
  73. public Result deleteUser(@PathVariable Integer userId){
  74. userMapper.deleteById(userId);
  75. return Result.success();
  76. }
  77. /**
  78. * 分页查询User表
  79. * 根据前端传来的搜索值进行模糊擦查询
  80. *
  81. * @param pageNum
  82. * @param pageSize
  83. * @param search
  84. * @return
  85. */
  86. @GetMapping
  87. public Result findPage(@RequestParam(defaultValue = "1") Integer pageNum,
  88. @RequestParam(defaultValue = "10") Integer pageSize,
  89. @RequestParam(defaultValue = "") String search) {
  90. // Wrappers.<User>lambdaQuery().like(User::getNickname,search) 模糊查询,根据前端传来的search
  91. Page<User> page = userMapper.selectPage(new Page<>(pageNum, pageSize), Wrappers.<User>lambdaQuery().like(User::getNickname, search));
  92. return Result.success(page);
  93. }
  94. }

七、后端技术点

1.MybatisPlus分页插件配置

  1. package com.example.demo.common.config;
  2. import com.baomidou.mybatisplus.annotation.DbType;
  3. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  4. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. /**
  9. * mybatis-plus 分页插件
  10. */
  11. @Configuration
  12. //扫描mapper文件包,加入ioc容器,不用在写@Mapper
  13. @MapperScan("com.example.demo.mapper")
  14. public class MybatisPlusConfig {
  15. /**
  16. * 分页插件
  17. */
  18. @Bean
  19. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  20. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  21. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  22. return interceptor;
  23. }
  24. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/549464
推荐阅读
相关标签
  

闽ICP备14008679号