Antd+vue Input下拉Table表格
Antd+vue Input下拉Table表格
·
Antd+vue Input下拉Table表格
遇到需要下拉选择信息的需求,发现Select 展示信息不太友好,尝试Input标签触发展示一个Table表格
AInputTable 组件 使用文档
- 说明: 输入框支持展示Table表格,支持翻页,多属性展示,
- 点击选中可获取列全部属性值;
参数配置
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
placeholder | String | 输入框未填值展示提示信息 | |
disabled | Boolean | true/false 默认false | |
value | String | 绑定v-model或是v-decorator后不需要设置 | |
columns | Array | 表格列的配置描述,详见https://www.antdv.com/components/table-cn/#Column | |
url | string | table 数据源请求地址 查询需返回带分页的数据 | |
sorter | Object | 排序字段及排序方式 { column: this.sorter, order: ‘desc’ } | |
saveLabel | string | 选中实际保存字段 | |
showLabel | string | 选中输入框展示字段 | |
queryParams | string | queryParams 额外参数如:部门人员、类型等 后台逻辑需自己书写 | |
pageSize | string | 指定每页显示条数 | |
rowKey | string | 指定rowKey 默认id 没有id时指定 | |
scroll | string | 设置显示Table高度限制,超出指定高度 滚动展示 |
使用示例
<template>
<a-input-table :="tableAIdConfig" v-model="queryParam.tableAId" @getRecord="getRecord"></a-input-table>
</template>
<script>
import AInputTable from "@/components/assien/AInputTable";
export default {
name: "Test",
components: {
AInputTable,
},
data() {
return {
queryParam: {},
tableAIdConfig: [{
title: '序号',
width: 60,
align: "center",
dataIndex: 'no',
customRender: function (t, r, index) {
return parseInt(index) + 1
},
},{
title: '用户名称',
align: "center",
dataIndex: 'realname'
},{
title: '岗位',
align: "center",
dataIndex: 'post'
},{
title: '电话',
align: "center",
dataIndex: 'telephone',
},{
title: '邮箱',
align: "center",
ellipsis: true,
dataIndex: 'mail',
}],
}
},
methods: {
getRecord(record){
console.log(record)
},
}
}
</script>
<style scoped></style>
AInputTable.vue子组件
<!--下拉Table再探究 2.0-->
<template>
<div class="input-table" v-clickoutside="handleHide">
<div class="input-table-input" @click="disabled?this:handleShow()">
<a-input
:value="showValue"
:disabled="disabled"
class="select-table-input"
:placeholder="placeholder"
@change="inputValueChange"
>
<a-icon type="bars" style="color: rgba(0,0,0,.45)" slot="suffix" />
</a-input>
</div>
<div v-bind:class="getTableVisible" :style="tableDivStyle()">
<a-table
bordered
size="small"
:scroll="scroll"
:columns="columns"
:dataSource="dataSource"
:customRow="onCustomRow"
:pagination="ipagination"
@change="handleTableChange"
:rowKey="rowKey"
/>
</div>
</div>
</template>
<script>
import {getAction} from "../../api/manage";
import { filterObj } from '@/utils/util';
const clickoutside = {
// 初始化指令
bind(el, binding, vnode) {
function documentHandler(e) {
// 这里判断点击的元素是否是本身,是本身,则返回
if (el.contains(e.target)) {
return false
}
// 判断指令中是否绑定了函数
if (binding.expression) {
// 如果绑定了函数 则调用那个函数,此处binding.value就是handleHide方法
binding.value(e)
}
}
// 给当前元素绑定个私有变量,方便在unbind中可以解除事件监听
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler)
},
update() {
},
unbind(el, binding) {
// 解除事件监听
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__
}
};
export default {
name: 'AInputTable',
props: {
placeholder: {
type: String,
required: false,
default: ''
},
disabled: {
type: Boolean,
required: false,
default: false,
},
url: {
type: String,
required: false,
default: ''
},
columns: {
type: Array,
required: false,
default: () => [],
},
value: {
type: String,
required: false,
default: '',
},
saveLabel: {
type: String,
required: false,
default: 'id',
},
showLabel: {
type: String,
required: false,
default: 'name',
},
sorter: {
type: Object,
required: false,
default: ()=>{},
},
queryParams: {
type: Object,
required: false,
default: ()=>{},
},
pageSize: {
type: Number,
required: false,
default: 10,
},
rowKey: {
type: String,
required: false,
default: "id",
},
scroll: {
type: Object,
required: false,
default: function () {
return { x:200, y: 500 }
},
},
},
directives: {clickoutside},
data() {
return {
tableVisible: false,
//----- new -----
dataSource: [],
/* 分页参数 */
ipagination: {
current: 1,
pageSize: this.pageSize,
pageSizeOptions: ['5','10','15','20','30'],
showTotal: (total, range) => {
return range[0] + "-" + range[1] + " 共" + total + "条"
},
showSizeChanger: true,
total: 0
},
isorter: this.sorter,/* 排序参数 */
showValue:'',//展示值
saveValue:'',//保存值
record:{},
// 存储各个div的style
style: {
tableDiv:{
position: "absolute",
zIndex: "999",
backgroundColor: "#ffffff",
border:"#dedede 1px solid",
padding: "5"
},
},
}
},
created() {
},
computed: {
getTableVisible() {
if (this.tableVisible) {
return 'showTable';
} else {
return 'hideTable';
}
},
},
watch: {
value: {
immediate: true,
handler(val) {
if (val) {
this.saveValue = val;
this.queryShowValueBySaveValue();
} else {
this.saveValue = '';
this.showValue = '';
this.record = {};
this.$emit('getRecord',{});
this.loadData(1);
}
}
},
},
methods: {
loadData(arg) {
if(!this.url){
this.$message.error("AInputTable组件未指定请求url,请设置url属性!")
return
}
//加载数据 若传入参数1则加载第一页的内容
if (arg === 1) {
this.ipagination.current = 1;
}
var params = this.getQueryParams();//查询条件
getAction(this.url, params).then((res) => {
if (res.success) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
}
if(res.code===510){
this.$message.warning(res.message)
}
})
},
getQueryParams() {
let queryParam = {};
queryParam = {
[this.showLabel]:this.showValue,
};
if(this.queryParams){
Object.assign(queryParam,this.queryParams)
}
var param = Object.assign({}, queryParam, this.isorter ,this.filters);
param.field = this.getQueryField();
param.pageNo = this.ipagination.current;
param.pageSize = this.ipagination.pageSize;
return filterObj(param);
},
getQueryField() {
//TODO 字段权限控制
var str = "id,";
this.columns.forEach(function (value) {
str += "," + value.dataIndex;
});
return str;
},
handleHide() { // 点击除了页面其他地方关闭车型选择
this.tableVisible = false;
},
handleShow() {
this.$emit('click', this.saveValue);
this.loadData(1);
this.tableVisible = true;
},
onCustomRow(record) {
return {
props: {},
on: {
click: () => {
this.record = record;
this.saveValue = this.record[this.saveLabel];
this.showValue = this.record[this.showLabel];
this.$emit('select', this.saveValue);
this.$emit('input', this.saveValue);
this.$emit('change', this.saveValue);
this.$emit('getRecord',this.record);
this.handleHide();
},
},
};
},
inputValueChange(e) {
this.showValue = e.target.value;
this.$emit('inputChange',e.target.value);
if(this.showValue === null || this.showValue === undefined || this.showValue === ''){
this.clear();
}
debounce(()=>{this.loadData(1)}, 1000);
},
getShowValue(){
return this.showValue;
},
getSaveValue(){
return this.saveValue;
},
clear() {
this.saveValue = '';
this.showValue = '';
this.record = {};
this.$emit('select', '');
this.$emit('input', '');
this.$emit('change', '');
this.$emit('getRecord',{});
this.handleHide();
},
handleTableChange(pagination, filters, sorter) {
//分页、排序、筛选变化时触发
//TODO 筛选
if (Object.keys(sorter).length > 0) {
this.isorter.column = sorter.field;
this.isorter.order = "ascend" == sorter.order ? "asc" : "desc"
}
this.ipagination = pagination;
this.loadData();
},
queryShowValueBySaveValue(){
let queryParam = {
[this.saveLabel]:this.saveValue,
}
getAction(this.url, queryParam).then((res) => {
if (res.code == 200) {
this.dataSource = res.result.records;
this.ipagination.total = res.result.total;
this.dataSource.some((item) => {
if(item){
if(item[this.saveLabel] == this.saveValue){
this.showValue = item[this.showLabel];
this.record = item;
return true;
}
}
})
}else{
this.$message.warning(res.message)
}
})
},
tableDivStyle() {
let style = Object.assign({}, this.style.tableDiv)
let width1 = this.getDivTopLength();
let width2 = this.realTrWidth();
if(width1>width2){
style['width'] = width2+"px";
}else {
style['width'] = width1+"px";
}
return style
},
//table 列总宽度
realTrWidth() {
let calcWidth = 0
this.columns.forEach((column, i) => {
let { type, width } = column
// 隐藏字段不参与计算
if (typeof width === 'number') {
calcWidth += width
} else if (typeof width === 'string') {
width = width.replace("px","");
calcWidth += Number(width)
} else {
calcWidth += '120'
}
})
return calcWidth
},
//获取指定第v据屏幕右侧宽度
getDivTopLength() {
return 600;
},
},
//2.2新增 在组件内定义 指定父组件调用时候的传值属性和事件类型
model: {
prop: 'value',
event: 'input'
}
}
</script>
<style scoped lang="less">
.input-table {
.showTable {
display: block;
}
.hideTable {
display: none;
}
.select-table-input {
margin-right: 20px;
}
}
</style>
效果图
更多推荐
已为社区贡献4条内容
所有评论(0)