代码和资料文档参考下一章:属性分组-后端(商品服务完成)
属性分组页面组件-attrgroup.vue
<template><el-row :gutter="20"><el-col :span="6"><category @tree-node-click="treenodeclick"></category></el-col><el-col :span="18"><div class="mod-config"><el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()"><el-form-item><el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input></el-form-item><el-form-item><el-button @click="getDataList()">查询</el-button><el-button type="success" @click="getAllDataList()">查询全部</el-button><el-buttonv-if="isAuth('product:attrgroup:save')"type="primary"@click="addOrUpdateHandle()">新增</el-button><el-buttonv-if="isAuth('product:attrgroup:delete')"type="danger"@click="deleteHandle()":disabled="dataListSelections.length <= 0">批量删除</el-button></el-form-item></el-form><el-table:data="dataList"borderv-loading="dataListLoading"@selection-change="selectionChangeHandle"style="width: 100%;"><el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column><el-table-column prop="attrGroupId" header-align="center" align="center" label="分组id"></el-table-column><el-table-column prop="attrGroupName" header-align="center" align="center" label="组名"></el-table-column><el-table-column prop="sort" header-align="center" align="center" label="排序"></el-table-column><el-table-column prop="descript" header-align="center" align="center" label="描述"></el-table-column><el-table-column prop="icon" header-align="center" align="center" label="组图标"></el-table-column><el-table-column prop="catelogId" header-align="center" align="center" label="所属分类id"></el-table-column><el-table-columnfixed="right"header-align="center"align="center"width="150"label="操作"><template slot-scope="scope"><el-button type="text" size="small" @click="relationHandle(scope.row.attrGroupId)">关联</el-button><el-buttontype="text"size="small"@click="addOrUpdateHandle(scope.row.attrGroupId)">修改</el-button><el-button type="text" size="small" @click="deleteHandle(scope.row.attrGroupId)">删除</el-button></template></el-table-column></el-table><el-pagination@size-change="sizeChangeHandle"@current-change="currentChangeHandle":current-page="pageIndex":page-sizes="[10, 20, 50, 100]":page-size="pageSize":total="totalPage"layout="total, sizes, prev, pager, next, jumper"></el-pagination><!-- 弹窗, 新增 / 修改 --><add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate" @refreshDataList="getDataList"></add-or-update><!-- 修改关联关系 --><relation-update v-if="relationVisible" ref="relationUpdate" @refreshData="getDataList"></relation-update></div></el-col></el-row></template><script>/*** 父子组件传递数据* 1)、子组件给父组件传递数据,事件机制;* 子组件给父组件发送一个事件,携带上数据。* // this.$emit("事件名",携带的数据...)*///这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)//例如:import 《组件名称》 from '《组件路径》';import Category from "@/views/common/category";import AddOrUpdate from "./attrgroup-add-or-update";import RelationUpdate from "./attr-group-relation";export default {//import引入的组件需要注入到对象中才能使用components: {Category, AddOrUpdate, RelationUpdate},props: {},data() {return {catId: 0,dataForm: {key: ""},dataList: [],pageIndex: 1,pageSize: 10,totalPage: 0,dataListLoading: false,dataListSelections: [],addOrUpdateVisible: false,relationVisible: false};},activated() {this.getDataList();},methods: {//处理分组与属性的关联relationHandle(groupId) {this.relationVisible = true;this.$nextTick(() => {this.$refs.relationUpdate.init(groupId);});},//感知树节点被点击treenodeclick(data, node, component) {if (node.level === 3) {this.catId = data.catId;this.getDataList(); //重新查询}},getAllDataList() {this.catId = 0;this.getDataList();},// 获取数据列表getDataList() {this.dataListLoading = true;this.$http({url: this.$http.adornUrl(`/product/attrgroup/list/${this.catId}`),method: "get",params: this.$http.adornParams({page: this.pageIndex,limit: this.pageSize,key: this.dataForm.key})}).then(({data}) => {if (data && data.code === 0) {this.dataList = data.page.list;this.totalPage = data.page.totalCount;} else {this.dataList = [];this.totalPage = 0;}this.dataListLoading = false;});},// 每页数sizeChangeHandle(val) {this.pageSize = val;this.pageIndex = 1;this.getDataList();},// 当前页currentChangeHandle(val) {this.pageIndex = val;this.getDataList();},// 多选selectionChangeHandle(val) {this.dataListSelections = val;},// 新增 / 修改addOrUpdateHandle(id) {this.addOrUpdateVisible = true;this.$nextTick(() => {this.$refs.addOrUpdate.init(id);});},// 删除deleteHandle(id) {var ids = id? [id]: this.dataListSelections.map(item => {return item.attrGroupId;});this.$confirm(`确定对[id=${ids.join(",")}]进行[${id ? "删除" : "批量删除"}]操作?`,"提示",{confirmButtonText: "确定",cancelButtonText: "取消",type: "warning"}).then(() => {this.$http({url: this.$http.adornUrl("/product/attrgroup/delete"),method: "post",data: this.$http.adornData(ids, false)}).then(({data}) => {if (data && data.code === 0) {this.$message({message: "操作成功",type: "success",duration: 1500,onClose: () => {this.getDataList();}});} else {this.$message.error(data.msg);}});});}}};</script><style scoped></style>
属性分组新增/修改组件-attrgroup-add-or-update.vue
此组件是属性分组点击新增或修改按钮弹出表单弹框的页面
<template><el-dialog:title="!dataForm.id ? '新增' : '修改'":close-on-click-modal="false":visible.sync="visible"@closed="dialogClose"><el-form:model="dataForm":rules="dataRule"ref="dataForm"@keyup.enter.native="dataFormSubmit()"label-width="120px"><el-form-item label="组名" prop="attrGroupName"><el-input v-model="dataForm.attrGroupName" placeholder="组名"></el-input></el-form-item><el-form-item label="排序" prop="sort"><el-input v-model="dataForm.sort" placeholder="排序"></el-input></el-form-item><el-form-item label="描述" prop="descript"><el-input v-model="dataForm.descript" placeholder="描述"></el-input></el-form-item><el-form-item label="组图标" prop="icon"><el-input v-model="dataForm.icon" placeholder="组图标"></el-input></el-form-item><el-form-item label="所属分类" prop="catelogId"><!-- <el-input v-model="dataForm.catelogId" placeholder="所属分类id"></el-input> @change="handleChange" --><!-- <el-cascader filterable placeholder="试试搜索:手机" v-model="catelogPath" :options="categorys" :props="props"></el-cascader> --><!-- :catelogPath="catelogPath"自定义绑定的属性,可以给子组件传值 --><category-cascader :catelogPath.sync="catelogPath"></category-cascader></el-form-item></el-form><span slot="footer" class="dialog-footer"><el-button @click="visible = false">取消</el-button><el-button type="primary" @click="dataFormSubmit()">确定</el-button></span></el-dialog></template><script>import CategoryCascader from '@/views/common/category-cascader'export default {data() {return {props:{value:"catId",label:"name",children:"children"},visible: false,categorys: [],catelogPath: [],dataForm: {attrGroupId: 0,attrGroupName: "",sort: "",descript: "",icon: "",catelogId: 0},dataRule: {attrGroupName: [{ required: true, message: "组名不能为空", trigger: "blur" }],sort: [{ required: true, message: "排序不能为空", trigger: "blur" }],descript: [{ required: true, message: "描述不能为空", trigger: "blur" }],icon: [{ required: true, message: "组图标不能为空", trigger: "blur" }],catelogId: [{ required: true, message: "所属分类id不能为空", trigger: "blur" }]}};},components:{CategoryCascader},methods: {dialogClose(){this.catelogPath = [];},getCategorys(){this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {this.categorys = data.data;});},init(id) {this.dataForm.attrGroupId = id || 0;this.visible = true;this.$nextTick(() => {this.$refs["dataForm"].resetFields();if (this.dataForm.attrGroupId) {this.$http({url: this.$http.adornUrl(`/product/attrgroup/info/${this.dataForm.attrGroupId}`),method: "get",params: this.$http.adornParams()}).then(({ data }) => {if (data && data.code === 0) {this.dataForm.attrGroupName = data.attrGroup.attrGroupName;this.dataForm.sort = data.attrGroup.sort;this.dataForm.descript = data.attrGroup.descript;this.dataForm.icon = data.attrGroup.icon;this.dataForm.catelogId = data.attrGroup.catelogId;//查出catelogId的完整路径this.catelogPath = data.attrGroup.catelogPath;}});}});},// 表单提交dataFormSubmit() {this.$refs["dataForm"].validate(valid => {if (valid) {this.$http({url: this.$http.adornUrl(`/product/attrgroup/${!this.dataForm.attrGroupId ? "save" : "update"}`),method: "post",data: this.$http.adornData({attrGroupId: this.dataForm.attrGroupId || undefined,attrGroupName: this.dataForm.attrGroupName,sort: this.dataForm.sort,descript: this.dataForm.descript,icon: this.dataForm.icon,catelogId: this.catelogPath[this.catelogPath.length-1]})}).then(({ data }) => {if (data && data.code === 0) {this.$message({message: "操作成功",type: "success",duration: 1500,onClose: () => {this.visible = false;this.$emit("refreshDataList");}});} else {this.$message.error(data.msg);}});}});}},created(){this.getCategorys();}};</script>
获取三级分类组件-category.vue
属性分组页面左侧三级分类显示的组件
<template><div><el-input placeholder="输入关键字进行过滤" v-model="filterText"></el-input><el-tree:data="menus":props="defaultProps"node-key="catId"ref="menuTree"@node-click="nodeclick":filter-node-method="filterNode":highlight-current="true"></el-tree></div></template><script>//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},props: {},data() {//这里存放数据return {filterText: "",menus: [],expandedKey: [],defaultProps: {children: "children",label: "name"}};},//计算属性 类似于data概念computed: {},//监控data中的数据变化watch: {filterText(val) {this.$refs.menuTree.filter(val);}},//方法集合methods: {//树节点过滤filterNode(value, data) {if (!value) return true;return data.name.indexOf(value) !== -1;},getMenus() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({data}) => {this.menus = data.data;});},nodeclick(data, node, component) {console.log("子组件category的节点被点击", data, node, component);//向父组件发送事件;this.$emit("tree-node-click", data, node, component);}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getMenus();},//生命周期 - 挂载完成(可以访问DOM元素)mounted() {},beforeCreate() {}, //生命周期 - 创建之前beforeMount() {}, //生命周期 - 挂载之前beforeUpdate() {}, //生命周期 - 更新之前updated() {}, //生命周期 - 更新之后beforeDestroy() {}, //生命周期 - 销毁之前destroyed() {}, //生命周期 - 销毁完成activated() {} //如果页面有keep-alive缓存功能,这个函数会触发};</script><style scoped></style>
分类级联选择组件-category-cascader.vue
此组件可以生成级联选择三级分类,属性分组新增修改时选择三级分类使用
<template><!--使用说明:1)、引入category-cascader.vue2)、语法:<category-cascader :catelogPath.sync="catelogPath"></category-cascader>解释:catelogPath:指定的值是cascader初始化需要显示的值,应该和父组件的catelogPath绑定;由于有sync修饰符,所以cascader路径变化以后自动会修改父的catelogPath,这是结合子组件this.$emit("update:catelogPath",v);做的--><div><el-cascaderfilterableclearableplaceholder="试试搜索:手机"v-model="paths":options="categorys":props="setting"></el-cascader></div></template><script>//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},//接受父组件传来的值props: {catelogPath: {type: Array,default(){return [];}}},data() {//这里存放数据return {setting: {value: "catId",label: "name",children: "children"},categorys: [],paths: this.catelogPath};},watch:{catelogPath(v){this.paths = this.catelogPath;console.log(this.paths)},paths(v){this.$emit("update:catelogPath",v);//还可以使用pubsub-js进行传值PubSub.publish("catPath",v);}},//方法集合methods: {getCategorys() {this.$http({url: this.$http.adornUrl("/product/category/list/tree"),method: "get"}).then(({ data }) => {this.categorys = data.data;});}},//生命周期 - 创建完成(可以访问当前this实例)created() {this.getCategorys();}};</script><style scoped></style>
属性分组关联组件-attr-group-relation.vue
<template><div><el-dialog :close-on-click-modal="false" :visible.sync="visible" @closed="dialogClose"><el-dialog width="40%" title="选择属性" :visible.sync="innerVisible" append-to-body><div><el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()"><el-form-item><el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input></el-form-item><el-form-item><el-button @click="getDataList()">查询</el-button></el-form-item></el-form><el-table:data="dataList"borderv-loading="dataListLoading"@selection-change="innerSelectionChangeHandle"style="width: 100%;"><el-table-column type="selection" header-align="center" align="center"></el-table-column><el-table-column prop="attrId" header-align="center" align="center" label="属性id"></el-table-column><el-table-column prop="attrName" header-align="center" align="center" label="属性名"></el-table-column><el-table-column prop="icon" header-align="center" align="center" label="属性图标"></el-table-column><el-table-column prop="valueSelect" header-align="center" align="center" label="可选值列表"></el-table-column></el-table><el-pagination@size-change="sizeChangeHandle"@current-change="currentChangeHandle":current-page="pageIndex":page-sizes="[10, 20, 50, 100]":page-size="pageSize":total="totalPage"layout="total, sizes, prev, pager, next, jumper"></el-pagination></div><div slot="footer" class="dialog-footer"><el-button @click="innerVisible = false">取 消</el-button><el-button type="primary" @click="submitAddRealtion">确认新增</el-button></div></el-dialog><el-row><el-col :span="24"><el-button type="primary" @click="addRelation">新建关联</el-button><el-buttontype="danger"@click="batchDeleteRelation":disabled="dataListSelections.length <= 0">批量删除</el-button><!-- --><el-table:data="relationAttrs"style="width: 100%"@selection-change="selectionChangeHandle"border><el-table-column type="selection" header-align="center" align="center" width="50"></el-table-column><el-table-column prop="attrId" label="#"></el-table-column><el-table-column prop="attrName" label="属性名"></el-table-column><el-table-column prop="valueSelect" label="可选值"><template slot-scope="scope"><el-tooltip placement="top"><div slot="content"><span v-for="(i,index) in scope.row.valueSelect.split(';')" :key="index">{{ i }}<br/></span></div><el-tag>{{ scope.row.valueSelect.split(";")[0] + " ..." }}</el-tag></el-tooltip></template></el-table-column><el-table-column fixed="right" header-align="center" align="center" label="操作"><template slot-scope="scope"><el-button type="text" size="small" @click="relationRemove(scope.row.attrId)">移除</el-button></template></el-table-column></el-table></el-col></el-row></el-dialog></div></template><script>//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)//例如:import 《组件名称》 from '《组件路径》';export default {//import引入的组件需要注入到对象中才能使用components: {},props: {},data() {//这里存放数据return {attrGroupId: 0,visible: false,innerVisible: false,relationAttrs: [],dataListSelections: [],dataForm: {key: ""},dataList: [],pageIndex: 1,pageSize: 10,totalPage: 0,dataListLoading: false,innerdataListSelections: []};},//计算属性 类似于data概念computed: {},//监控data中的数据变化watch: {},//方法集合methods: {selectionChangeHandle(val) {this.dataListSelections = val;},innerSelectionChangeHandle(val) {this.innerdataListSelections = val;},addRelation() {this.getDataList();this.innerVisible = true;},batchDeleteRelation(val) {let postData = [];this.dataListSelections.forEach(item => {postData.push({attrId: item.attrId, attrGroupId: this.attrGroupId});});this.$http({url: this.$http.adornUrl("/product/attrgroup/attr/relation/delete"),method: "post",data: this.$http.adornData(postData, false)}).then(({data}) => {if (data.code == 0) {this.$message({type: "success", message: "删除成功"});this.init(this.attrGroupId);} else {this.$message({type: "error", message: data.msg});}});},//移除关联relationRemove(attrId) {let data = [];data.push({attrId, attrGroupId: this.attrGroupId});this.$http({url: this.$http.adornUrl("/product/attrgroup/attr/relation/delete"),method: "post",data: this.$http.adornData(data, false)}).then(({data}) => {if (data.code == 0) {this.$message({type: "success", message: "删除成功"});this.init(this.attrGroupId);} else {this.$message({type: "error", message: data.msg});}});},submitAddRealtion() {this.innerVisible = false;//准备数据console.log("准备新增的数据", this.innerdataListSelections);if (this.innerdataListSelections.length > 0) {let postData = [];this.innerdataListSelections.forEach(item => {postData.push({attrId: item.attrId, attrGroupId: this.attrGroupId});});this.$http({url: this.$http.adornUrl("/product/attrgroup/attr/relation"),method: "post",data: this.$http.adornData(postData, false)}).then(({data}) => {if (data.code == 0) {this.$message({type: "success", message: "新增关联成功"});}this.$emit("refreshData");this.init(this.attrGroupId);});} else {}},init(id) {this.attrGroupId = id || 0;this.visible = true;this.$http({url: this.$http.adornUrl("/product/attrgroup/" + this.attrGroupId + "/attr/relation"),method: "get",params: this.$http.adornParams({})}).then(({data}) => {this.relationAttrs = data.data;});},dialogClose() {},//========// 获取数据列表getDataList() {this.dataListLoading = true;this.$http({url: this.$http.adornUrl("/product/attrgroup/" + this.attrGroupId + "/noattr/relation"),method: "get",params: this.$http.adornParams({page: this.pageIndex,limit: this.pageSize,key: this.dataForm.key})}).then(({data}) => {if (data && data.code === 0) {this.dataList = data.page.list;this.totalPage = data.page.totalCount;} else {this.dataList = [];this.totalPage = 0;}this.dataListLoading = false;});},// 每页数sizeChangeHandle(val) {this.pageSize = val;this.pageIndex = 1;this.getDataList();},// 当前页currentChangeHandle(val) {this.pageIndex = val;this.getDataList();}}};</script><style scoped></style>
