当前位置:   article > 正文

Vue3 + Element-Plus电商后台管理系统详细记录《前后端分离版》

Vue3 + Element-Plus电商后台管理系统详细记录《前后端分离版》

一、概述

基于vue3 和element-plus的电商后台管理系统

1.1 实现功能

        用户登录/退出
        用户管理

                用户列表:实现用户的增删改查、分页查询以及分配角色的功能

        权限管理

                角色列表

                        实现角色的增删改查以及分配权限、删除权限功能

                权限列表

                        展示所有权限以及权限等级

        商品管理

                商品列表:实现商品的增删改查,分页查询

                分类参数: 实现分类参数的增删改查

                商品分类:实现商品分类的增删改查以及查看改分类下的所有子类

        订单管理

                订单列表

                        实现修改地址

                        实现查看物流进度

        数据统计分析        

                        数据报表

1.2 前端技术栈

 电商后台管理系统里系统整体采用前后端分离的开发模式,其中前端是基于Vue框架的SPA项目

        技术栈 :vue3、vue-router、Element-Plus、Axios、Echarts

1.3 前端项目初始化步骤

        1. 安装vue脚手架-vue-cli
        2. 通过vue脚手架创建项目
        3. 配置vue路由
        4. 配置element-plus组件库
        5. 配置axios库
        6. 初始化git远程仓库
        7. 将本地项目托管到Gitee中   

https://gitee.com/ding-miao9898/vue_shop/blob/master/vue.config.jsicon-default.png?t=N7T8https://gitee.com/ding-miao9898/vue_shop/blob/master/vue.config.js

                Mac安装Git_mac git_rockvine的博客-CSDN博客

                Git使用教程,最详细,最傻瓜,最浅显,真正手把手教 - 知乎

二、登录与退出

1、登录

什么时候使用token 什么时候使用session和cookie?

token是后端产生的,前端可以生成token么?

 token唯一身份辨识。

在这里插入图片描述

2、登录

表单验证规则三步骤:

1、给form表单绑定规则 :rules = rules ;

2、data中编写rules,rules是一个对象,每个属性是一个数组,每个数组是一个对象;

3、el-form-item 中prop绑定对应的规则;

重置表单2步:

1、拿到表单实例对象 el-form 添加 ref="loginFormRef" 

2、通过this访问到$refs的loginFormRef对象

2、调用resetFields方法

表单的预校验:

当我们点击登录按钮,发送登录请求之前我们需要对表单进行预校验;

调用表单的validata方法

发送登录请求:

通过axios进行网络请求,传入的参数是用户名和用户密码,使用post请求,

在响应拦截器中判断,如果返回的状态码不是200,那么登录失败,否则登录成功。

message弹框组件的导入:

1、引入弹框提示组件:import {Message} from 'element-ui'

2、挂载为全局的属性: Vue.prototype.$message = Message

3、失败的弹窗信息,this.$message.error('登录失败!') ; 成功的弹窗信息, this.$message.success('登录成功')

登录组件登录成功后的行为:

1、将登录成功之后的token,保存到客户端的sessinStorage中;

        1.1项目中出现了登录之外的其他API接口,必须在登录之后才能访问;

        1.2 token只应在当前网站打开期间生效,所以将token保存在sessionStorage中;

