欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > windows >内容正文

windows

尚品汇后台管理系统

发布时间:2025/4/16 windows 26 豆豆
生活随笔 收集整理的这篇文章主要介绍了 尚品汇后台管理系统 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

尚品汇后台管理系统

  • 1、登录(退出登录)
  • 2、路由设置(***)
    • 路由表component属性
  • 3、品牌列表模块
    • 3.1 el-pagination layout属性
    • 3.2 封装四个模块api
    • 3.3 this滥用和参数解构
    • 3.4 品牌列表展示(插槽)
    • 3.5 品牌信息新增和修改
    • 3.6 表单验证
    • 3.7 删除品牌信息
  • 4、商品属性
    • 4.1 三级联动
    • 4.2 商品属性展示

1、登录(退出登录)

后台接口swagger在线文档:
后台接口1
后台接口2

1、将所有的api接口url更换为和swagger在线文档相同的url。
2、跨域解决
devServer部分(proxy代理解决跨域)

devServer: {port: port,open: true,overlay: {warnings: false,errors: true},proxy: {// 会把请求路径中的/api换为后面的代理服务器'/dev-api': {// 提供数据的服务器地址target: 'http://39.98.123.211',pathRewrite: { '^/dev-api': '' }}}},

记得重启项目
3、切记将请求拦截器的X-Token改为token,否则后台会返回jwt空错误。
config.headers['token'] = getToken()
退出登录部分可以不做修改。

2、路由设置(***)

路由部分代码

export const constantRoutes = [{path: '/login',component: () => import('@/views/login/index'),hidden: true},{path: '/404',component: () => import('@/views/404'),hidden: true},{path: '/',component: Layout,redirect: '/dashboard',children: [{path: 'dashboard',name: 'Dashboard',component: () => import('@/views/dashboard/index'),meta: { title: '首页', icon: 'dashboard' }}]},{path: '/product',name: 'Product',component: Layout,meta: { title: '商品管理', icon: 'el-icon-goods' },children: [{path: 'trademark',name: 'TradeMark',component: () => import('@/views/tradeMark'),meta: { title: '品牌管理' }}, {path: 'attr',name: 'Attr',component: () => import('@/views/Attr'),meta: { title: '平台属性管理' }}, {path: 'sku',name: 'Sku',component: () => import('@/views/Sku'),meta: { title: 'Sku管理' }}, {path: 'spu',name: 'Spu',component: () => import('@/views/Spu'),meta: { title: 'Spu管理' }}]},// 404 page must be placed at the end !!!{ path: '*', redirect: '/404', hidden: true } ]

路由表component属性

component用法一

path: 'trademark', name: 'TradeMark', component: () => import('@/views/tradeMark'),

当访问path为trademark时,会显示tradeMark这个组件。上面只是component最简单的应用。
component用法二

path: '/product',name: 'Product',component: Layout,meta: { title: '商品管理', icon: 'el-icon-goods' },children: [{path: 'trademark',name: 'TradeMark',component: () => import('@/views/tradeMark'),meta: { title: '品牌管理' }}]

如果一个路由只是一个菜单项,并不对应相应的组件,那么此时的component为本菜单项所在的路由组件。

例如:上面代码中product只是一个菜单项,并不对应相应组件。所以他的component应该为他所在的组件,即component: Layout。trademark为子菜单项,有具体对应的组件,所以component: () => import('@/views/tradeMark'),trademark的component原理就是用法一。

前端菜单栏显示的实现具体如下:

遍历路由信息数组,将路由项渲染为菜单项。菜单项的信息在路由信息中获取。
(1)如果路由项只有一个子路由,则将该子路由信息作为作为菜单项信息。
(2)如果路由项有多个子路由,将父路由信息作为一级菜单项信息。然后,遍历所有的子路由,生成相应的二级菜单项。

这个前端菜单项显示代码值得研究,写的非常好。

3、品牌列表模块

3.1 el-pagination layout属性

layout是指分页器各组件的排列方式,例如:
layout=" prev, pager, next, jumper,->,sizes,total"


->后面的组件会被放在页面的最右边。如下图所示:

3.2 封装四个模块api

四个模块分别为attr、sku、spu、tradeMark。
每个模块的api封装为对应的js文件,如下图所示:

为了方便使用,将四个模块再次封装到一个js文件中,然后统一暴露。

这样如果我们使用时,只需要import这个js文件就可以使用了,但是为了更加简介,我们可以将这个js文件在main.js中注册,将其是设置为全局属性。

// 引入api请求接口 import API from '@/api' Vue.prototype.$API = API

之后在组件中使用四个模块的api函数时,可直接通过this.$API.函数名调用。

3.3 this滥用和参数解构

data中的数据十分常用,当我们使用时可能会频繁的通过this.使用data中的数据,这样容易发生滥用this去读取data中数据,程序性能会下降。具体原因链接描述
解决方法:ES6允许我们通过参数解构来避免this的滥用。

例如,getPageList函数需要使用page, limit两个属性。直接const { page, limit } = this解构出这两个属性。

export default {name: 'TradeMark',data() {return {page: 1,limit: 3}},mounted() {this.getPageList()},methods: {getPageList() {const { page, limit } = thisthis.$API.trademark.getTradeMarkInfo(page, limit)}} }

3.4 品牌列表展示(插槽)

1、获取数据函数
设置了pager = 1参数,调用时,如果传值就会将值赋给pager ,如果不传pager = 1。即默认获取的是第一页数据。

async getPageList(pager = 1) {this.page = pagerconst { page, limit } = thisconst result = await this.$API.trademark.getTradeMarkInfo(page, limit)if (result.code === 200) {this.total = result.data.totalthis.list = result.data.records}}

2、需要注意的是插槽的使用。我们需要通过插槽获取父组件数据。

el-table插槽使用方法:

品牌logo列使用了插槽。所以通过一下代码探究插槽的使用

<el-table-column prop="logoUrl" label="品牌LOGO" align="center"><template slot-scope="{row, column, $index}"><p>{{row}}</p><p>{{column}}</p><p>{{$index}}</p></template> </el-table-column>

下面三个箭头分别对应slot-scope="{row, column, $index}中的row, column, $ index。
row表示表格当前一行的全部信息;
column表示当前列的一些属性;
$index表示当前行数据在整个数据数组中的下标。

这里我们只需要用到当前行所包含的品牌logo图片链接,所以只需要使用row,完整代码如下:

<el-table :data="list" style="width: 100%"><el-table-column type="index" label="序号" width="80px" align="center"></el-table-column><el-table-column prop="tmName" label="品牌名称" align="center"></el-table-column><el-table-column prop="logoUrl" label="品牌LOGO" align="center"><template slot-scope="{row}"><img :src="row.logoUrl" style="width: 80px;height: 80px"/></template></el-table-column><el-table-column prop="prop" label="操作" align="center"><template slot-scope="{row}"><el-button type="primary">修改</el-button><el-button type="danger">删除</el-button></template></el-table-column></el-table>

3、分页器修改页面大小和修改当前页码都比较简单,直接贴代码。

// 修改当前页码handleCurrentChange(current) {this.getPageList(current)},// 修改页面大小handleSizeChange(size) {this.limit = sizethis.getPageList()},

注意:handleSizeChange中的getPageList需要带参数,因为getPageList定义了默认参数pager=1,如果不传入current,则getPageList的默认参数pager=1就会生效,就会一直请求第一页数据。

3.5 品牌信息新增和修改

1、头像上传组件
新增中比较重要的时头像上传组件,代码如下

<el-uploadclass="avatar-uploader"action="dev-api/admin/product/fileUpload":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="tmFrom.logoUrl" :src="tmFrom.logoUrl" class="avatar"><i v-else class="el-icon-plus avatar-uploader-icon"></i><div slot="tip" class="el-upload__tip">只能上传jpg文件,且不超过2MB</div> </el-upload>

图片数据不能用v-model绑定,
action 必选参数,上传的地址。这里的 action取值是上传图片的接口,是后台提供好的接口。
before-upload表示上传成功前的函数

beforeAvatarUpload(file) {const isJPG = file.type === 'image/jpeg'const isLt2M = file.size / 1024 / 1024 < 2if (!isJPG) {this.$message.error('上传头像图片只能是 JPG 格式!')}if (!isLt2M) {this.$message.error('上传头像图片大小不能超过 2MB!')}return isJPG && isLt2M}

on-success表示上传成功后的函数

handleAvatarSuccess(res, file) {// res是上传成功后返回给前端的数据// file是上传成功后服务器返回给前端的数据this.tmFrom.logoUrl = URL.createObjectURL(file.raw)}

上面两个函数饿了吗UI官网都以给出,理解即可。
2、新增和修改函数
新增和修改按钮使用的是同一个弹窗。
(1)点击添加按钮显示弹窗
记得清空上次操作的数据

addTradeMark() {this.dialogFormVisible = true// 清空上次操作的数据this.tmFrom = { tmName: '', logoUrl: '' }}

(2)点击修改按钮显示弹窗(浅拷贝问题
this.$tmFrom = row会使得二者同时指向数据的引用,当修改tmFrom表单项时,表格中数据也会改变,如果修改后点了取消按钮,表格中数据会发生改变。所以,要解决浅拷贝

updateTradeMark(row) {this.dialogFormVisible = true// ...解决单层浅拷贝问题this.tmFrom = { ...row }}

当赋值的对象row中还有对象元素时,又会出现上面的问题,所以可以通过深拷贝JSON.parse(JSON.stringfy())实现。
(3)击弹窗的确定按钮实现数据的修改或新增
新增和修改成功后,需要再次获取品牌信息。需要注意,如果时新增则刷新后显示第一页,如果是修改,则要在当前页刷新显示。

async addOrUpdate() {this.dialogFormVisible = falselet result = await this.$API.trademark.addOrUpdateTradeMark(this.tmFrom)if (result.code === 200) {this.$message.success(this.tmFrom.id ? '修改品牌成功' : '添加品牌成功')}// 现需要再次获取品牌信息,修改数据要在当前页刷新this.getPageList(this.tmFrom.id ? this.page : 1)},

新增或修改品牌API函数

// 新增或修改品牌 export const addOrUpdateTradeMark = (tradeMark) => {// 有id则为修改if (tradeMark.id) {return request({ url: 'admin/product/baseTrademark/update', method: 'put', data: tradeMark })}// 无id则为新增return request({ url: 'admin/product/baseTrademark/save', method: 'post', data: tradeMark }) }

3.6 表单验证

表单验证,主要分以下几步:
(1)定义rules
(2)表单绑定rules,表单项prop绑定验证属性
(3)提交表单时触发的函数内,先进行表单验证,如果成功执行后续操作,否则弹出失败。

3.7 删除品牌信息

(1)气泡确认框
@onConfirm="deleteTradeMark(row)"绑定的是删除函数

<template ><el-popconfirmtitle="这是一段内容确定删除吗?"@onConfirm="deleteTradeMark(row)"><el-button slot="reference" type="danger" size="small">删除</el-button></el-popconfirm></template>

(2)删除函数
删除成功后要刷新页面。

async deleteTradeMark(row) {const result = await this.$API.trademark.deleteTradeMark(row.id)if (result.code === 200) {this.$message.success('删除成功')// 成功后,重新获取数据await this.getPageList(this.list.length > 1 ? this.page : 1)} else {this.$message.error('删除失败')}}

示例:

4、商品属性

4.1 三级联动

(1)三级联动静态组件
示例

由于多个页面都使用到了上面的el-card,所以将其封装为全局组件。
main.js

import CategorySelect from './components/CategorySelect' Vue.component(CategorySelect.name, CategorySelect)

注意:虽然该全局组件的名字是CategorySelect ,但是在使用时最好用后面的形式<category-select></category-select>。
原因:html不区分大小写,会将大写字母转换为小写,并在前面加-。即CategorySelect 转换为category-select
(2)三级联动数据展示
示例:

html静态代码

<el-card style="margin: 20px 0"><el-form :inline="true" class="demo-form-inline"><el-form-item label="一级分类"><el-select v-model="formList.category1" placeholder="请选择" value="" @change="getCategory2List"><el-option v-for="(c1,index) in category1List" :key="c1.id" :label="c1.name" :value="c1.id"></el-option></el-select></el-form-item><el-form-item label="二级分类" ><el-select v-model="formList.category2" placeholder="请选择" value="" @change="getCategory3List"><el-option v-for="(c2,index) in category2List" :key="c2.id" :label="c2.name" :value="c2.id"></el-option></el-select></el-form-item><el-form-item label="三级分类" ><el-select v-model="formList.category3" placeholder="请选择" value=""><el-option v-for="(c3,index) in category3List" :key="c3.id" :label="c3.name" :value="c3.id"></el-option></el-select></el-form-item><el-form-item><el-button type="primary" @click="onSubmit">查询</el-button></el-form-item></el-form></el-card>

data属性

data() {return {category1List: [],category2List: [],category3List: [],formList: {category1: '',category2: '',category3: ''}}

注意:formList内容是三个选择框选中属性的id。后续也是通过id去查询。

针对于选中一级属性后,自动获取二级属性列表,选中二级属性后,再自动获取三级属性列表问题。
最初思路:通过computed或者watch去实现,但都没有成功。
老师的方法:通过给选择框添加@change属性,再回调函数内去获取下一级属性列表。

@change绑定的获取三级列表函数都比较简单,这里就不过多描述。

// 获取一级分类// 获取一级分类async getCategory1List() {const result = await this.$API.attr.reqCategory1List()if (result.code === 200) {this.category1List = result.data} else {alert(result.message)}},// 通过选中一级属性id获取二级属性列表async getCategory2List() {// 当一级分类改变时,上一次选择的二级和三级分类应设置为空this.category2List = []this.category3List = []this.formList.category2 = ''this.formList.category3 = ''const result = await this.$API.attr.reqCategory2List(this.formList.category1)if (result.code === 200) {this.category2List = result.data} else {alert(result.message)}},// 通过选中二级属性id获取三级属性列表async getCategory3List() {// 当二级分类改变时,上一次选择的三级分类应设置为空this.category3List = []this.formList.category3 = ''const result = await this.$API.attr.reqCategory3List(this.formList.category2)if (result.code === 200) {this.category3List = result.data} else {alert(result.message)}},

(3)将选中的三级分类id传递给父组件
这里是通过点击查询按钮实现的父子组件通信
查询按钮绑定的回调

// 子组件将三级分类id传递给父组件,父组件使用该id去查询并展示数据async onSubmit() {this.$emit('getCategoryId', this.formList)}

父组件

<category-select @getCategoryId="getCategoryId"></category-select>

父组件data

data() {return {category1Id: '',category2Id: '',category3Id: ''}},

父子组件通信,父组件的接收函数:getCategoryId函数
只有当三级id不为空时,才发请求。

// 获取子组件传递三级分类idgetCategoryId(list) {this.category1Id = list.category1Idthis.category2Id = list.category2Idthis.category3Id = list.category3Idif (this.category3Id) {console.log('发请求')}}

4.2 商品属性展示

通过三级联动获取到要展示的属性id后,接下来就是通过该id请求数据,然后展示。

总结

以上是生活随笔为你收集整理的尚品汇后台管理系统的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。