# vue_oa
**Repository Path**: jiely007/vue_oa
## Basic Information
- **Project Name**: vue_oa
- **Description**: No description available
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 5
- **Forks**: 3
- **Created**: 2019-05-28
- **Last Updated**: 2023-03-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# vue_oa
## 项目初始化
1. 安装element-ui并导入到main.js中
```js
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI)
```
2. 安装`node-sass sass-loader`并导入默认样式文件
```js
// 1. 安装解析scss文件的加载器
npm i node-sass sass-loader --save-dev
"node-sass": "^4.9.0",
"css-loader": "^0.28.0",
"sass-loader": "^7.0.1",
// 2. 将reset.scss/index.scss复制到项目文件中,并新建element.scss
// 3. 在main.js中导入全局样式文件
import '@/styles/index.scss'
```
3. 删除vue-cli默认的组件`HelloWord.vue`以及`router`文件夹`index.js`中的组件导入和路由规则
## 登录页面路由跳转
1. `src`目录下创建`views`文件夹,并创建`login.vue`组件
2. 在`router`文件夹下的`index.js`中配置路由规则
```js
// 导入登录组件
import login from '../views/login.vue'
// 在routes数组中配置路由对象
export default new Router({
routes: [
{
path:'/login',
name:'Login',
component:login
}
]
})
```
3. 在页面中输入`http://localhost:1234/#/login`显示登录组件内容
## 使用element-ui布局登录页面
1. 使用element-ui表单组件布局结构
```html
```
2. 书写样式
```css
.login {
position: fixed;
width: 100%;
height: 100%;
background-color: #2f4050;
.container {
position: absolute;
left: 0;
right: 0;
width: 400px;
padding: 0px 40px 15px 40px;
margin: 200px auto;
background: white;
.avatar {
position: relative;
left: 50%;
width: 120px;
height: 120px;
margin-left: -60px;
margin-top: -60px;
box-sizing: border-box;
border-radius: 50%;
border: 10px solid #fff;
box-shadow: 0 1px 5px #ccc;
overflow: hidden;
}
.login-btn {
width: 100%;
}
}
}
```
3. 定义数据及表单验证规则
```js
export default {
data () {
return {
form: {
username: '',
password: ''
},
rules: {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' }
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' }
]
}
}
}
}
```
## 使用axios发送登录请求
1. 安装axios
```js
npm i axios -S
```
2. 在src目录下新建`api/index.js`文件,封装登录请求
```js
// 导入axios
import axios from 'axios'
// 设置请求的根路径
//const baseURL = 'http://www.lovegf.cn:8888/api/private/v1/'
const baseURL = 'http://ludir.cn:8888/api/private/v1/'
axios.defaults.baseURL = baseURL
// 登录验证
export const checkUser = params => {
return axios.post('login', params).then(res => res.data)
}
```
3. 在`login.vue`中的登录按钮上绑定点击事件,发送登录请求
```js
// 导入封装的登录请求接口
import {checkUser} from '../api/index.js'
// 定义登录方法
methods: {
loginSubmit (formName) {
// 校验表单
this.$refs[formName].validate(valide => {
if (valide) {
// 发送登录请求
checkUser(this.form).then(res => {
if (res.meta.status === 200) {
// 如果成功要跳转至首页
this.$router.push({name: 'Home'})
} else {
// 如果失败,展示提示信息
this.$message({
type: 'error',
message: res.meta.msg
})
}
})
} else {
console.log('校验不通过')
}
})
}
}
```
4. 在views文件夹中新建`Home.vue`文件,并配置好路由规则
```js
import home from '../views/Home.vue'
routes: [
{
path:'/login',
name:'Login',
component:login
},
{
path:'/home',
name:'Home',
component:home
}
]
```
## 存储登录状态并设置axios拦截器
> 除登录请求外,其他所有请求发送都必须保证请求头中有登录成功返回的token值,所以需要使用拦截器给请求添加`Authorization`
1. 登录成功时将后台返回的token存储起来
```js
// 存储后台返回的登录成功凭证token
localStorage.setItem('mytoken', res.data.token)
```
2. 使用axios拦截器将token添加到请求头中
```js
// 请求拦截器,给所有的请求加上token
axios.interceptors.request.use(function (config) {
// 取出localStorage中存储的token值
let token = localStorage.getItem('mytoken')
// 设置到请求头中 Authorization这个名字是后台规定的
config.headers['Authorization'] = token
return config
}, function (error) {
return Promise.reject(error)
})
```
3. 封装获取用户列表请求
```js
// 获取用户列表
export const getUserList = params => {
return axios.get('users', params).then(res => res.data)
}
```
4. 在`Home.vue`的生命周期函数`created`中发送获取数据列表请求
```js
created(){
let params = {params: {query: '', pagenum: 1, pagesize: 1}}
getUserList(params).then(res => {
console.log(res)
})
}
```
## 使用vue-router路由全局守卫进行路由拦截
> 对于需要登录的页面访问前需要判断是否已经登录,使用路由导航钩子进行拦截
1. 在`router/index.js`中使用路由全局守卫拦截所有的路由跳转
```js
// 注册一个全局守卫,作用是在路由跳转前,对路由进行判断,防止未登录的用户跳转到其他需要登录的页面去
router.beforeEach((to, from, next) => {
let token = localStorage.getItem('mytoken')
// 如果已经登录,放行
if (token) {
next()
} else {
// 如果没有登录,访问非登录页面,则跳转到登录页面
if (to.path !== '/login') {
next({path: '/login'})
} else {
// 如果没有登录,但访问的是登录页面,直接进入
next()
}
}
})
```
## 首页整体布局
1. 使用element-ui布局容器进行首页整体布局
```html
Aside
Header
Main
```
2. 调整样式
```scss
.home {
height: 100%;
.el-menu-admin:not(.el-menu--collapse) {
width: 200px;
min-height: 400px;
}
.el-container {
height: 100%;
}
.el-aside {
background-color: #545c64;
}
.el-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #545c64;
}
.logo {
height:60px;
background: url(../assets/logo.png);
background-size: cover;
background-color: #989898;
}
.toggle-btn {
font-size: 36px;
color: #989898;
cursor: pointer;
line-height: 60px;
}
.system-title {
font-size: 28px;
color: white;
}
.logout-btn {
color: orange;
}
}
```
## 完成侧边栏布局
1. 使用element-ui的导航菜单进行结构布局
```html
```
2. 定义导航菜单的点击事件
```js
methods:{
handleOpen (key, keyPath) {
console.log(key, keyPath)
},
handleClose (key, keyPath) {
console.log(key, keyPath)
}
}
```
## 完成头部内容以及中间部分路由跳转
1. 使用element-ui完成头部导航条
```html
电商后台管理系统
您好,xxx
退出
```
2. data中定义`isCollapse`属性控制左侧导航的切换
```js
// 1. el-menu上绑定collapse属性
// 2. 定义isCollapse:false
data() {
return {
isCollapse:false
}
}
/// 3. 切换事件
toggleCollapse(){
this.isCollapse = !this.isCollapse
}
```
3. 退出登录按钮绑定事件
```js
logout () {
// 1. 清除登录状态,即删除保存在localStorage中的token
localStorage.removeItem('mytoken')
// 2. 跳转到登录页面
this.$router.push({name: 'Login'})
}
```
4. 定义路由规则显示中间区域
> 由于每次点击左侧导航都是中间区域变化,而整体页面的左侧和头部不变,所以中间区域应该设置成子路由
```js
// 1. 创建welcome组件并导入
import welcome from '../views/welcome/Welcome.vue'
// 2. 配置子路由规则用于显示welcome组件
{
path: '/',
name: 'Home',
component: home,
redirect: {
path: 'welcome'
},
children: [{
name: 'Welcome',
path: 'welcome',
component: welcome
}]
}
// 3. 子路由的组件需要显示到父路由对应的组件中,所以Home.vue中需要放一个router-view
```
## 集成Vuex保存用户名
1. 新建`store/index.js`文件,定义store实例
```js
import Vue from 'vue'
// 1. 导入并绑定Vuex
import Vuex from 'vuex'
Vue.use(Vuex)
// 2. 定义数据存储仓库state
const state = {
username: ''
}
// 3. 定义用于修改数据的方法
const mutations = {
setUsername: (state, username) => {
state.username = username
localStorage.setItem('username', username)
}
}
// 4. 异步修改数据
const actions = {}
// 5. 计算属性
const getters = {
username: (state) => localStorage.getItem('username')
}
// 6. 导出store实例
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
```
2. `main.js`中导入并集成store
```js
// 导入
import store from './store/index.js'
// 挂载到vue实例
new Vue({
el: '#app',
router,
store,
components: { App },
template: ''
})
```
3. 登录成功后调用修改数据的方法保存数据
```js
// 2. 使用vuex存储用户名
this.$store.commit('setUsername', res.data.username)
```
4. 使用`$store.getters.username`显示数据
```html
您好,{{$store.getters.username}}
```
## 用户列表界面路由跳转及布局
1. 启用element-ui路由跳转功能,`Home.vue`组件中的`el-menu`标签上添加`:router = "true"`
2. `el-menu-item`标签的index属性设置需要跳转的路由路径
```html
用户列表
```
3. 创建`User.vue`组件,并配置好路由规则
```js
// 导入组件
import user from '../views/user/User.vue'
// 创建路由规则对象
{
name: 'User',
path: 'user',
component: user
}
```
4. 使用element-ui组件进行页面布局
```html
```
5. 跳转样式
```css
/*element.scss中书写面包屑组件样式*/
.el-breadcrumb {
background-color: #D3DCE6;
height: 45px;
font-size: 15px;
padding-left: 10px;
line-height: 45px;
margin-bottom: 15px;
}
/*组件内部style标签中书写以下样式*/
.user {
.margin-20 {
margin: 20px 0;
}
.search-input {
width: 300px;
}
.page {
padding: 5px 0;
background-color: #D3DCE6;
}
}
```
## 用户列表数据渲染
1. 发送数据请求
```js
// 1. data中定义存储数据的数组userList
// 2. 在methods中定义数据请求方法
initList () {
getUserList({params: {query: '', pagenum: 1, pagesize: 3}}).then(res => {
console.log(res)
this.userList = res.data.users
})
}
// 3. 在生命周期函数created中发送请求
created(){
this.initList()
}
```
2. 渲染数据
```css
```
## 完成搜索功能
1. data中定义query属性保存搜索条件,并将搜索条件加入到数据请求的参数中
```js
// 由于搜索接口和获取用户列表是同一个接口,所以只需要加入搜索条件即可
initList () {
getUserList({params: {query: this.query, pagenum: 1, pagesize: 3}}).then(res => {
console.log(res)
this.userList = res.data.users
})
}
```
2. 给搜索按钮绑定点击事件
```html
```
3. 给搜索框绑定keydown事件
```html
```
## 完成分页功能
1. 在data中定义`total`,`pagesize`,`pagenum`三个属性分别存储数据总条数、每页显示多少条、页码
2. 数据请求方法中给`total`赋值
```js
// 初始化表格数据
initList () {
getUserList({params: {query: this.query, pagenum: this.pagenum, pagesize: this.pagesize}}).then(res => {
console.log(res)
this.userList = res.data.users
this.total = res.data.total
})
}
```
3. 切换页码和切换条数事件中重新发送请求
```js
handleSizeChange (val) {
console.log(`每页 ${val} 条`)
this.pagesize = val
this.initList()
},
handleCurrentChange (val) {
console.log(`当前页: ${val}`)
this.pagenum = val
this.initList()
}
```
## 完成修改用户状态功能
1. 使用v-model给switch开关绑定状态值,并且添加切换状态的方法
```html
```
2. 定义更新用户状态的网络请求
```js
// 更改用户状态
export const changeUserState = params => {
return axios.put(`users/${params.uid}/state/${params.type}`).then(res => res.data)
}
```
3. 定义切换状态的方法发送网络请求更新用户状态
```js
// 改变用户状态
changeUserState (row) {
console.log(row)
changeUserState({uid: row.id, type: row.mg_state}).then(res => {
if (res.meta.status === 200) {
this.$message({
type: 'success',
message: '修改用户状态成功'
})
} else {
this.$message({
type: 'warning',
message: res.meta.msg
})
}
})
}
```
## 完成添加用户功能
1. 使用`el-dialog`组件实现弹窗
```html
添加用户
```
2. data中定义表单用到的数据和表单验证规则
```js
addDialogFormVisible: false,
addForm: {
username: '',
password: '',
email: '',
mobile: ''
},
// 添加用户的表单验证
rules: {
username: [{
required: true, message: '请输入用户名', trigger: 'blur'
}],
password: [{
required: true, message: '请输入密码', trigger: 'blur'
}],
email: [{
required: true, message: '请输入邮箱地址', trigger: 'blur' },{
type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur,change'
}],
mobile: [{
required: true, message: '电话不能为空'
}]
}
```
3. 定义添加用户的网络请求
```js
// 添加用户
export const addUser = params => {
return axios.post('users', params).then(res => res.data)
}
```
4. 点击确定按钮发送网络请求
```js
// 添加用户
addUserSubmit (formName) {
this.$refs[formName].validate(valide => {
if (valide) {
// 执行添加用户方法
addUser(this.addForm).then(res => {
console.log(res)
if (res.meta.status === 201) {
this.$message({
type: 'success',
message: '创建用户成功!'
})
}
this.addDialogFormVisible = false
this.initList()
})
}
})
}
```
## 完成编辑用户功能
1. 使用`el-dialog`组件实现弹窗
```html
```
2. 定义编辑表单中的数据
```js
editDialogFormVisible: false,
editForm: {
username: '',
email: '',
mobile: '',
id: 0
}
```
3. 定义获取用户信息的网络请求和编辑用户信息的网络请求
```js
// 根据id获取用户信息
export const getUserById = params => {
return axios.get(`users/${params}`).then(res => res.data)
}
// 编辑用户信息
export const editUser = params => {
return axios.put(`users/${params.id}`, params).then(res => res.data)
}
```
4. 点击编辑按钮发送获取用户信息的网络请求
```js
// 显示编辑用户对话框
showEditDialog (row) {
this.editDialogFormVisible = true
// 获取用户信息
getUserById(row.id).then(res => {
if (res.meta.status === 200) {
this.editForm.username = res.data.username
this.editForm.email = res.data.email
this.editForm.mobile = res.data.mobile
this.editForm.id = res.data.id
}
})
},
```
5. 点击确定按钮发送编辑用户信息的网络请求
```js
// 编辑用户提交
editUserSubmit (formName) {
this.$refs[formName].validate(valide => {
if (valide) {
editUser(this.editForm).then(res => {
if (res.meta.status === 200) {
this.$message({
type: 'success',
message: '编辑成功'
})
this.editDialogFormVisible = false
this.initList()
}
})
}
})
}
```
## 完成删除用户功能
1. 添加删除按钮事件
```html
```
2. 定义删除用户的网络请求
```js
// 删除用户信息
export const deleteUser = params => {
return axios.delete(`users/${params}`).then(res => res.data)
}
```
3. 发送删除用户网络请求
```js
// 显示删除对话框
showDeleteDialog (row) {
this.$confirm('此操作将永久删除该用户, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// 执行删除用户操作
deleteUser(row.id).then(res => {
if (res.meta.status === 200) {
this.$message({
type: 'success',
message: '删除成功!'
})
this.initList()
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
})
})
}
```
## 完成分配用户角色功能
1. 分配角色按钮添加事件,并使用弹窗组件
```html
{{grantForm.username}}
```
2. 定义分配角色表单需要用到的数据
```js
// 控制分配用户角色对话框显示隐藏
grantDialogFormVisible: false,
// 存储分配角色时获取的用户信息
grantForm: {},
// 角色列表
roleList: [],
// 角色ID
roleId: ''
```
3. 定义获取角色列表和分配角色的网络请求
```js
// 获取角色列表
export const getRoleList = params => {
return axios.get('roles').then(res => res.data)
}
// 分配角色
export const grantUserRole = params => {
return axios.put(`users/${params.id}/role`, {id: params.id, rid: params.rid}).then(res => res.data)
}
```
4. 点击分配角色按钮发送获取角色列表的请求,并使用v-for渲染数据
```js
// 显示分配角色对话框
showGrantDialog (row) {
this.grantForm = row
this.grantDialogFormVisible = true
getRoleList().then(res => {
console.log(res)
if (res.meta.status === 200) {
this.roleList = res.data
}
})
}
```
5. 点击确定按钮发送分配角色网络请求
```js
// 分配角色
grantUserSubmit () {
// 当没有选择角色时,不发送网络请求
if (!this.roleId) {
this.$message({
type: 'warning',
message: '角色不能为空,请选择!'
})
} else {
grantUserRole({id: this.grantForm.id, rid: this.roleId}).then(res => {
if (res.meta.status === 200) {
this.$message({
type: 'success',
message: '设置角色成功'
})
this.grantDialogFormVisible = false
} else {
this.$message({
type: 'error',
message: res.meta.msg
})
}
})
}
}
```
## 权限管理路由跳转
1. 书写结构代码,更改index为路由路径
```html
权限管理
角色列表
权限列表
```
2. 新建`Roles.vue`和`Rights.vue`组件,并配置路由规则
```js
import rights from '../views/right/Rights.vue'
import roles from '../views/right/Roles.vue'
{
name: 'Rights',
path: 'rights',
component: rights
}, {
name: 'Roles',
path: 'roles',
component: roles
}
```
## 权限列表数据展示
1. 结构代码
```html
首页
权限管理
权限列表
{{scope.row.level | fmtLevel}}
```
2. 定义网络请求
```js
// 获取权限列表
export const getRightList = params => {
return axios.get(`rights/${params.type}`).then(res => res.data)
}
```
3. `created`钩子函数中发送网络请求
```js
created () {
this.isLoading = true
getRightList({type: 'list'}).then(res => {
if (res.meta.status === 200) {
this.rightList = res.data
this.isLoading = false
}
})
}
```
4. 定义过滤器过滤层级显示
```js
filters: {
fmtLevel (level) {
if (level === '0') {
return '一级'
} else if (level === '1') {
return '二级'
} else {
return '三级'
}
}
}
```
## 角色列表数据展示
1. 结构代码
```html
```
2. 样式
```scss
.roles {
.el-tag {
margin-right: 5px;
margin-bottom: 5px;
}
.tree-container {
height: 300px;
overflow: auto;
}
}
```
3. 发送网络请求渲染界面
```js
data(){
return {
roleList: []
}
},
created () {
this.initList()
},
methods: {
initList () {
getRoleList().then(res => {
if (res.meta.status === 200) {
console.log(res)
this.roleList = res.data
}
})
}
}
```
## 角色列表展开数据展示
1. 使用栅格布局渲染界面
```html
{{firstChildren.authName}}
{{secondChildren.authName}}
{{thirdChildren.authName}}
该角色没有分配权限,请前往分配!
```
## 角色权限删除功能
1. `el-tag`标签绑定删除事件
```html
{{firstChildren.authName}}
{{secondChildren.authName}}
```
2. 定义删除权限数据请求
```js
// 删除角色指定权限
export const deleteRoleRight = params => {
return axios.delete(`roles/${params.roleId}/rights/${params.rightId}`).then(res => res.data)
}
```
3. 点击删除按钮触发删除请求
```js
deleteRight (row, rightId) {
deleteRoleRight({roleId: row.id, rightId: rightId}).then(res => {
if (res.meta.status === 200) {
row.children = res.data
} else {
this.$message({
type: 'error',
message: res.meta.msg
})
}
})
}
}
```
## 授权角色树数据展示
1. 书写弹窗组件结构代码
```html
```
2. 发送数据请求渲染界面
```js
// 1. 定义组件需要用到的数据
dialogFormVisible: false, // 控制弹窗显示隐藏
rightList: [], // 存放权限列表
defaultProps: {
children: 'children', // // 树形组件展示的数据源
label: 'authName' // 树形组件显示的标题字段
}
// 2. 发送数据请求
showDialog (row) {
this.dialogFormVisible = true
this.currentRole = row
getRightList({type: 'tree'}).then(res => {
if (res.meta.status === 200) {
console.log(res.data)
this.rightList = res.data
} else {
this.$message({
type: 'error',
message: res.meta.msg
})
}
})
}
```
## 完成授权角色默认选中功能
1. 利用`:default-checked-keys="selectedRights"`树形控制树形组件默认选中项
2. 遍历所有权限,找到已授权的ID存放到`selectedRights`中
```js
// 遍历之前先让数组清空
this.selectedRights.length = 0
// 取出当前点击角色的所有权限, 然后遍历到它的第三个children,取出它里面的所有的项的id,存进selectedRights中
// 1. 遍历第一个children取出一级权限
this.currentRole.children.forEach(first => {
if (first.children && first.children.length !== 0) {
// 2. 遍历第二个children取出二级权限
first.children.forEach(second => {
if (second.children && second.children.length !== 0) {
// 3. 遍历第三个children取出三级权限
second.children.forEach(third => {
this.selectedRights.push(third.id)
})
}
})
}
})
```
## 提交授权功能
1. 定义数据请求
```js
// 角色授权
export const grantRoleRight = (roleId, rids) => {
return axios.post(`roles/${roleId}/rights`, rids).then(res => res.data)
}
```
2. 点击确定按钮发送提交授权请求
```js
// 提交授权
submitGrant () {
// 获取到所有选中的权限ID
let rids = this.$refs.tree.getCheckedKeys().join(',')
grantRoleRight(this.currentRole.id, {rids: rids}).then(res => {
if (res.meta.status === 200) {
this.$message({
type: 'success',
message: res.meta.msg
})
this.dialogFormVisible = false
this.initList()
}
})
}
```
## 动态获取权限菜单
1. 定义获取权限菜单的数据请求
```js
// 左侧菜单权限
export const getMenus = () => {
return axios.get('menus').then(res => res.data)
}
```
2. 发送获取权限菜单的请求
```js
created() {
getMenus().then(res => {
if (res.meta.status === 200) {
this.menuData = res.data;
}
})
}
```
3. 使用`v-for`循环渲染界面
```html
```
## 商品分类界面布局
1. 创建`category/Category.vue`组件,配置路由规则实现跳转
```js
{
name: 'Category',
path: 'categories',
component: category
}
```
2. 在`componets`文件夹中放入`TreeGrid`组件,并在`Category.vue`组件中进行集成
```js
// 1. 在category.vue中导入组件
import TreeGrid from '@/components/TreeGrid/TreeGrid'
// 2. 注册组件
data() {
return {
addDialogFormVisible: false,
columns: [
{
text: "分类名称",
dataIndex: "cat_name",
width: ""
},
{
text: "是否有效",
dataIndex: "cat_deleted",
width: ""
},
{
text: "排序",
dataIndex: "cat_level",
width: ""
}
],
dataSource: [],
total: 10
}
},
components: {
TreeGrid
}
```
3. 使用`TreeGrid.vue`组件
```html
```
## 商品分类数据获取
1. 定义获取数据的请求
```js
// 获取商品分类信息
export const getCategories = (params) => {
return axios.get('categories', {params: params}).then(res => res.data)
}
```
2. 发送网络请求获取数据
```js
initList() {
getCategories({
type: "3",
pagenum: this.pagenum,
pagesize: this.pagesize
}).then(res => {
console.log(res);
if (res.meta.status === 200) {
this.total = res.data.total;
this.dataSource = res.data.result;
}
});
}
```
## 添加商品分类级联选择器使用
1. 添加分类弹窗布局
```html
```
2. 定义级联选择器需要用到的数据源
```js
addForm: {
cat_name: "",
cat_pid: 0,
cat_level: 0
},
// 级联选择器的数据源
options: [],
// 级联选择器选中后的数据
selectedOptions: [],
// props表示配置级联选择器展示的数据字段
props: {
value: "cat_id",
label: "cat_name"
}
```
3. 点击添加分类按钮发送请求获取分类数据
```js
addCategory() {
this.addDialogFormVisible = true;
getCategories({ type: "2" }).then(res => {
console.log(res);
if (res.meta.status === 200) {
this.options = res.data;
}
});
}
```
## 添加商品分类数据提交
```js
addCateSubmit(formName) {
this.$refs[formName].validate(valide => {
if (valide) {
// 添加一级分类
if (this.selectedOptions.length === 0) {
this.addForm.cat_pid = 0;
this.addForm.cat_level = 0;
} else if (this.selectedOptions.length === 1) {
// 添加二级分类
this.addForm.cat_pid = this.selectedOptions[
this.selectedOptions.length - 1
];
this.addForm.cat_level = 1;
} else {
// 添加三级分类
this.addForm.cat_pid = this.selectedOptions[
this.selectedOptions.length - 1
];
this.addForm.cat_level = 2;
}
addCategories(this.addForm).then(res => {
if (res.meta.status === 201) {
this.addDialogFormVisible = false;
this.initList();
this.$message({
type: "success",
message: res.meta.msg
});
}
});
}
});
}
```
## 添加商品步骤条组件和tabs组件集成
1. 创建商品列表组件和添加商品组件,并配置路由规则
```js
{
name: 'Goods',
path: 'goods',
component: goods
}, {
name: 'AddGoods',
path: 'toadd',
component: addGoods
}
```
2. 商品列表组件代码
```html
首页
商品管理
商品列表
添加商品
```
3. 添加商品组件结构代码
```html
首页
商品管理
商品列表
配置管理
角色管理
图片上传
定时任务补偿
```
4. 点击tabs切换步骤条
```js
data () {
return {
active: 0,
activeName: 'first'
}
},
methods: {
handleClick (tab, event) {
switch (tab.name) {
case 'first':
this.active = 0
break
case 'second':
this.active = 1
break
case 'third':
this.active = 2
break
case 'fourth':
this.active = 3
break
case 'fifth':
this.active = 4
break
default:
this.active = 0
break
}
}
}
```
## 图片上传组件使用
1. 使用`el-upload`组件上传图片
```html
点击上传
```
2. 设置请求头处理成功回调
```js
handleRemove(file, fileList) {
console.log(file, fileList);
},
handlePreview(file) {
console.log(file);
},
// 成功后回调函数
handleSuccess(response, file, fileList) {
if (response.meta.status === 200) {
this.$message({
type: "success",
message: response.meta.msg
});
}
},
// 设置请求头
setHeader() {
let token = localStorage.getItem("mytoken");
return { Authorization: token };
}
```
## axios上传图片
```html
```
#### https://www.iplaysoft.com/free-image-hosting.html 免费图片网站
```js
update(e) {
let file = e.target.files[0];// 获取文件数据
let param = new FormData(); // 创建form对象
param.append("file", file); // 通过append向form对象添加数据
console.log(param.get("file")); // FormData私有类对象,访问不到,可以通过get判断值是否传进去
let config = {
headers: {
"Content-Type": "multipart/form-data",
}
};
axios
.post("http://www.lovegf.cn:8888/api/private/v1/upload", param, config)
.then(response => {
console.log(response.data);
});
}
```