2、通过编程式导航跳转到后台主页,路由地址是 /home

  1. <template>
  2. <div class="login_wrap">
  3. <div class="form_wrap" v-if="!registerState">
  4. <el-form
  5. ref="loginForm"
  6. :model="loginData"
  7. label-width="80px"
  8. class="demo-dynamic"
  9. label-position="left"
  10. :rules="rules"
  11. >
  12. <el-form-item prop="username" label="用户名">
  13. <el-input v-model="loginData.username"></el-input>
  14. </el-form-item>
  15. <el-form-item prop="password" label="密码">
  16. <el-input v-model="loginData.password" type="password"></el-input>
  17. </el-form-item>
  18. <div style="display: flex">
  19. <el-button class="login_btn" @click="handleLogin">登录</el-button>
  20. <el-button class="login_btn" @click="registerState = true"
  21. >注册</el-button
  22. >
  23. </div>
  24. </el-form>
  25. </div>
  26. <!-- 注册表单 -->
  27. <div class="register_wrap" v-if="registerState">
  28. <el-form
  29. ref="registerRef"
  30. :model="registerForm"
  31. status-icon
  32. :hide-required-asterisk="true"
  33. :rules="rules"
  34. label-width="80px"
  35. class="login-form"
  36. >
  37. <!-- 用户名注册 -->
  38. <el-form-item label="用户名" prop="username">
  39. <el-input
  40. v-model.number="registerForm.username"
  41. minlength="6"
  42. maxlength="10"
  43. autocomplete="off"
  44. placeholder="请注册用户名"
  45. ></el-input>
  46. </el-form-item>
  47. <!-- 邮箱注册 handleGetCaptcha -->
  48. <el-form-item label="邮箱" prop="email">
  49. <el-input
  50. v-model="registerForm.email"
  51. autocomplete="off"
  52. placeholder="请输入注册邮箱"
  53. >
  54. <!-- 发送验证码按钮 -->
  55. <template #append>
  56. <el-button :disabled="false" @click="handleGetCaptcha">{{
  57. codeText
  58. }}</el-button>
  59. </template>
  60. </el-input>
  61. </el-form-item>
  62. <!-- 验证码输入 校验 -->
  63. <el-form-item label="验证码" prop="capcha">
  64. <el-input
  65. v-model="registerForm.capcha"
  66. maxlength="10"
  67. autocomplete="off"
  68. placeholder="请输入验证码"
  69. ></el-input>
  70. </el-form-item>
  71. <!-- 密码设置 -->
  72. <el-form-item label="密码" prop="password">
  73. <el-input
  74. v-model="registerForm.password"
  75. type="password"
  76. autocomplete="off"
  77. placeholder="请输入密码"
  78. ></el-input>
  79. </el-form-item>
  80. <!-- 确认密码registerForm.checkPass -->
  81. <el-form-item label="确认密码" prop="checkPass">
  82. <el-input
  83. v-model="registerForm.checkPass"
  84. type="password"
  85. autocomplete="off"
  86. ></el-input>
  87. </el-form-item>
  88. <!-- 完成注册按钮 handleRegister -->
  89. <el-form-item>
  90. <div class="btn-container">
  91. <el-button
  92. type="primary"
  93. style="width: 100%"
  94. @click="handleRegister()"
  95. >完成注册</el-button
  96. >
  97. </div>
  98. <div class="go-login">
  99. <span
  100. class="to-login"
  101. @click="registerState = !registerState"
  102. style="display: block; margin-left: 90px"
  103. >已有账号<em>去登陆</em></span
  104. >
  105. </div>
  106. </el-form-item>
  107. </el-form>
  108. </div>
  109. </div>
  110. </template>
  111. <script>
  112. import { reactive, toRefs, ref, computed, onMounted } from "vue";
  113. import { useStore } from "vuex";
  114. import { useRouter } from "vue-router";
  115. import { ElMessage } from "element-plus";
  116. import { loginApi, registerApi, getCaptchaApi } from "@/util/request";
  117. // import { encrypt } from "@/util/aes.ts";
  118. // import {store} from '/Users/dingmiao/Desktop/商店后台管理系统/myproject/src/store'
  119. export default {
  120. name: "login",
  121. setup() {
  122. const store = useStore();
  123. const router = useRouter();
  124. const loginForm = ref();
  125. const registerRef = ref();
  126. const sendingCode = ref(false);
  127. const data = reactive({
  128. loginData: {
  129. username: "",
  130. password: "",
  131. },
  132. registerState: false,
  133. registerForm: {
  134. username: "",
  135. email: "",
  136. capcha: "",
  137. password: "",
  138. checkPass: "",
  139. },
  140. codeText: "获取验证码",
  141. });
  142. // 登录表单校验规则
  143. const rules = {
  144. password: [
  145. { validator: validatePass, tigger: "blur" },
  146. {
  147. required: true,
  148. min: 6,
  149. max: 10,
  150. message: "长度在6 到 10个字符",
  151. trigger: "blur",
  152. },
  153. ],
  154. username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  155. checkPass: [{ validator: validatePass2, tigger: "blur" }],
  156. email: [
  157. { required: true, message: "请输入注册邮箱", trigger: "blur" },
  158. { type: "email", message: "请输入正确的邮箱地址", trigger: "blur" },
  159. ],
  160. capcha: [{ required: true, message: "请输入验证码", trigger: "blur" }],
  161. };
  162. // 二次校验
  163. function validatePass2(rule, value, callback) {
  164. if (value === "") {
  165. callback(new Error("请再次输入密码"));
  166. } else if (value != data.registerForm.password) {
  167. callback(new Error("两次输入的密码不一致"));
  168. } else {
  169. callback();
  170. }
  171. }
  172. // 校验密码函数
  173. function validatePass(rule, value, callback) {
  174. if (value === "") {
  175. callback(new Error("请输入密码"));
  176. } else {
  177. callback();
  178. }
  179. }
  180. // 通过 mutation 改变登录状态
  181. function handleLogin() {
  182. loginForm.value.validate(async (valid) => {
  183. if (valid) {
  184. try {
  185. loginApi(data.loginData).then((res) => {
  186. // console.log("res====>", res.data);
  187. if (!res.data.status) {
  188. store.commit("changeLoginStatus", data.loginData);
  189. localStorage.setItem(
  190. "loginData",
  191. JSON.stringify(data.loginData)
  192. ); //将用户信息存入localStorage
  193. // 跳转url
  194. router.push({
  195. path: "/user",
  196. });
  197. } else {
  198. alert("账户与密码不符合");
  199. }
  200. });
  201. } catch (err) {
  202. ElMessage({
  203. type: "warning",
  204. message: err.message,
  205. });
  206. }
  207. }
  208. return false;
  209. });
  210. }
  211. // 处理注册信息
  212. function handleRegister() {
  213. registerRef.value.validate(async (valid) => {
  214. if (valid) {
  215. try {
  216. const { username, email, password, capcha } = data.registerForm;
  217. const data1 = { username, email, capcha, password };
  218. registerApi(data1)
  219. .then((res) => {
  220. console.log("注册用户信息", res);
  221. if (res.data.status === 0) {
  222. console.log("注册完毕");
  223. localStorage.setItem("registerData", JSON.stringify(data1));
  224. // store.commit("storeRegisterData", data1);
  225. ElMessage({
  226. type: "success",
  227. message: "注册成功",
  228. });
  229. data.registerState = false;
  230. } else {
  231. ElMessage({
  232. type: "warning",
  233. message: res.message,
  234. });
  235. }
  236. })
  237. .catch((err) => {
  238. ElMessage({
  239. type: "warning",
  240. message: err.message,
  241. });
  242. });
  243. } catch (err) {
  244. ElMessage({
  245. type: "warning",
  246. message: err.message,
  247. });
  248. }
  249. }
  250. });
  251. }
  252. // getCodeSuccess 获取验证码状态
  253. const getCodeSuccess = () => {
  254. let countDown = 60;
  255. sendingCode.value = true;
  256. const interval = setInterval(() => {
  257. if (countDown > 0) {
  258. data.codeText = `已发送(${countDown}s)`;
  259. countDown -= 1;
  260. } else {
  261. clearInterval(interval); //清楚定时器
  262. sendingCode.value = false;
  263. data.codeText = "获取验证码";
  264. }
  265. }, 1000);
  266. };
  267. //发送验证码 handleGetCaptcha
  268. const handleGetCaptcha = async () => {
  269. try {
  270. const { email } = data.registerForm;
  271. if (!email) {
  272. ElMessage({
  273. type: "waring",
  274. message: "请输入注册邮箱",
  275. });
  276. return false;
  277. }
  278. const data1 = { email };
  279. // 发送获取验证码的请求 接口为registerApi
  280. await getCaptchaApi(data1).then((res) => {
  281. if (res.data.status === 0) {
  282. // console.log('验证码获取成功')
  283. ElMessage({
  284. type: "success",
  285. message: "成功发送请求",
  286. });
  287. getCodeSuccess();
  288. return true;
  289. }
  290. ElMessage({
  291. type: "warning",
  292. message: res.message,
  293. });
  294. return false;
  295. });
  296. } catch (error) {
  297. ElMessage({
  298. type: "warning",
  299. message: error.message,
  300. });
  301. }
  302. };
  303. return {
  304. ...toRefs(data),
  305. handleLogin,
  306. handleRegister,
  307. handleGetCaptcha,
  308. rules,
  309. loginForm,
  310. registerRef,
  311. sendingCode,
  312. };
  313. },
  314. };
  315. </script>
  316. <style scoped>
  317. .login_wrap {
  318. width: 100%;
  319. height: 100vh;
  320. background-image: url("@/assets/bg.JPG");
  321. background-size: cover;
  322. background-repeat: no-repeat;
  323. position: relative;
  324. }
  325. .form_wrap,
  326. .register_wrap {
  327. position: fixed;
  328. top: calc(50% - 101px);
  329. left: calc(50% - 390px);
  330. background-color: rgb(199, 224, 245);
  331. transform: transiton(-50%, -50%);
  332. border-style: double;
  333. border-width: 2px;
  334. padding: 30px 50px;
  335. border-radius: 5px;
  336. /* background-color: transparent;
  337. opacity: 0.9; */
  338. }
  339. .login_btn {
  340. display: block;
  341. margin: 10px auto;
  342. }
  343. .el-select {
  344. width: 300px;
  345. }
  346. .el-input {
  347. width: 300px;
  348. }
  349. .dialog-footer button:first-child {
  350. margin-right: 10px;
  351. }
  352. </style>
  1. /**
  2. * @description register mock data right here
  3. * 使用mock.js库来模拟接口数据,使用 Mock.js,可以在前端开发过程中模拟接口数据,以便进行接口调用和功能开发,而无需依赖后端接口的实际实现。
  4. * 通过定义模拟数据,可以在前端开发过程中模拟各种接口返回的数据结构和格式,以及测试不同的场景和状态
  5. * Mock.mock()用来定义接口的模拟数据
  6. */
  7. import Mock from 'mockjs'
  8. Mock.setup({
  9. timeout: "1900"
  10. })
  11. // 定义mock请求拦截,登录请求返回的数据 一定要写全请求地址http://localhost:8080xxxxxx
  12. Mock.mock('http://localhost:8080/api/auth/user/login', 'post', (option) => {
  13. console.log('拦截到了')
  14. console.log(option)
  15. // 拦截到请求后的处理逻辑
  16. const { username, password } = JSON.parse(option.body)
  17. // 情况1:账户admineSuper 密码:123456 超级管理员
  18. if (username === 'admineSuper' && password === '123456') {
  19. return {
  20. status: 0,
  21. data: {
  22. accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IjIyODA1MjAxMjhAcXEuY29tIiwic3ViIjo5LCJpYXQiOjE2MjU4MzQ3MTksImV4cCI6MTYyODQyNjcxOX0.YQLVi-zw4XWQEd8Hy2YZGlFaqX8c7xyRPrYuxcFywFE'
  23. },
  24. success: true,
  25. message: '登录成功'
  26. }
  27. }
  28. // 情况2:账户admine 密码:123456 普通用户
  29. if (username === 'admine' && password === '123456') {
  30. return {
  31. status: 0,
  32. data: {
  33. accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6IjIyODA1MjAxMjhAcXEuY29tIiwic3ViIjo5LCJpYXQiOjE2MjU4MzQ3MTksImV4cCI6MTYyODQyNjcxOX0.YQLVi-zw4XWQEd8Hy2YZGlFaqX8c7xyRPrYuxcFywFE'
  34. },
  35. success: true,
  36. message: '登录成功'
  37. }
  38. }
  39. // 情况3:密码不正确时候返回的数据
  40. return {
  41. status: 1,
  42. data: null,
  43. message: '账户或者密码错误'
  44. }
  45. })
  46. // 用户注册
  47. Mock.mock('http://localhost:8080/api/auth/user/register', 'post', (option) => {
  48. return {
  49. status: 0,
  50. data: { message: '注册请求成功' },
  51. success: true,
  52. message: '成功'
  53. }
  54. })

