背景:开发过程中会遇到某些字段需要做成下拉框。如下图:
组件 | Element里有select选择器这个组件可以实现下拉框的效果
我们可能会想到创一个辅助表来存储这些下拉数据像这样
这样虽然能实现,但是在实际开发中是不合理的,如果有多的表的多个字段都需要用到下拉框,就需要创建很多的辅助表。并且下拉框都有一个特点,就是键值对的存在。我们就引入了字典。
这是一个字典,里面有字典名称、字典项、字典值,可以实现动态选择,且多个表多个字段需要用到的数据都可以在字典里先添加一个字典名称,再添加对应的字典项和字典值(key-value)。
具体字段设计如下:
后端字典这个类里有三个重要的接口
1.获取某个字典内所有的字典项,提供给前端的select组件使用
/*** 获取某个字典内所有的字典项,提供给前端的select组件使用*/@GetMapping("/getDictValues/{code}")public R getDictValues(@PathVariable("code") String code){QueryWrapper<SysDictEntity> queryWrapper = new QueryWrapper<>();queryWrapper.eq("type", 2);queryWrapper.eq("code", code);queryWrapper.orderByAsc("sort");List<SysDictEntity> list = sysDictService.list(queryWrapper);
// System.out.println(list);List<Map<String,String>> returnMap = new ArrayList<>();list.forEach(x->{Map<String,String> newMap = new HashMap<>();newMap.put("value", x.getValue());newMap.put("label", x.getName());returnMap.add(newMap);});return R.ok().put("dict", returnMap);}
前端调用这个接口拿到某个字典里的所有字典项以汽车品牌为例展示
<el-form-item label="品牌" prop="brand"><el-selectv-model="dataForm.brand"placeholder="请选择品牌":disabled="dataForm.id !== 0" ><!-- :value=""是传给这个表单项prop="brand"的值 --><el-optionv-for="item in options":key="item.value"clearable:label="item.label":value="item.value"></el-option></el-select></el-form-item>
this.$http({url: this.$http.adornUrl('/sys/dict/getDictValues/brand'),method: 'get',params: this.$http.adornParams()}).then(({data}) => {//console.log(data);if (data && data.code === 0) {this.options = data.dict}})
就完成了字典以select的绑定,但是有一个问题, 选择器:value的值传给这个表单项prop="brand"的值,brand拿到的是key值。(下表value对应map集合里的key、lable对应value)
所以我们的展示页面品牌这列展示的都是数字,如何展示对应的lable呢?这就用到了字典里的第二个接口。
2.传入code值,获取这个字典中所有的字典项,并且以map集合的方式传回,前端table组件展示使用。
/*** 传入code值,获取这个字典中所有的字典项,并且以map集合的方式传回,前端table组件展示使用* @param code* @return*/@GetMapping("/getAllDictValues/{code}")public R getAllDictValues(@PathVariable("code") String code){QueryWrapper<SysDictEntity> queryWrapper = new QueryWrapper<>();queryWrapper.eq("type", 2);queryWrapper.eq("code", code);queryWrapper.orderByAsc("sort");List<SysDictEntity> list = sysDictService.list(queryWrapper);Map<String,String> returnMap = new HashMap<>();list.forEach(x->{returnMap.put(x.getValue(), x.getName());});return R.ok().put("dict", returnMap);}
展示页面通过传入code值,获取这个字典中所有的字典项,并且以map集合的方式传回,这个接口,将接收到的数据 data.dict赋值给this.carBrandAll ,carBrandAll定义的一个全局对象。
//获取所有品牌getCarBrand() {this.$http({url: this.$http.adornUrl('/sys/dict/getAllDictValues/brand'),method: 'get',params: this.$http.adornParams()}).then(({data}) => {if (data && data.code === 0) {this.carBrandAll = data.dict}})},
表单项通过插槽拿到对应brand的值(key)到carBrandAll对象里找到对应的 lable(value)l实现页面展示值
<el-table-columnprop="brand"header-align="center"align="center"width="80"label="品牌"><template slot-scope="scope"><span>{{ carBrandAll[scope.row.brand] }}</span></template></el-table-column>
3.传入code,value值,获取这个字典中对应的字典name值(在这里和选择器一起使用过程中没用到,就不过多讲。)
/*** 传入code,value值,获取这个字典中对应的字典name值* @return*/@GetMapping("/getAllDictNameByValue")public R getAllDictNameByValue(@RequestParam Map<String, Object> params){String code = (String)params.get("code");String value = (String)params.get("value");if (StringUtils.isNotBlank(code) &&StringUtils.isNotBlank( value) ) {QueryWrapper<SysDictEntity> queryWrapper = new QueryWrapper<>();queryWrapper.eq("type", 2);queryWrapper.eq("code", code);queryWrapper.eq("value", value);queryWrapper.last("limit 1");SysDictEntity sysDict = sysDictService.getOne(queryWrapper);return R.ok().put("name", sysDict.getName());}return R.error();}
总结:字典不光可以和选择器一起使用,单选框、多选框这些都可以看作key-value的形式,下次在讲解字典和其他组件使用。