Vue2 基础八电商后台管理项目——中
代码下载
商品分类页
新商品分类组件 goods/Cate.vue,在router.js中导入子级路由组件 Cate.vue,并设置路由规则。
绘制商品分类基本结构
在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮:
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>商品分类</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 添加 --><el-button type="primary" @click="showAddCateDialog">添加分类</el-button><!-- 分类列表 --><tree-table class="tree-table" :data="catelist" :columns="columns" :selection-type = "false" :expand-type="false" :show-index="true" :index-text="'#'" border :show-row-hover="false"><template slot="isOk" slot-scope="scope"><i class="el-icon-error" style="color: red;" v-if="scope.row.cat_deleted"></i><i class="el-icon-success" style="color: lightgreen;" v-else></i></template><template slot="order" slot-scope="scope"><el-tag v-if="scope.row.cat_level === 0">一级</el-tag><el-tag type="success" v-else-if="scope.row.cat_level === 1">二级</el-tag><el-tag type="warning" v-else>三级</el-tag></template><template slot="opt" slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeCateById(scope.row.cat_id)">删除</el-button></template></tree-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]":page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total"></el-pagination></el-card><!-- 添加分类对话框 --><el-dialog title="添加商品分类" :visible.sync="addCateDialogVisible" width="50%" @close="addCateDialogClosed"><el-form :model="addCateForm" :rules="addCateFormRules" ref="addCateFormRef" label-width="100px"><el-form-item label="分类名称:" prop="cat_name"><el-input v-model="addCateForm.cat_name"></el-input></el-form-item><el-form-item label="父级分类:"><el-cascader v-model="selectedKeys" :options="parentCateList" :props="cascaderProps" @change="parentCateChange" clearable></el-cascader></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addCateDialogVisible = false">取 消</el-button><el-button type="primary" @click="addCate">确 定</el-button></span></el-dialog></div>
</template>
主要功能实现
<script>
export default {data() {return {catelist: [], queryInfo: {type: 3,pagenum: 1,pagesize: 5},total: 0,columns: [{label: '分类名称',prop: 'cat_name'},{label: '是否有效',// 列类型,可选值有 'template'(自定义列模板)type: 'template',// 列类型为 'template'(自定义列模板) 时,对应的作用域插槽(它可以获取到 row, rowIndex, column, columnIndex)名称template: 'isOk'},{label: '排序',type: 'template',template: 'order'},{label: '操作',type: 'template',template: 'opt'}],addCateDialogVisible: false,addCateForm: {cat_pid: 0,cat_name: '',cat_level: 0},// 添加商品分类表单验证addCateFormRules: {cat_name: [{ required: true, message: '请输入分类名称', trigger: 'blur' }]},parentCateList: [],cascaderProps: {expandTrigger: 'hover',checkStrictly: true,value: 'cat_id',label: 'cat_name',children: 'children'},selectedKeys: []}},created() {this.getCateList()},methods: {async getCateList() {const { data: res } = await this.$http.get('categories', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.catelist = res.data.resultthis.total = res.data.totalthis.$msg.success('商品分类获取成功')},handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getCateList()},handleCurrentChange(page) {console.log('page: ', page);this.queryInfo.pagenum = pagethis.getCateList()},// 展示添加商品分类对话框async showAddCateDialog() {// 获取父级分类const { data: res } = await this.$http.get('categories', { params: { type: 2 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.error)this.parentCateList = res.datathis.addCateDialogVisible = true},// 关闭添加商品分类对话框addCateDialogClosed() {this.$refs.addCateFormRef.resetFields()this.addCateForm.cat_pid = 0this.addCateForm.cat_level = 0this.addCateForm.cat_name = ''this.selectedKeys = []},// 添加商品分类async addCate() {// 验证表单this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的分类名称')const { data: res } = await this.$http.post('categories', this.addCateForm)if (res.meta.status !== 201) return this.$msg.error(res.meta.msg)this.$msg.success('添加商品分类成功')this.getCateList()// 关闭对话框,重置数据this.addCateDialogVisible = false})},parentCateChange(v) {console.log('change: ', v);// 处理父分类id和分类级别if (this.selectedKeys.length > 0) {this.addCateForm.cat_pid = this.selectedKeys[this.selectedKeys.length - 1]this.addCateForm.cat_level = this.selectedKeys.length} else {this.addCateForm.cat_pid = 0this.addCateForm.cat_level = 0}},async removeCateById(uid) {const confirm = await this.$confirm('此操作将永久删除该分类, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = await this.$http.delete('categories/' + uid)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('删除商品分类成功')if (this.queryInfo.pagenum > 1 && this.catelist.length === 1) this.queryInfo.pagenum -= 1this.getCateList()}}
}
</script>
1、请求分类数据,请求分类数据并将数据保存在data中
2、使用插件展示数据,使用第三方插件 vue-table-with-tree-grid 展示分类数据:
- 在vue 控制台中点击依赖->安装依赖->运行依赖->输入vue-table-with-tree-gird->点击安装
- 打开main.js,导入vue-table-with-tree-grid import TreeTable from 'vue-table-with-tree-grid',并全局注册组件Vue.component('tree-table', TreeTable)
3、自定义数据列,使用vue-table-with-tree-grid定义模板列并添加自定义列
4、完成分页功能
5、完成添加分类,添加级联菜单显示父级分类。先导入Cascader组件,并注册;然后添加使用级联菜单组件
参数管理页
只允许给三级分类内容设置参数,参数分为动态参数和静态参数属性。
添加 goods/Params.vue 子组件,并在router.js中引入该组件并设置路由规则。
绘制参数管理基本结构
完成Params.vue组件的基本布局,其中警告提示信息使用了el-alert,在element.js引入该组件并注册:
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>参数列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><el-alert title="注意:只允许为第三级分类设置相关参数!" type="warning" show-icon :closable="false"></el-alert><!-- 商品分类 --><div class="cat_opt"><span>请选择商品分类:</span><el-cascader v-model="selectedCateKeys" :options="cateList" :props="cateProps"  @change="handleChange" clearable></el-cascader></div><el-tabs v-model="activeName" @tab-click="handleTabClick"><el-tab-pane label="动态参数" name="many"><el-button type="primary" size="mini" :disabled="selectedCateKeys.length!==3" @click="addDialogVisible = true">添加参数</el-button><!-- 动态参数列表 --><el-table :data="manyTableData" style="width: 100%" border stripe><el-table-column type="expand"><template slot-scope="scope"><el-tag v-for="(v, i) in scope.row.attr_vals" :key="i" closable @close="handleClose(scope.row, i)">{{v}}</el-tag><el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button></template></el-table-column><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="attr_name" label="属性名称"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParams(scope.row.attr_id)">删除</el-button></template></el-table-column></el-table></el-tab-pane><el-tab-pane label="静态属性" name="only"><el-button type="primary" size="mini" :disabled="selectedCateKeys.length!==3" @click="addDialogVisible = true">添加属性</el-button><!-- 静态属性列表 --><el-table :data="onlyTableData" style="width: 100%" border stripe><el-table-column type="expand"><template slot-scope="scope"><el-tag v-for="(v, i) in scope.row.attr_vals" :key="i" closable @close="handleClose(scope.row, i)">{{v}}</el-tag><el-input class="input-new-tag" v-if="scope.row.inputVisible" v-model="scope.row.inputValue" ref="saveTagInput" size="small" @keyup.enter.native="handleInputConfirm(scope.row)" @blur="handleInputConfirm(scope.row)"></el-input><el-button v-else class="button-new-tag" size="small" @click="showInput(scope.row)">+ New Tag</el-button></template></el-table-column><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="attr_name" label="属性名称"></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="showEditDialog(scope.row.attr_id)">编辑</el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeParams(scope.row.attr_id)">删除</el-button></template></el-table-column></el-table></el-tab-pane></el-tabs></el-card><!-- 添加参数对话框 --><el-dialog :title="'添加' + titleText" :visible.sync="addDialogVisible" width="50%" @close="addDialogClosed"><el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="100px"><el-form-item :label="titleText" prop="attr_name"><el-input v-model="addForm.attr_name"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addDialogVisible = false">取 消</el-button><el-button type="primary" @click="addParams">确 定</el-button></span></el-dialog><!-- 编辑参数对话框 --><el-dialog :title="'编辑' + titleText" :visible.sync="editDialogVisible" width="50%" @close="editDialogClosed"><el-form :model="editForm" :rules="editFormRules" ref="editFormRef" label-width="100px"><el-form-item :label="titleText" prop="attr_name"><el-input v-model="editForm.attr_name"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="editDialogVisible = false">取 消</el-button><el-button type="primary" @click="editParams">确 定</el-button></span></el-dialog></div>
</template>
主要功能实现
<script>
export default {data() {return {cateList: [],selectedCateKeys: [],cateProps: {expandTrigger: 'hover',value: 'cat_id',label: 'cat_name',children: 'children'},// 被激活的标签页名activeName: 'many',// 动态参数数据manyTableData: [],// 静态属性数据onlyTableData: [],// 是否展示添加参数对话框addDialogVisible: false,// 添加参数对话框数据addForm: {attr_name: ''},// 添加参数对话框验证规则addFormRules: {attr_name: [{ required: true, message: '请输入参数名称', trigger: 'blur' }]},// 是否展示编辑参数对话框editDialogVisible: false,// 编辑参数对话框数据editForm: {attr_name: ''},// 编辑参数对话框验证规则editFormRules: {attr_name: [{ required: true, message: '请输入参数名称', trigger: 'blur' }]}}},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } = await this.$http.get('categories', { params: { type: 3 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取商品分类成功')this.cateList = res.data},// 获取参数列表数据async getParamsData() {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: this.activeName } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取参数列表成功')// 将 attr_vals 转换为数组res.data.forEach(item => {item.attr_vals = item.attr_vals ? item.attr_vals.split(' ') : []item.inputVisible = falseitem.inputValue = ''});if (this.activeName === 'many') this.manyTableData = res.datathis.onlyTableData = res.data},// 分类改变handleChange() {if (this.selectedCateKeys.length !== 3) {this.selectedCateKeys = []this.manyTableData = []this.onlyTableData = []return}console.log('change: ', this.selectedCateKeys);this.getParamsData()},// 点击标签页handleTabClick() {if (this.selectedCateKeys.length === 3) this.getParamsData()},// 关闭添加参数对话框addDialogClosed() {this.$refs.addFormRef.resetFields()},// 添加商品参数addParams() {// 验证表单this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的参数名称')const { data: res } = await this.$http.post(`categories/${this.cateId}/attributes`, { attr_name: this.addForm.attr_name,attr_sel: this.activeName})if (res.meta.status !== 201) return this.$msg.error(res.meta.msg)this.$msg.success(`添加${this.titleText}成功`)this.addDialogVisible = falsethis.getParamsData()})},// 展示编辑参数对话框async showEditDialog(attrId) {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes/${attrId}`, { params: { attr_sel: this.activeName } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`获取${this.titleText}成功`)this.editForm = res.datathis.editDialogVisible = true},// 关闭编辑参数对话框editDialogClosed() {this.$refs.editFormRef.resetFields()},// 编辑商品参数editParams() {// 验证表单this.$refs.editFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写正确的参数名称')const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${this.editForm.attr_id}`, { attr_name: this.editForm.attr_name,attr_sel: this.activeName})if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`添加${this.titleText}成功`)this.editDialogVisible = falsethis.getParamsData()})},// 删除商品参数async removeParams(attrId) {const confirm = await this.$confirm(`此操作将永久删除该${this.titleText}, 是否继续?`, '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = await this.$http.delete(`categories/${this.cateId}/attributes/${attrId}`)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`删除${this.titleText}成功`)this.getParamsData()},// 保存参数可选项async saveAttrVals(row, attrVals, isAdd) {const { data: res } = await this.$http.put(`categories/${this.cateId}/attributes/${row.attr_id}`, { attr_name: row.attr_name,attr_sel: this.activeName,attr_vals: attrVals})if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success(`${isAdd ? '添加' : '删除'}${this.titleText}可选项成功`)this.getParamsData()},// 删除参数可选项handleClose(row, i) {// 删除元素const attrVals = [...row.attr_vals.slice(0, i), ...row.attr_vals.slice(i + 1)].join(' ')console.log('attrVals: ', attrVals, '\ni: ', i);this.saveAttrVals(row, attrVals, false)},// 展示添加参数可选项输入框showInput(row) {row.inputVisible = true// 让文本框自动获得焦点// $nextTick 方法的作用,就是当页面上元素被重新渲染之后,才会指定回调函数中的代码this.$nextTick(_ => {this.$refs.saveTagInput.$refs.input.focus();});},// handleInputConfirm(row) {if (row.inputValue.trim().length === 0) {row.inputVisible = falserow.inputValue = ''return}// 添加元素const attrVals = row.attr_vals.concat(row.inputValue.trim()).join(' ')console.log('attrVals: ', attrVals);this.saveAttrVals(row, attrVals, true)}},// 计算属性computed: {// 选中的分类idcateId() {if (this.selectedCateKeys.length === 3) return this.selectedCateKeys[2]return null},// 动态计算标题的文本titleText() {if (this.activeName === 'many') {return '动态参数'}return '静态属性'}}
}
</script>
1、完成级联选择框,完成商品分类级联选择框
2、展示参数,展示动态参数数据以及静态属性数据
3、添加参数,完成添加参数或属性
4、编辑参数,完成编辑参数或属性
5、删除参数,删除参数或属性
6、动态参数和静态属性管理:
- 展示动态参数可选项,动态参数可选项展示及操作在获取动态参数的方法中进行处理。
- 添加/删除动态参数可选项
- 展示静态属性可选项,静态属性可选项展示及操作在获取动态参数的方法中进行处理。
- 添加/删除静态属性可选项
注意:当用户在级联选择框中选中了非三级分类时,需要清空表格中数据
商品列表页
添加 goods/List.vue 子组件,并在router.js中引入该组件并设置路由规则
绘制商品列表页基本结构
略,详情参考如下代码:
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>商品列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 搜索与添加 --><el-row :gutter="20"><el-col :span="8"><el-input placeholder="请输入内容" v-model.trim="queryInfo.query" clearable @clear="getGoodsList"><el-button slot="append" icon="el-icon-search" @click="queryGoodsList" :disabled="queryInfo.query ? false : true"></el-button></el-input></el-col><el-col :span="4"><el-button type="primary" @click="goAddPage">添加商品</el-button></el-col></el-row><!-- 用户列表 --><el-table :data="goodsList" style="width: 100%" border stripe><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="goods_name" label="商品名称"></el-table-column><el-table-column prop="goods_price" label="商品价格(元)" width="95"></el-table-column><el-table-column prop="goods_weight" label="商品重量" width="70"></el-table-column><el-table-column prop="add_time" label="创建时间" width="140"><template slot-scope="scope">{{scope.row.add_time | dateFormatter}}</template></el-table-column><el-table-column label="操作" width="130"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini"></el-button><el-button type="danger" icon="el-icon-delete" size="mini" @click="removeById(scope.row.goods_id)"></el-button></template></el-table-column></el-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]" :page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total" background></el-pagination><pre>{{goodsList}}</pre></el-card></div>
</template>
主要功能实现
<script>
export default {data() {return {// 获取商品列表接口参数queryInfo: {query: '', // 搜索内容pagenum: 1, // 页面pagesize: 10 // 每页显示条数},// 商品列表数据goodsList: [],// 商品列表总条数total: 0}},created() {this.getGoodsList()},methods: {// 获取商品列表数据async getGoodsList() {const { data: res } = await this.$http.get('goods', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.goodsList = res.data.goodsthis.total = res.data.totalthis.$msg.success('获取商品列表成功')},// 查询商品queryGoodsList() {this.queryInfo.pagenum = 1this.getGoodsList()},// pagesize 改变handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getGoodsList()},// 页码值 改变handleCurrentChange(num) {console.log('num: ', num);this.queryInfo.pagenum = numthis.getGoodsList()},// 删除商品async removeById(gid) {const confirm = await this.$confirm('此操作将永久删除该商品, 是否继续?', '提示', {confirmButtonText: '确定',cancelButtonText: '取消',type: 'warning'}).catch(e => e);// 如果用户确认删除,则返回值为字符串 confirm;如果用户取消了删除,则返回值为字符串 cancelconsole.log('confirm: ', confirm);if (confirm !== 'confirm') returnconst { data: res } = this.$http.delete('goods/' + gid)if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('删除商品成功')this.getGoodsList()},// 添加商品goAddPage() {console.log('goAddPage');this.$router.push('/home/addGoods')}}
}
</script>
1、数据展示,添加数据表格展示数据以及分页功能的实现,搜索功能的实现。在main.js中添加过滤器:
Vue.filter('dateFormatter', (ov) => {const date = new Date(ov)const y = date.getFullYear()const m = (date.getMonth() + 1 + '').padStart(2, '0')const d = (date.getDate() + '').padStart(2, '0')const hh = (date.getHours() + '').padStart(2, '0')const mm = (date.getHours() + '').padStart(2, '0')const ss = (date.getHours() + '').padStart(2, '0')return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
})
2、实现删除商品
3、添加商品,添加编程式导航,在List.vue中添加编程式导航,并创建添加商品路由组件及规则
添加商品页
添加 goods/Add.vue 子组件,并在router.js中引入该组件并设置路由规则。
绘制添加商品页基本结构
- 布局过程中需要使用Steps组件,在element.js中引入并注册该组件,并在global.css中给组件设置全局样式
- 其他略……
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>商品管理</el-breadcrumb-item><el-breadcrumb-item>添加商品</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 警告 --><el-alerttitle="添加商品信息"type="info"centershow-icon :closable="false"></el-alert><!-- 步骤条 --><el-steps :space="200" :active="activeIndex * 1" align-center finish-status="success"><el-step title="基本信息"></el-step><el-step title="商品参数"></el-step><el-step title="商品属性"></el-step><el-step title="商品图片"></el-step><el-step title="商品内容"></el-step><el-step title="完成"></el-step></el-steps><!-- 标签栏 --><el-form :model="addForm" :rules="addFormRules" ref="addFormRef" label-width="70px" label-position="top"><el-tabs v-model="activeIndex" tab-position="left" :before-leave="beforeTabLeave" @tab-click="tabClicked"><el-tab-pane label="基本信息" name="0"><el-form-item label="商品名称" prop="goods_name"><el-input v-model="addForm.goods_name"></el-input></el-form-item><el-form-item label="商品价格" prop="goods_price"><el-input v-model="addForm.goods_price" type="number"></el-input></el-form-item><el-form-item label="商品重量" prop="goods_weight"><el-input v-model="addForm.goods_weight" type="number"></el-input></el-form-item><el-form-item label="商品数量" prop="goods_number"><el-input v-model="addForm.goods_number" type="number"></el-input></el-form-item><el-form-item label="商品分类" prop="goods_cat"><el-cascader v-model="addForm.goods_cat" :options="cateList" :props="cateProps"  @change="handleChange" clearable></el-cascader></el-form-item></el-tab-pane><el-tab-pane label="商品参数" name="1"><el-form-item v-for="(v, i) in manyTableData" :key="i" :label="v.attr_name"><el-checkbox-group v-model="v.attr_vals"><el-checkbox v-for="(item, index) in v.attr_vals" :key="index" :label="item" border></el-checkbox></el-checkbox-group></el-form-item><pre>{{manyTableData}}</pre></el-tab-pane><el-tab-pane label="商品属性" name="2"><el-form-item v-for="(v, i) in onlyTableData" :key="i" :label="v.attr_name"><el-input v-model="v.attr_vals"></el-input></el-form-item><pre>{{onlyTableData}}</pre></el-tab-pane><el-tab-pane label="商品图片" name="3"><el-upload action="http://127.0.0.1:8888/api/private/v1/upload":on-preview="handlePreview":on-remove="handleRemove" :headers="headerObj" :on-success="handleSuccess"list-type="picture"><el-button size="small" type="primary">点击上传</el-button></el-upload></el-tab-pane><el-tab-pane label="商品内容" name="4"><quill-editor v-model="addForm.goods_introduce" @blur="onEditorBlur"></quill-editor><el-button class="btnAdd" type="primary" @click="add">添加商品</el-button></el-tab-pane></el-tabs></el-form><!-- 预览对话框 --><el-dialogtitle="图片预览":visible.sync="previewVisible"width="50%"><img class="previewImg" :src="previewPath" alt=""></el-dialog></el-card></div>
</template>
主要功能实现
<script>
import _ from 'lodash';export default {data() {return {activeIndex: '0',addForm: {goods_name: '',goods_price: '',goods_weight: '',goods_number: '',goods_cat: [],// 商品图片pics: [],// 描述goods_introduce: '',// 参数attrs: []},addFormRules: {goods_name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }], goods_price: [{ required: true, message: '请输入商品价格', trigger: 'blur' }], goods_weight: [{ required: true, message: '请输入商品重量', trigger: 'blur' }], goods_number: [{ required: true, message: '请输入商品数量', trigger: 'blur' }],goods_cat: [{ required: true, message: '请选择商品分类', trigger: 'change' }]},// 商品分类cateList: [],cateProps: {expandTrigger: 'hover',value: 'cat_id',label: 'cat_name',children: 'children'},// 动态参数列表manyTableData: [],// 静态属性列表onlyTableData: [],// 请求头headerObj: { Authorization: window.sessionStorage.getItem('token') },// 是否展示预览图previewVisible: false,// 预览图片路径previewPath: ''}},created() {this.getCateList()},methods: {// 获取分类数据async getCateList() {const { data: res } = await this.$http.get('categories', { params: { type: 3 } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取商品分类成功')this.cateList = res.data},// 选择分类handleChange(v) {if (this.addForm.goods_cat.length !== 3) {this.addForm.goods_cat = []return}console.log('handleChange value: ', v);},// 标签页钩子函数beforeTabLeave(ai, oai) {console.log('ai: ', ai, ', oai: ', oai);if (oai === '0' && this.addForm.goods_cat.length !== 3) {this.$msg.error('请选择商品分类')return false}},// 点击标签栏async tabClicked() {if (this.activeIndex === '1') {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: 'many' } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取动态参数成功')res.data.forEach(item => {item.attr_vals = item.attr_vals.length > 0 ? item.attr_vals.split(' ') : []});this.manyTableData = res.data} else if (this.activeIndex === '2') {const { data: res } = await this.$http.get(`categories/${this.cateId}/attributes`, { params: { sel: 'only' } })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取动态参数成功')this.onlyTableData = res.data}},// 点击预览图片handlePreview(file) {console.log('handlePreview: ', file);this.previewPath = file.response.data.urlthis.previewVisible = true},// 点击删除图片handleRemove(file, fileList) {// console.log('handleRemove:\nfile: ', file, '\nfileList: ', fileList);const index = this.addForm.pics.findIndex(v => v.pic === file.response.data.tmp_path)if (index !== -1) this.addForm.pics.splice(index, 1)console.log('addForm: ', this.addForm);},// 上传文件成功handleSuccess(response, file, fileList) {// console.log('handleSuccess:\nresponse: ', response, '\nfile: ', file, '\nfileList: ', fileList);this.addForm.pics.push({ pic: response.data.tmp_path })console.log('addForm: ', this.addForm);},// 富文本编辑器失去焦点onEditorBlur() {console.log('content: ', this.addForm.goods_introduce);},// 添加商品add() {this.$refs.addFormRef.validate(async valid => {if (!valid) return this.$msg.error('请填写必要的表单项')// lodash 深拷贝const addForm = _.cloneDeep(this.addForm)// 处理分类数据addForm.goods_cat = addForm.goods_cat.join(',')// 处理动态参数this.manyTableData.forEach(item => {const newInfo = {attr_id: item.attr_id,attr_value: item.attr_vals.join(' ')}addForm.attrs.push(newInfo)});// 处理静态属性this.onlyTableData.forEach(item => {const newInfo = {attr_id: item.attr_id,attr_value: item.attr_vals}addForm.attrs.push(newInfo)});console.log('addForm: ', addForm);// 发起请求const { data: res } = await this.$http.post('goods', addForm)if (res.meta.status !== 201) this.$msg.error(res.meta.msg)this.$msg.success('添加商品成功')this.$router.push('/home/goods')})}},computed: {cateId() {if (this.addForm.goods_cat.length === 3) return this.addForm.goods_cat[2]return null}}
}
</script>
1、添加tab栏切换验证,也就是说不输入某些内容,无法切换到别的tab栏
2、展示信息,展示商品参数信息、商品属性信息,在商品参数信息展示中使用的el-checkbox,el-checkbox-group组件,打开element.js引入组件并注册组件
3、完成图片上传,使用upload组件完成图片上传,在element.js中引入upload组件,并注册。因为upload组件进行图片上传的时候并不是使用axios发送请求,所以需要手动为上传图片的请求添加token,即为upload组件添加headers属性
4、使用富文本插件,想要使用富文本插件vue-quill-editor,就必须先从依赖安装该插件,引入并注册vue-quill-editor
5、添加商品,完成添加商品的操作,在添加商品之前,为了避免goods_cat数组转换字符串之后导致级联选择器报错需要打开vue控制条,点击依赖,安装lodash,把addForm进行深拷贝
订单列表页
创建订单列表路由组件并添加路由规则。
绘制订单列表页基本结构
略,详情参考如下代码:
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>订单管理</el-breadcrumb-item><el-breadcrumb-item>订单列表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><!-- 搜索与添加 --><el-row :gutter="20"><el-col :span="8"><el-input placeholder="请输入内容" v-model.trim="queryInfo.query" clearable @clear="getOrderList"><el-button slot="append" icon="el-icon-search" @click="queryOrderList" :disabled="queryInfo.query ? false : true"></el-button></el-input></el-col></el-row><!-- 用户列表 --><el-table :data="orderList" style="width: 100%" border stripe><el-table-column type="index" label="#"></el-table-column><el-table-column  prop="order_number" label="订单编号"></el-table-column><el-table-column prop="order_price" label="订单价格"></el-table-column><el-table-column prop="order_pay" label="是否付款"><template slot-scope="scope"><el-tag type="danger" v-if="scope.row.pay_status === '0'">未付款</el-tag><el-tag type="success" v-else>已付款</el-tag></template></el-table-column><el-table-column prop="is_send" label="是否发货"></el-table-column><el-table-column prop="create_time" label="下单时间"><template slot-scope="scope">{{scope.row.create_time | dateFormatter}}</template></el-table-column><el-table-column label="操作"><template slot-scope="scope"><el-button type="primary" icon="el-icon-edit" size="mini" @click="addressVisible = true"></el-button><el-button type="success" icon="el-icon-location" size="mini" @click="showProgressBox(scope.row.order_number)"></el-button></template></el-table-column></el-table><!-- 分页 --><el-pagination@size-change="handleSizeChange"@current-change="handleCurrentChange":current-page="queryInfo.pagenum":page-sizes="[2, 3, 5, 10]" :page-size="queryInfo.pagesize"layout="total, sizes, prev, pager, next, jumper":total="total" background></el-pagination><pre>{{orderList}}</pre></el-card><!-- 修改地址对话框 --><el-dialog title="添加商品分类" :visible.sync="addressVisible" width="50%" @close="addressDialogClosed"><el-form :model="addressForm" :rules="addressFormRules" ref="addressFormRef" label-width="120px"><el-form-item label="省市区/县:" prop="address1"><el-cascader v-model="addressForm.address1" :options="cityData" clearable></el-cascader></el-form-item><el-form-item label="详细地址:" prop="address2"><el-input v-model="addressForm.address2"></el-input></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="addressVisible = false">取 消</el-button><el-button type="primary" @click="addressConfirm">确 定</el-button></span></el-dialog><!-- 物流进度对话框 --><el-dialog title="物流进度" :visible.sync="progressVisible" width="50%"><el-timeline><el-timeline-itemv-for="(activity, index) in progressInfo":key="index":color="index === 0 ? '#00ff00' : ''":timestamp="activity.time">{{activity.context}}</el-timeline-item></el-timeline></el-dialog></div>
</template>
主要功能实现
<script>
import cityData from './citydata.js'export default {data() {return {queryInfo: {query: '',pagenum: 1,pagesize: 10},total: 0,// 订单列表orderList: [],// 省市区/县数据cityData,// 级联选择器属性cascaderProps: {expandTrigger: 'hover'},// 修改地址对话框addressVisible: false,addressForm: {address1: [],address2: ''},addressFormRules: {address1: [{ required: true, message: '请选择省市区县', trigger: 'change' }],address2: [{ required: true, message: '请填写详细地址', trigger: 'blur' }]},// 物流进度对话框progressVisible: false,// 物流进度数据progressInfo: []}},created() {this.getOrderList()},methods: {// 获取订单列表async getOrderList() {const { data: res } = await this.$http.get('orders', { params: this.queryInfo })if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取订单列表成功')this.orderList = res.data.goodsthis.total = res.data.total},// 查询订单列表queryOrderList() {this.queryInfo.pagenum = 1this.getOrderList()},// pagesize 改变handleSizeChange(size) {console.log('size: ', size);this.queryInfo.pagesize = sizeconst maxN = parseInt(this.total / this.queryInfo.pagesize + '') + (this.total % this.queryInfo.pagesize > 0 ? 1 : 0)this.queryInfo.pagenum = this.queryInfo.pagenum > maxN ? maxN : this.queryInfo.pagenumthis.getOrderList()},// 页码值 改变handleCurrentChange(num) {console.log('num: ', num);this.queryInfo.pagenum = numthis.getOrderList()},// 关闭修改地址对话框addressDialogClosed() {// console.log('addressForm: ', this.addressForm);this.$refs.addressFormRef.resetFields()},// 修改地址addressConfirm() {// console.log('addressForm: ', this.addressForm);this.addressVisible = false},// 展示物流进度对话框async showProgressBox(orderNumber) {// const { data: res } = await this.$http.get('kuaidi/' + orderNumber)// if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)// this.$msg.success('获取物流进度成功')// this.progressInfo = res.dataconst data = `[{"time": "2018-05-10 09:39:00","ftime": "2018-05-10 09:39:00","context": "已签收,感谢使用顺丰,期待再次为您服务","location": ""},{"time": "2018-05-10 08:23:00","ftime": "2018-05-10 08:23:00","context": "[北京市]北京海淀育新小区营业点派件员 顺丰速运 95338正在为您派件","location": ""},{"time": "2018-05-10 07:32:00","ftime": "2018-05-10 07:32:00","context": "快件到达 [北京海淀育新小区营业点]","location": ""},{"time": "2018-05-10 02:03:00","ftime": "2018-05-10 02:03:00","context": "快件在[北京顺义集散中心]已装车,准备发往 [北京海淀育新小区营业点]","location": ""},{"time": "2018-05-09 23:05:00","ftime": "2018-05-09 23:05:00","context": "快件到达 [北京顺义集散中心]","location": ""},{"time": "2018-05-09 21:21:00","ftime": "2018-05-09 21:21:00","context": "快件在[北京宝胜营业点]已装车,准备发往 [北京顺义集散中心]","location": ""},{"time": "2018-05-09 13:07:00","ftime": "2018-05-09 13:07:00","context": "顺丰速运 已收取快件","location": ""},{"time": "2018-05-09 12:25:03","ftime": "2018-05-09 12:25:03","context": "卖家发货","location": ""},{"time": "2018-05-09 12:22:24","ftime": "2018-05-09 12:22:24","context": "您的订单将由HLA(北京海淀区清河中街店)门店安排发货。","location": ""},{"time": "2018-05-08 21:36:04","ftime": "2018-05-08 21:36:04","context": "商品已经下单","location": ""}]`this.progressInfo = JSON.parse(data)this.progressVisible = true}}
}
</script>
1、实现数据展示及分页
2、制作省市区/县联动,制作 citydata.js 数据文件放到到components/order文件夹中,然后导入citydata.js文件
3、制作物流进度对话框,因为使用的是element-ui中提供的Timeline组件,所以需要导入并注册组件
数据统计页
创建数据统计路由组件并添加路由规则。
导入ECharts并使用,具体实现如下:
<template><div><!-- 面包屑导航 --><el-breadcrumb separator-class="el-icon-arrow-right"><el-breadcrumb-item :to="{ path: '/home/welcome' }">首页</el-breadcrumb-item><el-breadcrumb-item>数据统计</el-breadcrumb-item><el-breadcrumb-item>数据报表</el-breadcrumb-item></el-breadcrumb><!-- 卡片 --><el-card><div id="main" style="width: 750px; height:400px;"></div></el-card></div>
</template><script>
// 只会导出(export default mutations)这个默认的对象返回
// import echarts from 'echarts'// 将 若干export导出的内容组合成一个对象返回
import * as echarts from 'echarts'import _ from 'lodash'export default {data() {return {options: {title: {text: '用户来源'},tooltip: {trigger: 'axis',axisPointer: {type: 'cross',label: {backgroundColor: '#E9EEF3'}}},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis: [{boundaryGap: false}],yAxis: [{type: 'value'}]}}},async mounted() {const { data: res } = await this.$http.get('reports/type/1')if (res.meta.status !== 200) return this.$msg.error(res.meta.msg)this.$msg.success('获取折线图数据成功')// 初始化var myChart = echarts.init(document.getElementById('main'))// 设置配置项myChart.setOption(_.merge(this.options, res.data))}
}
</script>
相关文章:
Vue2 基础八电商后台管理项目——中
代码下载 商品分类页 新商品分类组件 goods/Cate.vue,在router.js中导入子级路由组件 Cate.vue,并设置路由规则。 绘制商品分类基本结构 在Cate.vue组件中添加面包屑导航以及卡片视图中的添加分类按钮: <template><div><…...
Typescript window.localStorage 存储 Obj Value区别
window.localStorage.setItem(UserC, JSON.stringify(userC)) const userC JSON.parse(window.localStorage.getItem(UserC) || {}) 不能获得UserC,所有保存的时候需要存储value,而不是对象。 {"__v_isShallow":false, "__v_isRef&quo…...
Linux要解压 .rar 文件,你应该使用 unrar 命令
命令 sudo tar -zxf ~/WebDemo.rar -C /usr/local 有一些问题。tar 命令通常用于解压 .tar、.tar.gz 或 .tar.bz2 文件,而不是 .rar 文件。要解压 .rar 文件,你应该使用 unrar 命令。下面是正确的步骤: 首先,安装 unrar࿰…...
 
【qt】如何获取网卡的信息?
网卡不只一种,有有线的,有无线的等等 我们用QNetworkInterface类的静态函数allInterfaces() 来获取所有的网卡 返回的是一个网卡的容器. 然后我们对每个网卡来获取其设备名称和硬件地址 可以通过静态函数humanReadableName() 来获取设备名称 可以通过静态函数**hardwareAddre…...
 
使用Netty框架实现WebSocket服务端与客户端通信(附ssl)
仓库地址: https://gitee.com/lfw1024/netty-websocket 导入后可直接运行 预览页面 自签证书: #换成自己的本地ip keytool -genkey -alias server -keyalg RSA -validity 3650 -keystore D:\mystore.jks -ext sanip:192.168.3.7,ip:127.0.0.1,dns:lo…...
 
ssm校园志愿服务信息系统-计算机毕业设计源码97697
摘 要 随着社会的进步和信息技术的发展,越来越多的学校开始重视志愿服务工作,通过组织各种志愿服务活动,让学生更好地了解社会、服务社会。然而,在实际操作中,志愿服务的组织和管理面临着诸多问题,如志愿者…...
 
JVM原理(二):JVM之HotSpot虚拟机中对象的创建寻位与定位整体流程
1. 对象的创建 遇到new指令时 当Java虚拟机遇到一个字节码new指令时。 首先会去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否被加载、解析和初始化过。 如果没有,那么必须执行类的加载过程(加载、检查…...
 
(七)glDrawArry绘制
几何数据:vao和vbo 材质程序:vs和fs(顶点着色器和片元着色器) 接下来只需要告诉GPU,使用几何数据和材质程序来进行绘制。 #include <glad/glad.h>//glad必须在glfw头文件之前包含 #include <GLFW/glfw3.h> #include <iostrea…...
 
记一次小程序渗透
这次的小程序渗透刚好每一个漏洞都相当经典所以记录一下。 目录 前言 漏洞详情 未授权访问漏洞/ 敏感信息泄露(高危) 水平越权(高危) 会话重用(高危) 硬编码加密密钥泄露(中危࿰…...
C++ 的常见算法 之一
C 的常见算法 之一 不修改序列算法for_eachcountfind 修改序列算法copymove 不修改序列算法 for_each #include <iostream> // std::cout #include <algorithm> // std::for_each #include <vector> // std::vectorusing namespace std;struc…...
微前端的需求有哪些?微前端的原理是怎么样的?为什么这么设计,及微前端的应用场景是什么?对有些客户,前端的重要性高于后端
微前端(Micro Frontends)是将前端应用拆分成多个独立、可部署的部分,每个部分可以由不同的团队独立开发、测试、部署和维护。这种架构类似于微服务在后端的应用,是为了应对复杂前端应用的维护和扩展问题而提出的。 来龙去脉 背景…...
 
【Spring Boot】统一数据返回
目录 统一数据返回一. 概念二.实现统一数据返回2.1 重写responseAdvice方法2.2 重写beforeBodyWriter方法 三. 特殊类型-String的处理四. 全部代码 统一数据返回 一. 概念 其实统一数据返回是运用了AOP(对某一类事情的集中处理)的思维,简单…...
 
证券交易系统中服务器监控系统功能设计
1.背景介绍 此服务器监控系统的目的在于提高行情服务器的监管效率,因目前的的行情服务器,包括DM、DT、DS配置数量较多,巡回维护耗时较多,当行情服务器出现异常故障,或者因为网络问题造成数据断线等情况时,监…...
 
【线性代数的本质】矩阵与线性变换
线性变化要满足两点性质: 直线(连续的点)在变换后还是直线。原点不变。 假设有坐标轴(基底) i ^ \widehat{i} i 和 j ^ \widehat{j} j : i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…...
 
CV02_超强数据集:MSCOCO数据集的简单介绍
1.1 简介 MSCOCO数据集,全称为Microsoft Common Objects in Context,是由微软公司在2014年推出并维护的一个大规模的图像数据集,旨在推动计算机视觉领域的研究,尤其是目标识别、目标检测、实例分割、图像描述生成等任务。该数据集…...
 
Linux--信号(万字详解!超完整!)
目录 0.预备知识 0.1.基本概念 0.2.信号的捕捉 0.3.理解信号的发送与保存 1.信号的产生(阶段一) 1.通过kill命令,向指定进程发送指定的信号 2.通过终端按键产生信号:ctrlc(信号2),ctrl\(…...
 
onnx模型转rknn到部署
简介 最近开始用3568的板子,之前是在用3399,cpu的话3399比3568强,但是3568有1T的npu算力,所以模型移植过来用npu使用,之前用ncnn感觉太慢了,rk的npu使用没有开源,所以没法兼容,只能跑…...
 
lua入门(1) - 基本语法
本文参考自: Lua 基本语法 | 菜鸟教程 (runoob.com) 需要更加详细了解的还请参看lua 上方链接 交互式编程 Lua 提供了交互式编程模式。我们可以在命令行中输入程序并立即查看效果。 Lua 交互式编程模式可以通过命令 lua -i 或 lua 来启用: 如下图: 按…...
 
Finding Global Homophily in Graph Neural Networks When Meeting Heterophily
本文发表于:ICML22 推荐指数: #paper/⭐⭐⭐ 问题背景: 异配图的邻接矩阵难以确定,以及异配图的计算复杂度开销大 可行的解决办法:高通滤波多跳邻居,GPRGNN(pagerank一类,各阶邻居的权重不同,ACM-GCN(高低通滤波,H2GCN(应该复杂度很大&…...
 
DisFormer:提高视觉动态预测的准确性和泛化能力
最新的研究进展已经显示出目标中心的表示方法在视觉动态预测任务中可以显著提升预测精度,并且增加模型的可解释性。这种表示方法通过将视觉场景分解为独立的对象,有助于模型更好地理解和预测场景中的变化。 尽管在静态图像的解耦表示学习方面已经取得了一…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
 
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
 
大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
 
el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
 
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
 
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
 
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
 
【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...