3、效果展示

4、路由导航守卫控制访问权限

如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面;

在全局路由守卫router.beforeEach((to, from, next)=>{}) 中,

1、判断用户当前要去的页面是否为登录页,如果是,则放行next;

2、读取sessionStorage中是否存在token,如果存在token,则放行;否则强制跳转到登录页。

5、退出功能

基于token的方式实现退出比较简单,只需要销毁本地的token即可,这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才能访问页面。

6、处理语法警告

当eslint和格式化冲突的时候,在根目录上添加配置文件prettierrc来进行格式化的配置,将格式化时候的默认双引号变成单引号,默认添加分号关闭。

当eslint中报错,可以通过在eslintrc.js中的规则rules进行配置

五、优化element-ui的按需导入

在plugins/element-ui.js文件中

7、提交登录功能代码

1、git status命令 查看当前源代码的状态 能够看到了修改文件和新增文件

2、git add . 将文件添加到暂存区

3、git commit -m “提示信息“ 将当前代码提交到本地仓库中

4、git branch 查看当前的分支

5、将login 内容合并到master分支上,1)要切换到master分支 git checkout master        2)合并 git merage login

6、git push 将本地的master分支中的代码推送到云端的master分支中

7、本地的login分支推送到云端的仓库中 1)切换到login分支 git checkout login  2)推送到云端 git push -u origin login

