字典表
前端页面显示
依据这个字典表实现动态查询
初始化数组
首先先在全局变量里定义一个数据存放查询出来的数据
data() {
return {
dicts: []
};
},
生命周期
查询的时候是声明周期开始的时候,原本增删改查页面在生命周期开始的时候就查询了页面的数据获得了列表值,此时在生命周期开始也要查询字典的数据值
activated() {
this.getDataList();
// 获取所有的"性别
this.getDicts("sex");
},
查询符合条件的字典数据项getDicts()
getDicts()
方法在methods内写,类似于查询方法,先向后端发送一个请求,查询字典数据项,查到之后如果符合数据不为空不为null不是undefined类型且code恒等于0,就进行数据的查询放入上面定义的空数组,否则数组还是为空
getDicts(code) {
this.$http({
url: this.$http.adornUrl("/sys/dict/select"),
method: "get",
params: this.$http.adornParams({
code: code,
}),
}).then(({ data }) => {
if (data && data.code === 0) {
this.dicts = data.list;
})
} else {
this.dicts = [];
}
// this.dicts = data && data.code === 0 ? data.list : [];
});
},
这里code不定义值,可以在生命周期内写形参,让code和形参相等的时候查询到对应的数据库数据
下拉框
在表单选项内写下拉框组件el-select
,和性别双向绑定,加上清除,可以点叉叉一键清除下拉框内数据,el-option
内写法就是先遍历dicts数组,因为上面已经查询到数据了,v-for遍历查询item
- key:相当于身份令牌,唯一的令牌,防止出错。这个key没有也行,但是保险起见最好加上。因为这个key作为 value 唯一标识的键名,绑定值为对象类型时必填。
- label :这是给用户看的,当点击下拉菜单时,会出来选项,用户看到的选项就是这个
- value :这是你点击某个label(option)之后,将对应的值给v-model绑定的值model
这里都写item.name
是因为数据库内字典表的name是需要填入的值也是需要显示的值
<el-form-item>
<el-select v-model="dataForm.sex" placeholder="请选择筛选条件" clearable>
<el-option v-for="item in dicts" :key="item.value" :label="item.name" :value="item.name" ></el-option>
</el-select>
</el-form-item>
至此,前端已书写完毕,要接着写后端的查询方法
查询方法写在字典service层中
先写一个查询接口方法
写一个通用的接口,先在service层里写一个自定义根据传入的code查找方法,查找到的数据放入集合
List<SysDictEntity> select(String code);
在实现层实现接口方法
再在实现类中重写这个方法,创建一个高级查询对象,根据这个对象的查询条件,需要数据库字典表type字段值为2,code字段值是code的数据,最后在接口中调用service的方法并且传入code值放入list集合,返回响应前端
此时code值没有传入,不知道code值是什么,需要在前端启动的时候就传入
在方法内写一个根据code值发送请求查找数据
需要在前端启动的时候就传入,所以要在生命周期内调用,此时就可以传入相对应的形参
下面写一个伪代码,可根据伪代码进行相应书写
public 类型 方法名(){
创建一个wrapper对象
给这个对象加上查询条件,在条件里写对字段的限制
返回basemapper里的查询方法(17)用这个查询方法查询wrapper对象
}
对应写出来的代码如下
@Override
public List<SysDictEntity> select(String code) {
QueryWrapper<SysDictEntity> sdeqw = new QueryWrapper<>();
sdeqw.eq("type","2")
//性别 男女保密
//code和数据库内的值相等的
.eq("code",code);
return this.baseMapper.selectList(sdeqw);
}
最后在controller层内写查询方法
@GetMapping("/select")
public R select(String code){
List<SysDictEntity> list = sysDictService.select(code);
return R.ok().put("list",list);
}
至此,前后端的字典查询都写好啦
拓展:通常数据库内性别都是数字来表示的,如何根据数字在页面上显示字典项的汉字呢?
user表的sex字段值和dict表的value字段值相等且dict表的code字段值和user表的sex字段名相等的时候在前端页面展示sex字段值的地方要展示dict表value字段值对应的name字段值
此时有两种处理方法,一是在后端处理,查询的时候就进行集合一对一,二是在前端处理,数据传过来之后放进一个集合,最后一对一
后端处理:查询的时候就要显示 所以在分页查询内写
1.查询出code值为sex的数据放入list
2.dict中的name和value是一一对应关系,所以用map集合存放较好
3.遍历上面有数据的list集合,键为dict的value值,值是name,因为键找值快
4.由于是分页查询,在写这个性别处理的时候上面已经写好分页查询了,所以可以直接用page,获取记录,page.getRecords=分页查询结果集,遍历结果集对每一个元素先获取当前元素对象的sex字段值,再从map集合里找这个对应的值,最后将找到的值映射到当前对象的sex字段上
@Override
/*返回PageUtils工具类对象*/
public PageUtils queryPage(Map<String, Object> params) {
String username = (String) params.get("username");
String sex = (String) params.get("sex");
String start=(String) params.get("start");
String end=(String) params.get("end");
QueryWrapper<User> qw = new QueryWrapper<>();
/*like-模糊查询*/
qw.like(StringUtils.isNotBlank(username),"username",username)
.eq(StringUtils.isNotBlank(sex),"sex",sex);
if (StringUtils.isNotBlank(start) && StringUtils.isNotBlank(end)) {
qw.between("birthday",start,end);
}
/*分页查询*/
IPage<User> page=this.page(new Query<User>().getPage(params),qw);
//1.查询出code值为sex的数据放入list
List<SysDictEntity> list = sysDictService.select("sex");
//2.dict中的name和value是一一对应关系,所以用map集合存放较好
HashMap<String, String> sexMap = new HashMap<>();
//3.遍历上面有数据的list集合,键为dict的value值,值是name,因为键找值快
list.forEach(dict->{
sexMap.put(dict.getValue(),dict.getName());
});
//4.由于是分页查询,在写这个性别处理的时候上面已经写好分页查询了,所以可以直接用page,获取记录,page.getRecords=分页查询结果集,遍历结果集对每一个元素
page.getRecords().forEach(val->{
// 先获取当前元素对象的sex字段值,再从map集合里找这个对应的值,最后将找到的值映射到当前对象的sex字段上
val.setSex(sexMap.get(val.getSex()));
});
return new PageUtils(page);
}
前端处理
1.同样要一个集合来存放一一对应关系数据,在全局变量内声明一个集合{}
data() {
return {
sexMap:{}
};
},
2.获取字典数据之后dicts内有所有需要的性别数据了,遍历这个dicts数组,存放键值value和name
this.dicts.forEach(dict=>{
this.$set(this.sexMap,dict.value,dict.name)
})
3.在表单项数据内要获取一行的性别数据替换为集合内的name(value=sex),需要使用到插槽,在el-table-column中占一个位置,等待操作往里面填值,这里填的值就是集合中获取的name替换这一行插槽的性别数据
先在 el-table-column 中占一个位置,等待操作往里面填值
<el-table-column
prop="sex"
header-align="center"
align="center"
label="性别"
>
<template slot-scope="scope">
{{ sexMap[scope.row.sex] }}
</template>
</el-table-column>
4.由于数据库内sex由字符串改为了数字,所以需要在上面下拉框的value属性进行更改,此时value应该输入item.value
<el-form-item>
<el-select v-model="dataForm.sex" placeholder="请选择筛选条件" clearable>
<el-option v-for="item in dicts" :key="item.value" :label="item.name" :value="item.value" ></el-option>
</el-select>
</el-form-item>
在同一页面多个字典的使用
前端处理
首先新建一个全局变量来存放新的字典项的值,步骤和上面一样,只是更换了字典项的存放点,在大部分代码都相同的情况下可以使用流程控制语句
,根据传入不同的形参执行不同的方法
新建一个全局变量
data() {
dicts: [],
sexMap:{},
positionDicts:[],
positionMap: {}
};
},
activated() {
this.getDataList();
// 获取所有的性别
this.getDicts("sex");
// 获取所有的职位
this.getDicts("position");
},
流程控制语句传入不同的形参
methods: {
getDicts(code) {
this.$http({
url: this.$http.adornUrl("/sys/dict/select"),
method: "get",
params: this.$http.adornParams({
code: code,
}),
}).then(({ data }) => {
if (data && data.code === 0) {
if (code === 'sex') {
this.dicts = data.list;
// console.log(this.dicts);
this.dicts.forEach(dict=>{
this.$set(this.sexMap,dict.value,dict.name)
})
}
if (code === 'position') {
this.positionDicts = data.list;
// console.log(this.dicts);
this.positionDicts.forEach(dict=>{
this.$set(this.positionMap,dict.value,dict.name)
})
}
} else {
if (code === 'sex') {
this.dicts = [];
}
if (code === 'position') {
this.positionDicts = [];
}
}
});
},
列表使用插槽
<el-table-column
prop="sex"
header-align="center"
align="center"
label="性别"
>
<template slot-scope="scope">
{{ sexMap[scope.row.sex] }}
</template>
</el-table-column>
<el-table-column
prop="position"
header-align="center"
align="center"
label="职位"
>
<template slot-scope="scope">
{{ positionMap[scope.row.position] }}
</template>
</el-table-column>