示例
使用
# ------------------------使用---------------------------------------
<drop-down-selector v-model="value" :options="{placeholder:'单位名称',disabled: false,multiple: true,selection:true,key:'id',label: 'name',clearable: true,collapseTags: 5}" :request-fun="getList" :showField="[{prop:'name',label: '名称',width: '200'},{prop: 'sex',label: '性别'}]" :returnField="['id','name']" :page-option="{pageSizes: [1,2,3,4,5]}"></drop-down-selector>
组件 --------------drop-down-selector.vue------------
<!-- 下拉选择器组件分装 -->
<template>
<div>
<!-- :hide-on-click="!allOptions.multiple" -->
<el-dropdown class="drop_down_input" ref="selectDown" :class="[allOptions.size == 'mini'? 'el-input--mini':(allOptions.size == 'small'?'el-input--small':'el-input--medium')]" trigger="click" :disabled="allOptions.disabled || false" :placement="allOptions.placement || 'bottom-start'" @visible-change="toggleClick">
<!-- 选择框 -->
<div class=" el-input__inner select_wrap" :class="{clearBtn: multipleSelection.length > 0}">
<div class="input_left"></div>
<div class="input_center" :class="{'margin_right_position': allOptions.collapseTags && multipleSelection.length > allOptions.collapseTags}">
<template v-if="allOptions.collapseTags">
<el-tag v-for="(item,index) in multipleSelection.filter((it,idx) => {return idx < parseInt(allOptions.collapseTags)})" :key="index" closable type="danger" style="margin-right: 5px" @close="colseSelectItem(item,index)"> {{item[allOptions.label]}}</el-tag>
</template>
<template v-else>
<el-tag v-for="(item,index) in multipleSelection" :key="index" closable type="danger" style="margin-right: 5px" @close="colseSelectItem(item,index)"> {{item[allOptions.label]}} </el-tag>
</template>
</div>
<el-tag style="margin-right: 25px" v-if="allOptions.collapseTags && multipleSelection.length > allOptions.collapseTags">{{multipleSelection.length < 99? `+${multipleSelection.length}`: `99+`}}</el-tag>
<div class="el-input__suffix el-input__suffix-inner el-input__icon el-icon-arrow-down" :class="{'rotate_right': dropDownStatus}" @click.stop="clearAllSelect"></div>
</div>
<!-- 下拉框 -->
<el-dropdown-menu slot="dropdown" class="drop_down_box">
<el-row class="search_box">
<el-input :size="allOptions.size" v-model="keyword" :placeholder="`请输入${allOptions.placeholder || ''}`" @keydown.enter.native.stop="searchClick"></el-input>
<el-button type="primary" @click="searchClick">搜 索</el-button>
<el-button type="success">清 空</el-button>
</el-row>
<el-row>
<u-table :row-key="allOptions.key" :row-id="allOptions.key" :size="allOptions.size || 'mini'" ref="multipleTable" :height="initTableHeight" :data="tableData" :stripe="allOptions.stripe || true" :border="allOptions.border || true" :tooltip-effect="allOptions.tooltipEffect || 'dark'" style="width: 100%" selectTrClass="selectTr" :record-table-select="true" @selection-change="handleSelectionChange" @row-click="selectRow" :pagination-show="true" :total="allPage.total" :page-size="allPage.pageSize" :current-page="allPage.currentPage" :page-sizes="allPage.pageSizes ||[10,20,50,100,200,500]" @handlePageSize="handlePageSize">
<template slot="empty">
<el-empty description="暂无数据" :image-size="100" class="table_empty"></el-empty>
</template>
<u-table-column :reserve-selection="true" v-if="allOptions.multiple || false" type="selection" fixed></u-table-column>
<u-table-column v-for="(item,index) in showField" :key="index" :prop="item.prop" :label="item.label" :width="item.width" :show-overflow-tooltip="true" :fixed="item.fixed || false"></u-table-column>
</u-table>
</el-row>
</el-dropdown-menu>
</el-dropdown>
</div>
</template>
<script>
import { Input } from 'element-ui'
export default {
props: {
value: { type: String | Array, request: true },
options: { type: Object, default() { return {} } },
requestFun: { type: Function },
showField: { type: Array, request: true },
returnField: { type: Array, default() { return [] } },
pageOption: { type: Object, default() { return { total: 0, currentPage: 1, pageSize: 20 }}}
},
watch: {
value: {
handler(newValue, oldValue) {
console.log(newValue, 'newValue')
if (!newValue) return
newValue = this.conversionValue(newValue)
this.formateSelectData(newValue)
this.returnData()
},
deep: true,
immediate: true
}
},
computed: {
allOptions() {
return { size: 'mini', formatKey: 'String', ...this.options }
},
allPage() {
return {...this.page,...this.pageOption}
}
},
data() {
return {
table_height: '',
dropDownStatus: false,
keyword: "",
showcolumn: "",
search: {},
tableData: [{ id: 1, name: "张三", sex: "男" }, { id: 2, name: "李四", sex: "女" }],
tableData1: [{ id: 1, name: "张三", sex: "男" }, { id: 2, name: "李四", sex: "女" }, { id: 5, name: "张三", sex: "男" }, { id: 6, name: "张三", sex: "男" },],
tableData2: [{ id: 3, name: "3", sex: "女" }, { id: 4, name: "4", sex: "女" }, { id: 7, name: "张三", sex: "男" }, { id: 8, name: "张三", sex: "男" },],
page: {
total: 8,
currentPage: 1,
pageSize: 2,
},
initTableHeight: 0,
multipleSelection: []
}
},
methods: {
conversionValue(value) {
if (typeof value == 'string') {
value = value.split(',')
}
return value.map(item => { return String(item) })
},
selectRow(row, column, event) {
if (!this.allOptions.multiple) return;
console.log('点击某行', row, column, event)
this.$refs.multipleTable.toggleRowSelection([{ row: row }])
},
handleSelectionChange(val) {
console.log('监听事件多选返回子项对象数组:', val, this.allOptions)
this.multipleSelection = val;
let arr = this.multipleSelection.map(item => item[this.allOptions.key])
this.allOptions.formatKey == 'String' ? this.$emit('input', arr.join(',')) : this.$emit('input', arr)
},
returnData() {
if (!this.returnField.length) return { its: this.multipleSelection }
let obj = {}
this.returnField.forEach(item => {
this.multipleSelection.forEach(it => {
if (obj[item]) {
obj[item].push(it[item])
} else {
obj[item] = [it[item]]
}
})
})
obj.its = this.multipleSelection
console.log('处理返回的数据', obj)
},
async toggleClick(value) {
this.dropDownStatus = value
console.log(value)
},
formateSelectData(value) {
console.log('初始化默认选中的数据', value)
this.$nextTick(() => {
let arr = []
this.tableData.forEach(item => {
if (value.includes(String(item[this.allOptions.key]))) {
arr.push({ row: item, selected: true })
}
})
this.$refs.multipleTable.toggleRowSelection(arr)
})
},
clearAllSelect($event) {
let arr = this.multipleSelection.map(item => { return { row: item, selected: false } })
this.$refs.multipleTable.toggleRowSelection(arr)
},
colseSelectItem(item, index) {
console.log('关闭选中的标签', item, index)
this.multipleSelection.forEach(it => {
if (it[this.allOptions.key] == item[this.allOptions.key]) {
this.$refs.multipleTable.toggleRowSelection([{ row: it, selected: false }])
}
})
},
searchClick($event) {
console.log('搜索按钮点击事件: searchClick',';搜索条件值:',this.keyword)
$event.preventDefault()
this.$emit('searchClick', this.keyword)
},
handlePageSize({size, page}) {
console.log('触发的分页事件:handlePageSize;','传入的参数:',{size, page})
this.$emit('handlePageSize',{size, page})
this.page.currentPage = page
this.page.pageSize = size
if (page == 1) {
this.tableData = this.tableData1
} else {
this.tableData = this.tableData2
}
this.$refs.selectDown.show()
console.log('分页变化:', page)
},
resetClick() {
this.query = {}
this.onLoad()
},
},
created() { },
mounted() {
setTimeout(() => {
this.initTableHeight = 300
}, 500);
},
}
</script>
<style scoped lang="scss">
.drop_down_input {
width: 100%;
cursor: pointer;
&:hover {
}
.mini {
height: 28px;
}
.select_wrap {
padding: 3px;
display: flex;
align-items: center;
&.clearBtn:hover {
.el-icon-arrow-down::before {
content: "\e78d";
}
}
.input_left {
}
.input_center {
&.margin_right_position {margin-right: 3px;}
flex: 1;
margin-right: 25px;
scrollbar-width: none;
-ms-overflow-style: none;
line-height: 1.5;
white-space: nowrap;
overflow: auto;
}
.rotate_right {
transform: rotate(-180deg);
}
}
}
::-webkit-scrollbar {
display: none;
}
.drop_down_box {
padding: 0px;
min-width: 300px;
.el-button {
width: unset !important;
}
.search_box {
display: flex;
.el-button {
margin: 0;
}
}
}
/deep/ .avue-crud__menu {
display: none;
}
.table_empty {
padding: 0;
}
/deep/.el-table__empty-block {
height: 100%;
}
</style>
<style>
.selectTr td {
background: #d5e4f4 !important;
}
.myPagination {
padding: 0 !important;
}
</style>
配置