三、页面布局

1、整体布局:

1-引入element-ui

2-设置样式 :注意el-mian el-container就是组件类名,可以直接.el-main{}来设置样式

2、header布局

3、侧边栏布局

1)elementui按需导入         2)只设置一二级菜单栏,多余部分删除

4、通过接口获取菜单数据

通过axios请求拦截器添加token,保证拥有获取数据的权限;

打印config,config的属性如下:我们要使用的是header属性

5、发起请求获得左侧菜单栏

1)封装菜单请求api

2)定义菜单源数据

3)获取所有菜单列表

6、左侧菜单UI绘制

1)一级菜单栏渲染: v-for="item in menuList" :key="item.id" index="item.id" 文本{{item.authName}}

【注意】:index必须是唯一的 否则的话就会导致操作一个菜单,其他的菜单也会有同样的动作,所以将index设置为item.id + ''

2)二级菜单:循环item.children即可 v-for="subItem in item.children" :key="subItem.id"

文本:<span>{{subItem.authName}}</span> 

index更改为 subItem.id + ''

7、左侧菜单格美化

1) 改变选中菜单时的颜色: 修改el-menu标签中的active-text-color属性的颜色

        

2)修改二级菜单的图标:修改二级菜单中 i标签的class属性为el-icon-menu

3)修改一级菜单的图标

