目录
1.电商业务概述
2.电商后台管理系统的功能
3.项目初始化步骤
4.后台项目的环境安装配置
4.1. API V1 接口说明
4.2. 支持的请求方法
4.3. 通用返回状态说明
5.测试后台接口是否正常
6.登录/退出功能
1.登录概述
1.登录业务流程
2.登录业务的相关技术点
3.token原理
2.登录功能实现
1.终端执行git status:查看当前工作区是否干净
2.用分支开发登录功能
3.查看项目运行效果
4.删除不需要的组件
5.创建登录组件
6.设置背景颜色
7.组件头像布局
8.登录组件表单布局
9.表单小图标布局
10.表单的数据绑定
11.表单的数据验证
12.表单的重置
13.登录前的预验证
14.根据预验证是否发起请求
15.配置弹窗提示
16.登录成功后的行为
17.创建home组件
18.路由导航守卫控制访问权限
19.退出功能的实现
20.语法警告问题(无问题)
21.提交登录功能代码
7.主页部分
1.主页布局
1.主页Header布局
2.左侧菜单布局
3.通过接口获取菜单数据
4.发起请求获取左侧菜单数据
5.渲染UI结构
6.左侧菜单格式美化
7.左侧菜单的折叠和展开功能
8.首页的路由重定向
9.左侧菜单改为路由链接
10.用户列表开发
11.用户列表的基本UI结构
12.获取用户列表数据
13.渲染用户列表数据
13.用户列表添加索引列
14.状态列的按需展示
15.插槽形式自定义操作列的渲染
16.数据的分页形式
17.用户状态的修改
18.实现搜索的功能
19.实现添加用户的功能
20.添加用户对话框中渲染一个添加用户的表单
21.实现自定义校验规则
22.添加用户表单的重置功能
23.添加用户的预验证功能
24.发起请求添加一个新用户
25.添加用户修改的操作
26.根据id
查询到用户信息
27.绘制修改用户的表单
28.修改表单的关闭后的重置操作
29.修改用户信息的操作
30.实现删除用户的操作
31.提交用户列表功能
1.电商业务概述
根据不同的应用场景,电商系统一般都提供了 PC 端、移动 APP、移动 Web、微信小程序等多种终端访问方式。
- 客户使用的业务服务:PC端,小程序,移动web,移动app
- 管理员使用的业务服务:PC后台管理端。
- PC后台管理端的功能:管理用户账号(登录,退出,用户管理,权限管理),商品管理(商品分类,分类参数,商品信息,订单),数据统计
- 电商后台管理系统采用前后端分离(后端写接口,前端调接口)的开发模式
- 前端项目是基于Vue的SPA(单页应用程序)项目
- 前端技术栈:Vue,Vue-Router,Element-UI,Axios,Echarts
- 后端技术栈:Node.js,Express,Jwt(模拟session(登录记录功能),状态保持工具),Mysql,Sequelize(操作数据库的框架)
一般电商系统是由不同终端组成,共用同一份数据库,同一份接口服务器,通过PC后台管理来管理不同终端访问的数据。
2.电商后台管理系统的功能
电商后台管理系统用于管理用户账号、商品分类、商品信息、订单、数据统计等业务功能。
3.项目初始化步骤
- A.安装Vue脚手架
-
npm i -g @vue/cli
- B.通过脚手架创建项目
-
//使用可视化的形式创建项目 vue ui
手动配置项目->Babel,Router,Linter/Formatter(代码格式校验,风格一致),使用配置文件
-
- C.配置路由
- D.配置Element-UI:在插件中安装,搜索vue-cli-plugin-element(根据自己需要,选择导入方式:按需导入)
- E.配置Axios:在依赖中安装,搜索axios(运行依赖)
- F.初始化git仓库
- 创建仓库,用管理员运行终端,进行Git 全局设置(创建仓库成功后,会显示需要执行的命令)
- G.将本地项目托管到github或者码云中
- 打开项目实战的文件夹,打开powerShell终端,执行git status检查项目状态;在将所有文件放入暂存区git add . ;在本地做一次提交 git commit -m "add files"
- 检查状态,正处于主分支,工作区干净的git status
这只是本地仓库,选择需要跟gittee仓库连通
- 执行gitee简易的命令行内容
git remote add origin https://gitee.com...git git push -u origin "master"
4.后台项目的环境安装配置
A.使用Navicat导入mysql数据库数据
B.安装Node.js环境,配置后台项目,从终端打开后台项目vue_api_server 然后在终端中输入命令安装项目依赖包:npm install,在执行node .\app.js
C.使用postman测试api接口
4.1. API V1 接口说明
-
接口基准地址:
http://127.0.0.1:8888/api/private/v1/
-
服务端已开启 CORS 跨域支持
-
API V1 认证统一使用 Token 认证
-
需要授权的 API ,必须在请求头中使用
Authorization
字段提供token
令牌 -
使用 HTTP Status Code 标识状态
-
数据返回格式统一使用 JSON
4.2. 支持的请求方法
-
GET(SELECT):从服务器取出资源(一项或多项)。
-
POST(CREATE):在服务器新建一个资源。
-
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
-
PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
-
DELETE(DELETE):从服务器删除资源。
-
HEAD:获取资源的元数据。
-
OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。
4.3. 通用返回状态说明
状态码 | 含义 | 说明 |
---|---|---|
200 | OK | 请求成功 |
201 | CREATED | 创建成功 |
204 | DELETED | 删除成功 |
400 | BAD REQUEST | 请求的地址不存在或者包含不支持的参数 |
401 | UNAUTHORIZED | 未授权 |
403 | FORBIDDEN | 被禁止访问 |
404 | NOT FOUND | 请求的资源不存在 |
422 | Unprocesable entity | [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误 |
500 | INTERNAL SERVER ERROR | 内部错误 |
5.测试后台接口是否正常
修改mysql数据库密码为自己电脑数据库的密码
在default.json中有后端的数据库配置文件,本机中的数据库名称,账号,密码与数据库配置文件中的保持一致,后台服务器才能访问到该数据库。
6.登录/退出功能
1.登录概述
1.登录业务流程
- 在登录页面输入用户名和密码
- 调用后台接口进行验证
- 通过验证之后,根据后台的响应状态跳转到项目主页
2.登录业务的相关技术点
- http是无状态的
- 通过cookie在客户端记录状态
- 通过session在服务器端记录状态
- 通过token方式维持状态
存在跨域问题,推荐使用token;不存在跨域问题,推荐使用cookie,session。
- A.登录状态保持 如果服务器和客户端同源,建议可以使用cookie或者session来保持登录状态 如果客户端和服务器跨域了,建议使用token进行维持登录状态。
- B.登录逻辑: 在登录页面输入账号和密码进行登录,将数据发送给服务器 服务器返回登录的结果,登录成功则返回数据中带有token 客户端得到token并进行保存,后续的请求都需要将此token发送给服务器,服务器会验证token以保证用户身份。
- C.添加新分支login,在login分支中开发当前项目vue_shop: 打开vue_shop终端,使用git status确定当前项目状态。 确定当前工作目录是干净的之后,创建一个分支进行开发,开发完毕之后将其合并到master git checkout -b login 然后查看新创建的分支:git branch 确定我们正在使用login分支进行开发
3.token原理
2.登录功能实现
登录页面的布局,通过——Element-UI组件实现布局
- el-form
- el-form-item
- el-input
- el-button
- 字体图标
1.终端执行git status:查看当前工作区是否干净
2.用分支开发登录功能
创建分支
git checkout -b login
查看分支
git branch
3.查看项目运行效果
点击任务->serve运行->启动app
4.删除不需要的组件
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
]
const router = new VueRouter({
routes
})
export default router
App.vue
<template>
<div id="app">App根组件</div>
</template>
<script>
export default {
name: 'app'
}
</script>
<style>
</style>
5.创建登录组件
components/Login.vue
<template>
<div>登录组件</div>
</template>
src/router/index.js
import Login from '@/components/Login.vue'
const routes = [
{ path: '/login', component: Login }
]
App.vue
<template>
<div id="app">App根组件
<!-- 放路由占位符 -->
<router-view></router-view>
</div>
</template>
component name XXX should always be multi-word 报错
.eslintrc.js
// 在rules中添加自定义规则
rules: {
// 关闭组件命名规则
// 'vue/multi-word-component-names': 'off'
// 关闭命名规则,不会校验组件名;最好设置:根据组件名进行忽略
// 忽略部分组件名
// 添加组件命名忽略规则
"vue/multi-word-component-names": ["error", {
"ignores": ["Login"]//需要忽略的组件名
}]
}
重定向规则,让它默认为login页面
const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login }
]
6.设置背景颜色
<template>
<div class="login_container">登录组件</div>
</template>
<style lang="less" scoped>
.login_container {
background-color: pink;
height: 100%;
}
.login_box {
width: 450px;
height: 300px;
background-color: #fff;
border-radius: 3px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
</style>
报错Can't resolve 'less-loader' in,需要添加依赖
终端下载依赖(开发依赖)---版本出错
npm i less@3.9.0 less-loader@4.1.0 --save-dev
vue ui下载开发依赖less和less-loader ---正常使用
src/assets/css/global.css
/* 全局样式表 */
html,
body,
#app{
height: 100%;
margin: 0;
padding:0;
}
main.js
// 导入全局样式表
import './assets/css/global.css'
7.组件头像布局
<div class="login_container">
<div class="login_box">
<div class="avatar_box">
<img src="../assets/logo.png" alt="" />
</div>
</div>
</div>
.avatar_box {
height: 130px;
width: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 10px;
box-shadow: 0 0 10px #ddd;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background-color: #fff;
img {
width: 100%;
height: 100%;
border-radius: 50%;
background-color: #eee;
}
}
8.登录组件表单布局
<!-- 登录表单区域 -->
<el-form label-width="0" class="login_form">
<!-- 用户名 -->
<el-form-item>
<el-input prefix-icon="el-icon-search"></el-input>
</el-form-item>
<!-- 密码 -->
<el-form-item>
<el-input prefix-icon="el-icon-search"></el-input>
</el-form-item>
<!-- 按钮区域 -->
<el-form-item class="btns">
<el-button type="primary">登录</el-button>
<el-button type="info">重置</el-button>
</el-form-item>
</el-form>
.login_form {
position: absolute;
bottom: 0;
// 只占左边一半,需要设置宽度
width: 100%;
padding: 0 20px;
// 超出区域了,需要设置border-box
box-sizing: border-box;
}
.btns {
// 居右对齐
display: flex;
justify-content: flex-end;
}
src/plugins/element.js
import { Button, Form, FormItem, Input } from 'element-ui'
//Vue.use(Button, Form, FormItem, Input)错误,要分别使用
Vue.use(Button)
Vue.use(Form)
Vue.use(FormItem)
Vue.use(Input)
Element文章来源:https://www.toymoban.com/news/detail-447973.html
9.表单小图标布局
prefix-icon="el-icon-search"
Element
elment图标不完整,使用iconfont图标下载图标形式,使用图标,
- 将图标文件夹fonts放入assets文件夹
- 在main.js中导入字体图标
-
// 导入字体图标 import './assets/fonts/iconfont.css'
- 在Login.vue进行使用
-
<el-form-item> <el-input prefix-icon="iconfont icon-user"></el-input> </el-form-item> <el-form-item> <el-input prefix-icon="iconfont icon-3702mima"></el-input> </el-form-item>
10.表单的数据绑定
- 1.el-form添加:model属性绑定,指向一个数据对象
- 2.为每一个表单项通过v-model绑定到数据对象上对应的属性中
<el-form :model="loginForm">
data () {
return {
// 这是登录表单的数据绑定对象
loginForm:{
username: '',
password: ''
}
}
},
<el-input v-model="loginForm.username"></el-input>
<el-input v-model="loginForm.password"type="password"></el-input>
11.表单的数据验证
- 1.为el-form通过属性绑定,指定一个:rules校验对象
- 2.在data数据中定义这个校验对象,每一个属性都是一个验证规则
- 3.为不同的表单item项el-form-item,通过props指定不同的验证规则,来进行表单的验证
<el-form :rules="loginFormRules">
// 这是表单的验证规则对象
loginFormRules: {
// 验证用户名是否合法
username: [
{ required: true, message: '请输入登录名称', trigger: 'blur' },
{ min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
],
// 验证密码是否合法
password: [
{ required: true, message: '请输入登录密码', trigger: 'blur' },
{ min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
]
}
<el-form-item prop="username">
<el-form-item prop="password">
12.表单的重置
- 为表单添加ref引用,ref的值就是组件的实例对象(拿到表单的实例对象,使用ref绑定组件(ref相当于给当前标签取名字,用这个名字可以直接获取到这个元素并且操作它里面的数据))
- 重置按钮绑定事件,通过this访问到$refs,点出表单的引用对象loginFormRef,直接调用resetFields( )方法
- 即可重置表单
<el-form ref="loginFormRef">
<el-button type="info" @click="resetLoginForm">重置</el-button>
methods: {
// 点击重置按钮,重置登录表单
resetLoginForm () {
console.log(this)// 通过this,可以直接获取引用对象(就是这个组件的实例)
this.$refs.loginFormRef.resetFields()
}
}
13.登录前的预验证
当点击登录按钮,要进行一下验证,验证通过才能进行登录。
- 为登录按钮绑定点击事件login
- 调用表单的引用对象loginFormRef,调用validate函数进行验证,接收一个回调函数,从而拿到验证结果
- 符合要求则输出true,不符合要求则输出false(布尔值)
<el-button type="primary" @click="login">登录</el-button>
login () {
this.$refs.loginFormRef.validate((valid) => {
console.log(valid)
})
}
14.根据预验证是否发起请求
login () {
this.$refs.loginFormRef.validate(valid => {
// console.log(valid)
// valid为false则return,不发起请求
if (!valid) return
})
}
添加到vue.prototype.$http后,可以在每一个组件上通过this.$http获取axios,不必在每个页面都import axios,$http是自定义属性名,可以随便起名。
main.js
// 对axios进行全局配置
import axios from 'axios'
// 配置请求根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
Vue.prototype.$http = axios
返回结果是promise,可以用async await来简化promise操作。
只有data才是服务器返回的数据,可以直接解构data
login () {
this.$refs.loginFormRef.validate(async valid => {
// console.log(valid)
// valid为false则return,不发起请求
if (!valid) return
// loginForm当成请求参数,因为用户填写的数据会同步到loginForm
// const result = await this.$http.post('login', this.loginForm)
// console.log(result)
const { data: res } = await this.$http.post('login', this.loginForm)
console.log(res)
if (res.meta.status !== 200) return console.log('登录失败')
console.log('登录成功')
})
}
15.配置弹窗提示
src/plugins/element.js
// 导入弹框提示组件
import { Message } from 'element-ui'
// 在Message挂载到Vue原型上,每个组件都可以直接通过this,访问到Message
Vue.prototype.$message = Message
if (res.meta.status !== 200) return this.$message.error('登录失败')
this.$message.success('登录成功')
Element
16.登录成功后的行为
- 将登录后的token,保存到客户端的sessionStorage中
- 项目中除了登录之外的其他API接口,必须在登录之后才能访问
- token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
- 通过编程式导航跳转到后台主页,路由地址是 /home
// 1.将登录后的token,保存到客户端的sessionStorage中
// 1.1项目中除了登录之外的其他API接口,必须在登录之后才能访问
console.log(res)
// 1.2token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
window.sessionStorage.setItem('token', res.data.token)
// 2.通过编程式导航跳转到后台主页,路由地址是/home
this.$router.push('/home')
17.创建home组件
18.路由导航守卫控制访问权限
只允许在登录成功后才能看见home组件。
如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面。
- to:将要访问的那个页面路径
- from:从哪个页面路径跳转而来的
- next:放行函数
//为路由对象,添加beforeEach导航守卫
router.beforeEach((to,from,next)=>{
//如果用户访问的登录页,直接放行
if(to.path === '/login') return next()
//从sessionStorage中获取到保存的token值
const tokenStr = window.sessionStorage.getItem('token')
//没有token,强制跳转到登录页
if(!tokenStr) return next('/login')
next()
})
src/router/index.js
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
// to 将要访问的路径
// from 代表从哪个路径跳转而来
// next 是一个函数,表示放行
// next() 放行 next('/login') 强制跳转
if (to.path === '/login') return next()
// 获取token
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
19.退出功能的实现
基于token的方式实现退出比较简单,只需要摧毁本地的token即可。这样,后续的请求就不会携带token,必须重新登录生成一个新的token之后才可以访问。
//清空token
window.sessionStorage.clear()
//跳转到登录页,重定向到登录页
this.$router.push('/login')
Home.vue
<template>
<div>
<el-button type="info" @click="logout">退出</el-button>
</div>
</template>
logout () {
window.sessionStorage.clear()
this.$router.push('/login')
}
20.语法警告问题(无问题)
shift+alt+f格式化文件
创建格式化配置文件.prettierrc
{
// 末尾不加分号
"semi": false,
// 启用单引号的格式化方式
"singleQuote": true
}
.eslintrrc.js关闭某语法规则
'space-before-function-paren': 0
我在setting json中已经全局设置了
21.提交登录功能代码
1.git status 检查当前代码
2.git add . 添加代码到暂存区
3.git status
4.git commit -m "完成了登录功能" 把暂存区的代码提交到本地仓库中
5.git branch 检查所处分支
6.把login分支代码合并到master主分支中
- 1.切换到master主分支
- git checkout master
- 检查发现处于master分支
- 2.再从主分支合并login分支
- git merge login
7.远程推送,把本地的master分支推送到远程的码云中 git push
8.把本地的login分支推送到远程码云中(远程码云只有master分支)
- git checkout login 切换到login子分支
- 检查分支状态 git branch
- 推送到码云中,需要使用 git push -u origin login(将本地的login分支推送到远程的origin仓储里面,并且叫做login子分支,进行保存)
7.主页部分
1.主页布局
Home.vue
<el-container>
<!-- 头部区域 -->
<el-header>
<el-button type="info" @click="logout">退出</el-button>
</el-header>
<!-- 页面主体区域 -->
<el-container>
<!-- 侧边栏 -->
<el-aside width="200px">Aside</el-aside>
<!-- 右侧内容主体 -->
<el-main>Main</el-main>
</el-container>
</el-container>
<style lang="less" scoped>
// 没有撑满全屏,需要添加home-container
.home-container {
height: 100%;
}
.el-header {
background-color: rgb(69, 14, 65);
}
.el-aside {
background-color: rgb(165, 59, 154);
}
.el-main {
background-color: rgb(241, 192, 241);
}
</style>
element.js注册组件
import { Container,Header,Aside,Main } from 'element-ui'
Vue.use(Container)
Vue.use(Header)
Vue.use(Aside)
Vue.use(Main)
Element
1.主页Header布局
左右布局,flex布局。
<el-header>
<div>
<img src="../assets/logo.png" alt="" />
<span>电商后台管理系统</span>
</div>
<el-button type="info" @click="logout">退出</el-button>
</el-header>
.el-header {
background-color: rgb(69, 14, 65);
display: flex;
justify-content: space-between;
padding-left: 0;
align-items: center;
color: #fff;
font-size: 20px;
// 嵌套div
> div {
display: flex;
align-items: center;
span {
margin-left: 15px;
}
}
img {
height: 50px;
}
}
2.左侧菜单布局
<el-aside width="200px">
<!-- 侧边栏菜单区 -->
<el-menu
background-color="#545c64"
text-color="#fff"
active-text-color="#ffd04b"
>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>导航一</span>
</template>
<el-menu-item-group>
<template slot="title">分组一</template>
<el-menu-item index="1-1">选项1</el-menu-item>
<el-menu-item index="1-2">选项2</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="分组2">
<el-menu-item index="1-3">选项3</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">选项4</template>
<el-menu-item index="1-4-1">选项1</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span slot="title">导航二</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span slot="title">导航三</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span slot="title">导航四</span>
</el-menu-item>
</el-menu>
</el-aside>
按需导入element.js
import { Menu, Submenu, MenuItem } from 'element-ui'
Vue.use(Menu)
Vue.use(Submenu)
Vue.use(MenuItem)
梳理结构
<!-- 侧边栏 -->
<el-aside width="200px">
<!-- 侧边栏菜单区 -->
<el-menu
background-color="rgb(165, 59, 154)"
text-color="#fff"
active-text-color="rgb(69, 14, 65)"
>
<!-- 一级菜单 -->
<el-submenu index="1">
<!-- 一级菜单的模板区域 -->
<template slot="title">
<!-- 图标 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>导航一</span>
</template>
<!-- 二级菜单 -->
<el-menu-item index="1-4-1">
<template slot="title">
<!-- 图标 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>导航一</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
Element
3.通过接口获取菜单数据
接口说明:需要授权的API,必须在请求头中使用Authorization字段提供token令牌。
所以需要:通过axios请求拦截器添加token,保证拥有获取数据的权限。
后台除了登录接口之外,都需要token权限验证,我们可以通过添加axios请求拦截器来添加token,以保证拥有获取数据的权限
//axios请求拦截
//请求在到达服务器之前,先会调用use中的这个回调函数来添加请求头信息
axios.interceptors.request.use(config => {
//为请求头对象,添加Token验证的Authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
在重新登录或会获取到此数据
发起login的登录请求,request请求头Headers中包括Authorization:null(登录期间是null,服务器没有颁发令牌;如果登录之后,再用其他接口,此时这个值就不是null)(符合要求才会执行请求 ,不符合要求或者请求不存在,则服务器驳回请求)
main.js
// 配置请求根路径
axios.defaults.baseURL = 'http://127.0.0.1:8888/api/private/v1/'
// 在挂载到原型对象之前,先设置一个拦截器
axios.interceptors.request.use(config => {
config.headers.Authorization = window.sessionStorage.getItem('token')
console.log(config)// 获取headers数据
// 在最后必须要return config
return config
})
Vue.prototype.$http = axios
这时,有权限的API就能调用成功了。
4.发起请求获取左侧菜单数据
左侧菜单权限
- 请求路径:menus
- 请求方法:get
- 响应数据
{
"data":
{
"id": 101,
"authName": "商品管理",
"path": null,
"children": [
{
"id": 104,
"authName": "商品列表",
"path": null,
"children": []
}
]
}
"meta": {
"msg": "获取菜单列表成功",
"status": 200
}
}
请求左侧菜单:在刚一加载时就应该获取左侧菜单(所以在created时要进行调用)。
data () {
return {
// 左侧菜单数据
menulist: []
}
},
created () {
this.getMenuList()
},
methods: {
// 获取所有的菜单
async getMenuList () {
const { data: res } = await this.$http.get('menus')
// 获取到的数据立即挂载到自己的data中,赋值
if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
this.menulist = res.data
console.log(res)
}
}
5.渲染UI结构
<!-- 一级菜单 -->
<!-- index相同的话,点开其中一个,所有都会展开,每一个都应该有一个独属于自己的index值:报错,index只接收字符串不接收数值,所有需要转成字符串 +'' -->
<el-submenu
:index="item.id + ''"
v-for="item in menulist"
:key="item.id"
>
<!-- 一级菜单的模板区域 -->
<template slot="title">
<!-- 图标 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>{{ item.authName }}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item
:index="subItem.id + ''"
v-for="subItem in item.children"
:key="subItem.id"
>
<template slot="title">
<!-- 图标 -->
<i class="el-icon-location"></i>
<!-- 文本 -->
<span>{{ subItem.authName }}</span>
</template>
</el-menu-item>
</el-submenu>
6.左侧菜单格式美化
二级菜单小图标修改;一级菜单图标,每一个一级菜单图标都不一样,element不能满足需求,使用iconfont,将字体图标按照顺序更改到一级菜单图标上。在自动生成期间,加上图标,使用data初始化图标,以id为key,id对应图标为它的值。
<i :class="iconObj[item.id]"></i>
data () {
return {
// 左侧菜单数据
menulist: [],
iconObj: {
125: 'iconfont icon-user',
103: 'iconfont icon-tijikongjian',
101: 'iconfont icon-shangpin',
102: 'iconfont icon-shangpin',
145: 'iconfont icon-baobiao'
}
}
},
.iconfont {
margin-right: 10px;
}
如果想要实现,点击一个一级菜单,再点击第二个一级菜单,之前点击的一级菜单收回情况(每次只展开一个),可以通过修改下面属性
<el-menu
background-color="rgb(165, 59, 154)"
text-color="#fff"
active-text-color="rgb(69, 14, 65)"
unique-opened
>
Element
解决细微的对齐问题
.el-aside {
background-color: rgb(165, 59, 154);
.el-menu {
border-right: none;
}
}
7.左侧菜单的折叠和展开功能
//侧边栏不能跟着宽度变化,需要动态绑定在isCollapse。折叠,则为64px;不折叠,则为200px
<el-aside :width="isCollapse ? '64px' : '200px'">
<div class="toggle-button" @click="toggleCollaapse">|||</div>
<el-menu
:collapse="isCollapse"
:collapse-transition="false"
>
// 是否折叠
isCollapse: false
// 点击按钮,切换菜单的折叠和展开
toggleCollaapse () {
this.isCollapse = !this.isCollapse
}
.toggle-button {
background-color: rgb(217, 119, 225);
font-size: 10px;
line-height: 24px;
color: #fff;
text-align: center;
letter-spacing: 0.2em;
cursor: pointer;
}
8.首页的路由重定向
登录成功后,在main区域显示欢迎页面;home路由中嵌套显示了main子路由组件。
只要访问了home这个地址,就显示Welcome子路由规则。
router/index.js
{
path: '/home',
component: Home,
redirect: '/welcome',
children: [
{ path: '/welcome', component: Welcome }
]
}
Home.vue
<!-- 右侧内容主体 -->
<el-main>
<!-- 路由占位符 -->
<router-view></router-view>
</el-main>
9.左侧菜单改为路由链接
把每一个设置为router-link(麻烦),通过element router属性完成,为整个侧边栏开启路由模式。(简单)
<!-- 侧边栏菜单区 -->
<el-menu
router
>
path作为唯一的跳转路径合适,比id好;path不是以‘/’开头的,需要我们对齐补充
<!-- 二级菜单 -->
<el-menu-item
:index="'/' + subItem.path"
>
点击二级菜单可以进行跳转
Element
10.用户列表开发
router.js
import Users from '@/components/user/Users.vue'
{
path: '/home',
component: Home,
redirect: '/welcome',
children: [
{ path: '/welcome', component: Welcome },
{ path: '/users', component: Users }
]
}
此时点击用户列表,右侧会显示用户列表的组件内容
解决无高亮现象(高亮效果的动态切换)
点击链接时把对应的地址保存到sessionStorage中,在刷新时(home杠创建的时候)就立即把值取出来,赋值到左边菜单即可。
default-active="/users"//写死
- 给二级菜单绑定单击事件
- 定义点击事件函数,保存链接的激活状态(把对应的index值保存到sessionStorage中)
- 把值重新取出来,在data中定义数据activePath,保存激活的链接
- 把activePath地址动态保存到el-menu上(:default-active="activePath")
- 给它动态赋值,在整个home组件一被创建时,就把sessionStorage中的值取出来,给它赋值上去
- 在点击不同链接时,应该为activePath重新赋值
<!-- 侧边栏菜单区 -->
<el-menu
:default-active="activePath"
>
<!-- 二级菜单 -->
<el-menu-item
@click="saveNavState('/' + subItem.path)"
>
// 被激活的链接地址
activePath: ''
created () {
this.activePath = window.sessionStorage.getItem('activePath')
}
// 保存链接的激活状态
saveNavState (activePath) {
window.sessionStorage.setItem('activePath', activePath)
this.activePath = activePath
}
点击用户列表,就会多一个键
保存记录你所选择的path(提留的界面),然后储存在sessionStorage中,重新加载时就从sessionStorage中查看你的历史记录,你浏览了其他的path则需要通过sessionStorage更新一下。
11.用户列表的基本UI结构
import { Breadcrumb, BreadcrumbItem, Card, Row, Col } from 'element-ui'
Vue.use(BreadcrumbItem)
Vue.use(Breadcrumb)
Vue.use(Card)
Vue.use(Row)
Vue.use(Col)
<div>
<!-- 面包屑导航区域 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
<!-- 卡片视图区域 -->
<el-card class="box-card">
<!-- 搜索与添加区域 -->
<el-row :gutter="20">
<el-col :span="8">
<el-input placeholder="请输入内容">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-col>
<el-col :span="4">
<el-button type="primary">添加用户</el-button>
</el-col>
</el-row>
</el-card>
</div>
Element
Element
Element
Element
src/assets/css/global.css
.el-breadcrumb {
margin-bottom: 15px;
font-size: 12px;
}
.el-card {
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important;
}
12.获取用户列表数据
// 获取用户列表的参数对象
queryInfo: {
query: '',
pagenum: 1,
pagesize: 2
},
userlist: [],
total: 0
created () {
this.getUserList()
},
async getUserList () {
const { data: res } = await this.$http.get('users', { params: this.queryInfo })
if (res.meta.status !== 200) {
return this.$message.error('获取用户列表失败!')
}
this.userlist = res.data.users
this.total = res.data.total
console.log(res)
}
13.渲染用户列表数据
import {Table,TableColumn } from 'element-ui'
Vue.use(Table)
Vue.use(TableColumn)
<!-- 用户列表区域 -->
<el-table :data="userlist" border stripe>
//label:当前页的标题;prop:指向这一列的数据
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="邮箱" prop="email"></el-table-column>
<el-table-column label="电话" prop="mobile"></el-table-column>
<el-table-column label="角色" prop="role_name"></el-table-column>
<el-table-column label="状态" prop="mg_state"></el-table-column>
<el-table-column label="操作"></el-table-column>
</el-table>
src/assets/css/global.css
.el-table {
margin-top: 15px;
font-size: 12px;
}
Element
13.用户列表添加索引列
<el-table-column type="index" label="#"></el-table-column>
14.状态列的按需展示
通过作用域插槽来渲染当前状态列。
- 先在状态列中定义一个作用域插槽,通过slot-scope接收当前作用域的数据
- 通过scope.row拿到对应这一行的数据
- 需要把整个开关的状态绑定到哪个属性身上,v-model上绑定具体地方属性值即可
- 此时,prop="mg_state"可以删除,作用域插槽会覆盖prop
import { Switch } from 'element-ui'
Vue.use(Switch)
<el-table-column label="状态">
<template slot-scope="scope">
<!-- {{ scope.row }} -->
<!-- 通过作用域插槽接收了scope,scope.row就等于这一行对应的数据 -->
<el-switch v-model="scope.row.mg_state"> </el-switch>
</template>
</el-table-column>
Element
15.插槽形式自定义操作列的渲染
import { Tooltip } from 'element-ui'
Vue.use(Tooltip)
<el-table-column label="操作" width="180">
<template slot-scope="">
<!-- 修改按钮 -->
<el-button
type="primary"
icon="el-icon-edit"
size="mini"
></el-button>
<!-- 删除按钮 -->
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
></el-button>
<!-- 分配角色按钮 -->
<el-tooltip
effect="dark"
content="分配角色"
placement="top-start"
:enterable="false"
>
<el-button
type="warning"
icon="el-icon-setting"
size="mini"
></el-button>
</el-tooltip>
</template>
</el-table-column>
Element
Element
16.数据的分页形式
使用element ui分页组件。
- 按需导入这个分页组件
- 定义 size-change的handleSizeChange事件( 监听最新的pagesize),定义current-change的handleCurrentChange事件(监听最新的页码值pagenum)
- 只要页码值pagenum或者pagesize发生改变,就立即发起一次新的数据请求
- 通过不同的属性配置页码条
import { Pagination } from 'element-ui'
Vue.use(Pagination)
<!-- 分页区域 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[1, 2, 5, 10]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
>
</el-pagination>
// 获取用户列表的参数对象
queryInfo: {
query: '',
// 当前的页数
pagenum: 1,
// 当前每页显示多少条数据
pagesize: 2
},
userlist: [],
total: 0
// 监听pagesize改变的事件
handleSizeChange (newsize) {
// console.log(newsize)
this.queryInfo.pagesize = newsize
this.getUserList()
},
// 监听页码值改变的事件,可以拿到最新的页码值
handleCurrentChange (newPage) {
// console.log(newPage)
this.queryInfo.pagenum = newPage
this.getUserList()
}
assets/css/global.css
.el-pagination {
margin-top: 15px;
}
Element
17.用户状态的修改
把用户状态同步到数据库中进行保存。
-
监听switch开关状态的改变,从而拿到状态
-
调用对应的API接口,把最新的状态保存到数据库中
<!-- 只要调用了这个函数,就可以把当前用户的信息传过去,因为当前switch是通过v-model双向绑定到了scope.row.mg_state上,只要状态改变了,mg_state也会改变,所以直接把这一行的数据scope.row传到函数userStateChanged中 -->
<el-switch
v-model="scope.row.mg_state"
@change="userStateChanged(scope.row)">
</el-switch>
// 监听switch开关状态的改变
async userStateChanged (userinfo) {
console.log(userinfo)
const { data: res } = await this.$http.put(`users/${userinfo.id}/state/${userinfo.mg_state}`)
// 如果获取用户状态失败了,应该把状态重置回去
if (res.meta.status !== 200) {
userinfo.mg_state = !userinfo.mg_state
return this.$message.error('更新用户状态失败!')
}
this.$message.success('更新用户状态成功')
}
修改用户状态的API
-
请求路径:users/:uId/state/:type
-
请求方法:put
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
uId | 用户 ID | 不能为空携带在url中
|
type | 用户状态 | 不能为空携带在url中 ,值为 true 或者 false |
-
响应数据
{
"data": {
"id": 566,
"rid": 30,
"username": "admin",
"mobile": "123456",
"email": "bb@itcast.com",
"mg_state": 0
},
"meta": {
"msg": "设置状态成功",
"status": 200
}
}
18.实现搜索的功能
- 在input上使用v-model双向绑定queryInfo
- 为搜索按钮绑定点击事件getUserList,点击了一次这个按钮,就会发起一次查询用户的请求
<el-input
placeholder="请输入内容"
v-model="queryInfo.query"
clearable
@clear="getUserList">
<el-button
@click="getUserList"
></el-button>
</el-input>
19.实现添加用户的功能
- 按需导入对话框组件
- 复制粘贴对话框结构
- 点击按钮可以隐藏对话框和显示对话框
import { Dialog } from 'element-ui'
Vue.use(Dialog)
<el-button type="primary" @click="addDialogVisible = true"
<!-- 添加用户的对话框 -->
<el-dialog
title="提示"
:visible.sync="addDialogVisible"
width="50%"
>
<!-- 内容主体区域 -->
<span>这是一段信息</span>
<!-- 底部区域 -->
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addDialogVisible = false"
>确 定</el-button
>
</span>
</el-dialog>
// 控制添加用户对话框的显示和隐藏
addDialogVisible: false
Element
20.添加用户对话框中渲染一个添加用户的表单
<!-- 内容主体区域 -->
<el-form
:model="addForm"
:rules="addFormRules"
ref="addFormRef"
label-width="70px"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="addForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="addForm.password"></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="addForm.email"></el-input>
</el-form-item>
<el-form-item label="手机" prop="mobile">
<el-input v-model="addForm.mobile"></el-input>
</el-form-item>
</el-form>
// 添加用户的表单数据
addForm: {
username: '',
password: '',
email: '',
mobile: ''
},
// 添加表单的验证规则对象
addFormRules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur'},
{ min: 3, max: 10, message: '用户名的长度在3-10个字符之间', trigger: 'blur'}
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur'},
{ min: 6, max: 15, message: '用户名的长度在6-15个字符之间', trigger: 'blur'}
],
email: [
{required: true, message: '请输入邮箱', trigger: 'blur'}
],
mobile: [
{required: true, message: '请输入手机号', trigger: 'blur'}
]
}
21.实现自定义校验规则
- 定义一个箭头函数,写自定义校验规则
- 在具体的校验规则中,通过validator来使用上面自定义校验规则
data () {
// 验证邮箱的规则
// rule:规则;value:待检验的value值;cb:回调函数
const checkEmail = (rule, value, cb) => {
// 验证邮箱的正则表达式
const regEmail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/
if (regEmail.test(value)) {
// 合法的邮箱
return cb()
}
cb(new Error('请输入合法的邮箱'))
}
// 验证手机号的规则
const checkMobile = (rule, value, cb) => {
// 验证手机号的正则表达式
const regMobile = /^(0|86|17951)?(13[0-9]|15[0123456789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
// 如果时合法的手机号,则直接return cb()
if (regMobile.test(value)) {
return cb()
}
// 不合法,调用cb,传递错误对象
cb(new Error('请输入合法的手机号'))
}
email: [
{ required: true, message: '请输入邮箱', trigger: 'blur'},
{validator: checkEmail, trigger: 'blur'}
],
mobile: [
{required: true, message: '请输入手机号', trigger: 'blur'},
{ validator: checkMobile, trigger: 'blur'}
]
}
Element
22.添加用户表单的重置功能
监听对话框的关闭事件以及对话框的重置事件。
<el-dialog @close="addDialogClosed">
// 监听添加用户对话框的关闭事件
addDialogClosed () {
this.$refs.addFormRef.resetFields()
}
- 要监听对话框的close事件
- 在close事件的处理函数中,拿到表单的引用$refs
- 调用resetFields( )方法
23.添加用户的预验证功能
在点击确认按钮后,不应该直接关闭对话框,应该在点击这个按钮的时候调用函数,在函数中对整个表单进行预验证。
<el-button @click="addUser">确 定</el-button>
// 点击按钮添加新用户
addUser () {
this.$refs.addFormRef.validate(valid => {
// 接收校验结果
console.log(valid)// 布尔值
if (!valid) return
// 可以发起添加用户的网络请求
})
}
24.发起请求添加一个新用户
-
请求路径:users
-
请求方法:post
-
请求参数(跟addForm相同)
参数名 | 参数说明 | 备注 |
---|---|---|
username | 用户名称 | 不能为空 |
password | 用户密码 | 不能为空 |
邮箱 | 可以为空 | |
mobile | 手机号 | 可以为空 |
-
响应参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 ID | |
rid | 用户角色 ID | |
username | 用户名 | |
mobile | 手机号 | |
邮箱 |
- 响应数据
{
"data": {
"id": 28,
"username": "tige1200",
"mobile": "test",
"type": 1,
"openid": "",
"email": "test@test.com",
"create_time": "2017-11-10T03:47:13.533Z",
"modify_time": null,
"is_delete": false,
"is_active": false
},
"meta": {
"msg": "用户创建成功",
"status": 201
}
}
// 点击按钮添加新用户
addUser () {
this.$refs.addFormRef.validate(async valid => {
// 接收校验结果
console.log(valid)// 布尔值
if (!valid) return
// 可以发起添加用户的网络请求
const { data: res } = await this.$http.post('users', this.addForm)
if (res.meta.status !== 201) {
this.$message.error('添加用户失败!')
}
this.$message.success('添加用户成功!')
// 隐藏添加用户的对话框
this.addDialogVisible = false
// 刷新列表,重新获取用户列表数据
this.getUserList()
})
}
25.添加用户修改的操作
为修改按钮绑定点击事件,点击按钮就会弹出修改的对话框。
<!-- 修改按钮 -->
<el-button @click="showEditDialog()"></el-button>
<!-- 修改用户的对话框 -->
<el-dialog title="修改用户" :visible.sync="editDialogVisible" width="50%">
<span>这是一段信息</span>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="editDialogVisible = false"
>确 定</el-button>
</span>
</el-dialog>
// 控制修改用户对话框的显示与隐藏
editDialogVisible: false
// 展示编辑用户的对话框
showEditDialog () {
this.editDialogVisible = true
}
Element
26.根据id查询到用户信息
根据用户的id查询到用户的旧数据,并且保存起来。
- 先在调用方法的时候,把用户的id通过scope.row.id将其传进去
- 接收到id后,调用API 接口查询用户信息
- 把查询到的用户信息存到editForm表单数据对象上
<template slot-scope="scope">
<!-- 修改按钮 -->
<el-button
type="primary"
icon="el-icon-edit"
size="mini"
@click="showEditDialog(scope.row.id)"
></el-button>
// 查询到的用户信息对象
editForm: {}
// 展示编辑用户的对话框
async showEditDialog (id) {
console.log(id)
const { data: res } = await this.$http.get('users/' + id)
if (res.meta.status !== 200) {
return this.$message.error('查询用户信息失败!')
}
// 给它进行赋值
this.editForm = res.data
this.editDialogVisible = true
}
-
请求路径:users/:id
-
请求方法:get
-
请求参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 ID | 不能为空携带在url中
|
-
响应参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 ID | |
role_id | 角色 ID | |
mobile | 手机号 | |
邮箱 |
-
响应数据
{
"data": {
"id": 503,
"username": "admin3",
"role_id": 0,
"mobile": "00000",
"email": "new@new.com"
},
"meta": {
"msg": "查询成功",
"status": 200
}
}
27.绘制修改用户的表单
- 通过element ui把表单项粘贴过来
- 提供:model="editForm"; :rules="editFormRules";ref="editFormRef"
-
提供修改表单的验证规则对象editFormRules
<el-form
:model="editForm"
:rules="editFormRules"
ref="editFormRef"
label-width="70px"
>
<el-form-item label="用户名">
<el-input v-model="editForm.username" disabled></el-input>
</el-form-item>
<el-form-item label="邮箱" prop="email">
<el-input v-model="editForm.email"></el-input>
</el-form-item>
<el-form-item label="手机号" prop="mobile">
<el-input v-model="editForm.mobile"></el-input>
</el-form-item>
</el-form>
// 修改表单的验证规则对象
editFormRules: {
email: [
{
required: true,
message: '请输入用户邮箱',
trigger: 'blur'
},
{ validator: checkEmail, trigger: 'blur' }
],
mobile: [
{
required: true,
message: '请输入用户手机',
trigger: 'blur'
},
{ validator: checkMobile, trigger: 'blur' }
]
}
Element
28.修改表单的关闭后的重置操作
- 监听对话框的close事件
- 在close事件中应该重置表单
<el-dialog @close="editDialogClosed">
// 监听修改用户对话框的关闭事件
editDialogClosed () {
this.$refs.editFormRef.resetFields()
}
29.修改用户信息的操作
-
提交修改之前表单预验证操作
-
然后再修改用户信息的操作
<el-button type="primary" @click="editUserInfo">确 定</el-button>
// 修改用户信息并提交
editUserInfo () {
this.$refs.editFormRef.validate(async valid => {
// console.log(valid)
if (!valid) return
// 发起修改用户信息的数据请求
const { data: res } = await this.$http.put('users/' + this.editForm.id, {
email: this.editForm.email,
mobile: this.editForm.mobile
})
if (res.meta.status !== 200) {
return this.$message.error('更新用户信息失败!')
}
// 关闭对话框
this.editDialogVisible = false
// 刷新数据列表
this.getUserList()
// 提示修改成功
this.$message.success('更新用户信息成功!')
})
}
-
请求路径:users/:id
-
请求方法:put
-
请求参数(editForm修改的数据)
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 id | 不能为空 参数是url参数:id
|
邮箱 | 可以为空 | |
mobile | 手机号 | 可以为空 |
-
响应参数
参数名 | 参数说明 | 备注 |
---|---|---|
id | 用户 ID | |
role_id | 角色 ID | |
mobile | 手机号 | |
邮箱 |
-
响应数据
/* 200表示成功,500表示失败 */
{
"data": {
"id": 503,
"username": "admin3",
"role_id": 0,
"mobile": "111",
"email": "123@123.com"
},
"meta": {
"msg": "更新成功",
"status": 200
}
}
30.实现删除用户的操作
plugins/element.js
import { MessageBox } from 'element-ui'
//在每一个组件中都可以通过this.$confirm来弹出确认弹出的提示框
Vue.prototype.$confirm = MessageBox.confirm
<!-- 删除按钮 -->
<el-button @click="removeUserById(scope.row.id)"></el-button>
// 根据Id删除对应的用户信息
async removeUserById (id) {
console.log(id)
// 弹框询问用户是否需要删除数据
const confirmResult = await this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).catch(err => err)
// (err => err)为(err => {return err})的简写形式
// 如果用户确认删除,则返回值为字符串confirm
// 如果用户取消删除,则返回值为字符串cancel
console.log(confirmResult)
if (confirmResult !== 'confirm') {
return this.$message.info('已取消删除')
}
// 在终端里显示了确认删除
//console.log('确认了删除')
const { data: res } = await this.$http.delete('users/' + id)
if (res.meta.status !== 200) {
return this.$message.error('删除用户失败!')
}
this.$message.success('删除用户成功!')
// 删除成功之后,需要刷新用户列表,直接调用getUserList()
this.getUserList()
}
Element
31.提交用户列表功能
提交代码到git仓库。文章来源地址https://www.toymoban.com/news/detail-447973.html
- 检查当前所处的分支 git branch
- 创建新分支并切换checkout到新分支上 git checkout -b user
- 再所有修改操作添加到暂存区 git status检查当前user分支文件的状态 git add .
- 检查状态git status 所有文件都被添加到了暂存区
- 将user提交到仓库中 git commit -m "完成用户列表功能的开发"
- 检查状态 git status
- 本地user的代码就是最新的了
- 码云中还没有记录user分支,检查当前所处的分支 git branch
- 把本地分支推送到云端(第一次推送新分支user)git push -u origin user (把本地的user分支推送到云端的origin仓库中,同时以user分支来进行保存)
- 此时master主分支还是旧的
- 检查当前所处分支 git branch
- 切换到master主分支 git checkout master
- 检查是否处于master主分支 git branch
- 从主分支上把user代码合并过来 git merge user
- 把本地的master分支代码推送到云端 git push (有master分支,不是第一次了)
到了这里,关于Vue+JS+Element UI实战(电商项目1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!