P71 属性分组页面搭建
前端组件抽取&父子组件交互
前端页面中:
菜单
1、sys_admin.sql语句在gulimail_admin数据库执行。注意自己的数据库名称是否和文件中的一致。刷新页面后,发现页面新增。找到平台属性—属性分组。
2、在product文件夹,新建attrgroup.vue分组。设计为栅格格式。左侧菜单占6列,右侧表格占18列。见element-ui官网layout布局的分栏间隔。刷新,查看效果。
3、product同级新建common文件夹,建 category.vue文件。抽取出来一个简单的树形结构,用于上面的树形分组菜单展示。
attrgroup.vue导入并注册组件
<script>
import Category from "../common/category.vue";
components: { Category}
<el-col :span="6">
<category></category>
</el-col>
模板、数据、方法、创建页面时获取数据。
getmenus
<el-tree
:data="menus"
:props="defaultProps"
node-key="catId"
ref="menuTree"
></el-tree>
menus: [],
defaultProps: {
children: "children",
label: "name",
},
表格
在上面的目录中,也就是生成器生成的文件。把attrgroup.vue同名文件下的内容div格式粘贴到表格模块,还有data、方法cv。
特别是AddOrUpdate导入和注册,需要cv一个新的文件进来。不要弄错了。
整体页面布局显示完成!
子传父值
要求左边菜单点击后,右边呈现详细信息。
子组件给父组件传递数据,事件机制。发送一个事件,携带上数据。
el-tree中有个 node-click 事件,包含3个参数。
@node-click="nodeclick"
nodeclick(data, node, component){
console.log("树节点被点击:",data, node, component)
console.log("刚才被点击的节点id:",data.catId)
//向父组件发送事件
this.$emit("tree-node-click",data, node, component)
}
此外,父组件
<category @tree-node-click="treeNodeClick"></category>
treeNodeClick(data, node, component){
console.log("父感知到子节点:",data.catId)
},
P72 获取属性分组
后端
在AttrGroupController.java文件中有list路径获取信息,在此基础上面改为按catelogId查找
@RequestMapping("/list/{catelogId }")
public R list(@RequestParam Map<String, Object> params,
@PathVariable("catelogId") Integer catelogId){
PageUtils page = attrGroupService.queryPage(params, catelogId);
return R.ok().put("page", page);
}
然后创建方法、添加实现
接口转到实现类,ctrl+alt+B;查看这个接口的所有实现类,ctrl+H,或者右边栏的层次结构
实现接口方法如下:接着之前的思路,包括按页查找
不要写错类名
SELECT * FROM `pms_attr_group` WHERE catelog_id = 1 and (attr_group_name like '%%' or attr_group_id = )
public PageUtils queryPage(Map<String, Object> params, Integer categoryId) {
if(categoryId == 0){ //跟原来一样
IPage<AttrGroupEntity> page = this.page(
new Query<AttrGroupEntity>().getPage(params),
new QueryWrapper<AttrGroupEntity>()
);
return new PageUtils(page);
}else{
QueryWrapper<AttrGroupEntity> wrapper = new QueryWrapper<AttrGroupEntity>().eq("catelog_id", categoryId);
String s = (String) params.get("key");
if(!StringUtils.isEmpty(s)){ // 优秀的字符串处理方法
wrapper.and((obj)->{ // consumer 函数式编程
obj.eq("attr_group_id",s).or().like("attr_group_name",s);
});
}
IPage<AttrGroupEntity> page = this.page(
new Query<AttrGroupEntity>().getPage(params),
wrapper
);
return new PageUtils(page);
}
前端
data中默认catId:0
只有节点level为3时才传递数据
if(node.level == 3){
this.catId = data.catId
this.getDataList()
}
添加请求路径,记得改为飘号,动态的;否则,前端还是显示this.catId
url: this.$http.adornUrl(`/product/attrgroup/list/${this.catId}`),
P73 分组新增&级联选择器
第一步
Cascader 级联选择器
在属性分组新增页面,的分类号模块,初始化catelogs:[]
, 改为
<el-cascader
v-model="dataForm.catelogId" 绑定
:options="catelogs" 有哪些数据可以选择
></el-cascader>
把隔壁category.vue的getmenus方法,在这新建一个getCategory方法,数据传入catelogs里,并且初始化created
发现级联结构出现,但是没有文字!
第二步
在上面的选择器增加配置属性:并且data新加
:props="props"
props:{
value:"catId",
label:"name",
children:"children"
},
显示成功!但是三级目录下,即使子为空,仍显示
第三步
在 [localhost:20000/product/category/list/tree](http://localhost:20000/product/category/list/tree)
中把目录的子属性当为空时去掉,在categoryEntity.java中子属性增加注释 @JsonInclude(JsonInclude.Include.NON_EMPTY)
测试正常!
第四步
在vue页面查看,控制选择,找到正确的页面,发现绑定的catelogId为3个。父父子
data中改为数组格式,并且发送请求,改为:-1不管用
catelogId: this.dataForm.catelogId[this.dataForm.catelogId.length-1]
P74 级联回显
第一步
将初始化数据获取,的分类号变为path
this.dataForm.catelogPath = data.attrGroup.catelogPath;
包括分类号 v-model绑定部分
第二步
attrGroup新增catelogPath属性,并标注为数据库不存在
@TableField(exist = false)
private Long[] catelogPath;
在info请求获取数据后,根据分类号id查找完整路径,再返回实体
Long catelogId = attrGroup.getCatelogId();
Long[] path = categoryService.findCatelogPath(catelogId);
attrGroup.setCatelogPath(path);
categoryService中新建方法,实现方法,记得反转
这里有List类型转为数组Long[] 类型toArray
@Override
public Long[] findCatelogPath(Long catelogId) {
List<Long> path = new ArrayList<>();
// 递归查找
List parentPath = findParentPath(catelogId, path);
Collections.reverse(parentPath);
return (Long[]) parentPath.toArray(new Long[parentPath.size()]);
}
private List findParentPath(Long catelogId, List<Long> path) {
path.add(catelogId);
CategoryEntity byId = this.getById(catelogId);
if(byId.getParentCid() != 0){
findParentPath(byId.getParentCid(), path);
}
return path;
}
在测试类中测试,可以用@Slf4j打印查看输出
@Test
public void categoryAllPath(){
Long[] catelogPath = categoryService.findCatelogPath(225L);
log.info(Arrays.toString(catelogPath));
}
成功!
第三步
发现问题,关闭页面后,分类号数据仍存在。
在dialog对话框存在回调函数,@closed="dialogClose"
新建方法,进行清除
dialogClose(){
this.dataForm.catelogPath = []
},
并在级联选择器附近放入,可搜索 filterable
搜索框提示 placeholder="搜索"