4)每次只展开一个子菜单

5)边框线对不齐的效果:子菜单展开的时候,会多出一个块

8、实现侧边栏的展开与折叠

1)通过给el-menu绑定:collapse="isCollapse"属性来进行折叠,并消除组件自带的动画效果 :collapse-transition="false"

定义一个变量isCollapsed,动态的绑定collapse属性

2)给折叠按钮绑定点击事件

3) 折叠时候背景色区域并没有跟着折叠

原因:整个区域都属于侧边栏el-side, 而el-side的width属性写死了200px,导致不能跟随侧边栏折叠而折叠;

解决方法: width宽度随着 isCollapse变化而变化,即:width="isCollapse ? '64px' : '200px'"

9、实现首页的路由重定向

访问/home,可以重定向到Welcome组件,

也就是Home组件嵌套Welcom组件,一定要在Home组件中使用router-view给Welcome 组件占位。

1)创建Welcom组件

2)编写路由表

3)在Home组件中占位

10、左侧菜单改造为路由链接

需求:点击二级子菜单,路由进行跳转

方法:el-menu中的router属性,可以实现路由跳转,并且以index为path进行跳转

1)el-menu开启router

2)二级菜单index设置为path,注意加/

四、用户列表页开发

1)components/user/Users.vue创建组件

