一、项目应用场景
最初需求:单纯要求封装【查询名称】的弹窗组件,能够进行勾选,名称展示到页面搜索条件的搜索框内。
实际考虑:在名称过多的情况下,用户不可能一页页点击table列表页码去查找对应的名称,如果能够直接搜索到想要的名称进行勾选,肯定能更好的提升用户体验。
二、代码实现
第一步:封装查询名称弹窗组件
<el-dialog
width=“70%”
title=“名称查询”
append-to-body
class=“search-name”
:visible.sync=“dialogVisible”
:before-close=“closeDialog”
<div class="search-box">
<div class="search-box-input">
<span>名称:</span>
<el-input
clearable
placeholder="请输入"
v-model.trim="Name"
></el-input>
</div>
<el-button type="primary" class="search-btn" @click="handQuery">
查 询
</el-button>
</div>
<div class="tree-box" ref="treeBox" @scroll="handleScroll">
<el-table
:data="treedata"
border
ref="multipleTable"
:row-style="rowStyle"
:cell-style="cellStyle"
@selection-change="handleChangeSelection"
empty-text="暂无数据"
>
<el-table-column
type="selection"
width="55"
align="center"
></el-table-column>
<el-table-column
type="index"
label="序号"
width="85"
align="center"
:index="(index) => indexrank(index, this.pagenumber, this.pagesize)"
></el-table-column>
<el-table-column
property="name"
label="名称"
align="center"
></el-table-column>
</el-table>
</div>
<div class="list-pagination">
<Paging
ref="refPaging"
:total="parseInt(palnTotal)"
:pagesize="parseInt(pagesize)"
@pageNumChange="pageNumChange"
></Paging>
</div>
<div slot="footer">
<el-button @click="submitVal" type="primary" class="submit-btn">
确 认
</el-button>
<el-button @click="closeDialog()" class="cancel-btn">取 消</el-button>
</div>
export default {
props: {
dialogVisible: {
type: [Boolean],
default: false,
},
// 重置时清空选中数据
resetData: {
type: Array,
default: [],
},
},
components: {
Paging,
},
data() {
return {
stopReBack: false, // 防止回显成功前对表格进行操作的标识
scrollTop: 0,
palnTotal: 0,
Name: ‘’,
treedata: [],
pagesize: 10,
pagenumber: 1,
checkData: [], // 选中的名称集合
rowStyle: { height: ‘32px’ },
cellStyle: { padding: ‘8px’ },
};
},
watch: {
dialogVisible(val) {
if (val) {
this.KaTeX parse error: Expected '}', got 'EOF' at end of input: … this.refs.refPaging.pageChange(1);
});
}
},
resetData(val) {
this.checkData = val;
},
},
methods: {
clearInfo() {
this.Name = ‘’;
},
// 手动搜索
handQuery() {
this.pagenumber = 1; // 重置页码
this.queryName();
},
// 获取名称
queryName() {
let para = {
pagesize: this.pagesize,
pagenumber: this.pagenumber,
Name: this.Name ? this.Name : ''
};
commonService.queryName(para).then((res) => {
if (res && res.code == 200) {
if (res.data) {
this.treedata = res.data.list;
this.stopReBack = true;
setTimeout(() => {
this.checkData.map((item) => {
const b = this.treedata.find(
(it) => item.id == it.id,
);
if (b) {
this.$refs.multipleTable.toggleRowSelection(b, true);
}
});
this.stopReBack = false;
}, 50);
this.Total = res.data.total;
}
} else {
this.$message.error(res.message);
}
});
},
pageNumChange(val) {
this.pagenumber = val;
this.queryName();
},
// 选择方法
handleChangeSelection(value) {
if (this.stopReBack) {
return false;
}
const userList = JSON.parse(JSON.stringify(this.treedata)); //当前页、接口返回的数组
const selected = []; // 当前页选中数据
const unSelected = []; // 当前页未选中数据
// 遍历当前页数据,查找选中数据,分别放置不同的数组中
userList.map((item) => {
const b = value.find((it) => item.id == it.id);
b ? selected.push(item) : unSelected.push(item);
});
// 当前页选中数据selected遍历,在全部选中数据匹配查找,全部选中数据checkData中没有的信息,就塞入
selected.map((item) => {
const b = this.checkData.find((it) => item.id == it.id);
if (!b) {
this.checkData.push(item);
}
});
// 当前页未选中数据unSelected遍历,在全部选中数据匹配查找,全部选中数据checkData中有的信息,就删除
unSelected.map((item) => {
this.checkData.map((it, index) => {
if (item.id == it.id) {
this.checkData.splice(index, 1);
}
});
});
},
// 确认选中的,回显在父组件输入框
submitVal() {
if (this.checkData.length === 0) {
this.$message.error('请选择名称!');
return false;
} else {
this.$emit('getData', this.checkData);
this.closeDialog();
}
},
// 关闭弹窗
closeDialog() {
this.$emit('close');
},
// 弹窗高度
handleScroll() {
this.scrollTop = this.$refs.treeBox.scrollTop;
},
},
};
第二步:组件应用
<NameDialog
:resetData=“resetData” // 页面中点击重置按钮时,要清空弹窗中全选中数据
:dialogVisible=“dialogVisible”
@getData=“getData”
@close=“closeDialog”
第三步:组件方法
三、总结
1.名称组件封装,关注每次【打开弹窗】或点击【重置】按钮时,组件中接口查询或者页面展示数据的清除问题;
2.需求存在多级联动,例:省、市、区这种情况下更需要注意。