2)配置路由表

Home组件是一级组件

Users组件嵌套在Home组件中,也就是二级路由

13、解决用户列表小问题

问题1:点击子菜单时,不高亮;刷新页面的时候,也应该有高亮效果。

0)设置链接高亮

1)每次点击链接(子菜单)的时候,将地址保存到sessionStorage中,并且设置高亮

2)刷新的时候,读取sessionStorage的地址,并赋值给default-active

14、绘制用户列表的基本UI结构

1)面包屑

2)卡片视图区域 el-card

设置全局样式:

src/css/global.css

3)设置搜索与添加区域

el-row 的gutter属性是设置 列与列之间的间距

el-col的span属性是设置 每列的宽度

15、获取用户列表数据

1)封装请求用户列表api

2)发送请求,并对请求后的数据处理 userList 《用户列表》和total 《数据条数》

16、渲染用户列表数据

data: 指定数据源

label:当前列的标题

prop:当前列指向的数据

响应数据:

1)用户列表区域:border表示带边框, stripe表示隔行变色

2)设置table的样式  src/assets/css/gloabal.css

17、为用户列表添加索引列

索引列:table的每一行的最前面的一列, 即带# 序号的那一列

设置索引列,在“姓名”前添加一列,设置type="index"即可

18、改造状态列的显示效果

由于请求返回的数据mg_state是布尔值,我们需要将el-switch的状态和mg_state关联起来。

方法:通过作用域插槽,scope.row得到的是当前这一行的数据,打印scope.row结果如下图所示。

[注意]        prop:"mg_state"可以直接删除了

19、插槽形式自定义列的渲染

1)作用域插槽获得作用域的数据 <template slot-scope></template>

2)在模版中放入三个按钮, el-button

3)在最后一个按钮外层包裹 el-tooltip用于显示提示信息

el-tooltip的属性:设置为false表示,进入tooltip中文字提示就消失

20、实现数据分页效果

1)按需导入分页组件 el-pagination 

2)定义 @size-change 事件、@current-change事件

3)不同的属性配置页码条    

21、实现用户状态的修改

问题:用户状态改变后刷新页面后,状态恢复默认值,无法实现保存更改

解决:1)监听用户状态的改变《switch的change事件》;2)封装接口,将状态改变提交数据库

22、实现搜索的功能

1)为文本框绑定查询参数

2)点击搜索按钮,发起getUser请求

3)input添加清除按钮,并监听@clear事件

23、实现添加用户的功能

1)按需引入el-dialog组件 2)控制对话框的显示与隐藏 addDialogVisible = false/true,当点击“添加”按钮的时候显示对话框;当点击“取消”/“确定”按钮的时候隐藏对话框;

24、添加用户的对话框中渲染一个添加用户的表单

1)将“内容主体区域”替换为el-form,prop绑定具体的校验规则

2)data中添加addForm数据源,校验规则表addformRules

25、实现自定义规则

“邮箱”、“手机号”通过el-form的自定义校验规则。

1) 定义校验规则 checkEmail, checkMobile

checkEmail是一个箭头函数,接受三个参数,rules、value、callback,函数内部使用正则表达式进行校验,当正则表达式结果为true时,调用callback(),否则,callback(new Error('请输入合法的邮箱'))

2)addFormRlues中添加{validator: checkEmile, triggle:'blur'}

26、实现添加用户表单的重置功能

当对话框关闭后再打开,对话框是初始状态《无数据》

1)监听对话框的关闭事件 @close =“addDialogClose”

2)在关闭事件中重置对话框  通过表单对象的resetFields方法 this.$refs.addFormRef.resetFields()

27、添加用户的预检验证功能

点击“确定”按钮时,对表单进行预检验。

1)“确定”按钮i添加点击事件 @click="addUser"

2)点击事件addUser中使用form对象的 validate方法进行校验,参数是一个箭头函数,箭头函数的参数是valid,如果校验通过valid是true,否则为false;

28、发起请求添加一个新用户

校验成功后,发起添加用户的请求

1)封装添加用户请求的api

2)在预校验函数中,调用api接口,发送请求; 请求完毕后,关闭添加用户的对话框,并调用getUser()接口,刷新table数据

29、添加用户修改的操作

点击“修改”按钮,弹出对话框,对话框上显示当前用户的信息,其中 用户名是“只读的”, 邮箱和手机是“可修改的”。

1)引入对话框,“修改”按钮绑定点击事件,弹出对话框

30、根据ID查询用户信息

根据用户的id,发送查询用户信息的请求

1)封装查询用户信息的api

2)发送请求,对请求结果进行处理

31、修改绘制用户表单

1)为表单绑定数据、添加校验规则

32、实现修改表单的关闭之后的重置操作

监听对话框的close事件,拿到表单的引用,然后调用resetFields函数。

33、提交修改之前表单预检验操作

1)给“确定”按钮绑定click事件

2)监听点击事件,触发预检验的回调函数 this.$refs.editForm.validate((valid) =>{})

34、修改用户信息的操作

1)封装修改用户数据请求接口

2)发送请求

35、实现删除用户的操作

点击“删除”按钮,弹出提示消息框MessageBox,提示是否确定删除,防止误删除

1)按需引入MessageBox, 挂载到vue原型上

2)给删除按钮绑定点击事件, 弹出删除提示框

this.$confirm返回值是一个promise,可以使用async/await进行优化,优化后返回值就是一个字符串;async表示该函数是一个异步任务,返回值是一个promise, await是将promise的执行结果返回,并且将await后的语句加入微任务队列,类似于then()后面的语句。

36、完成删除用户的操作

1)封装删除用户信息的Api

2)调用api,执行删除用户操作

37、提交用户列表功能代码

//创建一个user分支,并推送到云端

1)git branch 检查当前分支

2)git checkout -b user 新建一个user分支,并切换到该分支上

3)git branch 检查分支

4)git status 检查user分支上的文件

5)git add . 添加所有文件到暂存区

6)git commit -m "完成用户列表功能的开发"   提交代码到user分支

7)git status 检查user分支上的文件,发现没有新增的文件了,说明提交完毕

8)git push -u origin user 将本地分支user 推送到码云上

//将master分支更新,并推动到云端

9)git checkout master 切换到master主分支

10)git merge user 将master中的代码更新

11)git push 将云端的master分支也更新

五、权限管理开发

1、权限管理开发开始:

创建component/power/Right.vue组件,配置路由表。

1)git branch 查看当前分支

2)git checkout -b rights 创建一个rights子分支

3)git push -u origin rights 将rights子分支推送到远程仓库中

2、开发权限列表对应规格

3、权限列表的基本页面布局

4、获取权限列表数据

1)封装请求权限列表api

2)发送请求

5、权限列表数据渲染

引入el-tag

6、用户、角色、权限三者之间的关系

“用户” 具有不同的“角色”, 每个“角色”对应不同的“权限”

====》 不同的“用户” 有不同的“权限”

7、角色列表管理

1)创建src/components/power/Roles.vue组件

2)配置路由规则

8、角色列表的基础布局及数据获取

1)基本布局

2)封装角色列表请求Api

3)发送请求,渲染页面

多了一个展开列 设置type为expand即可

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

闽ICP备14008679号