一:前言
二:正文
1:示例展示
单选
多选
index.vue
<template> <el-select ref="select" v-model="defaultValue" :title="isNeedTitle ? getTitle() : null" :clearable="false" :multiple="multiple" :filterable="false" :placeholder="placeholder" :disabled="disabled" :value-key="defaultProps.value" :filter-method="filterMethod" @remove-tag="removeTag" @visible-change="visibleChange" @clear="clear" > <template #empty> <div class="sc-table-select__table" :style="{ width: tableWidth + 'px' }" v-loading="loading" > <div class="sc-table-select__header"> <slot name="header" :form="formData" :submit="formSubmit"></slot> </div> <el-table ref="table" style="font-size: 16px" :data="tableData" :height="245" :highlight-current-row="!multiple" @row-click="rowClick" @select="select" @select-all="selectAll" reserve-selection > <el-table-column v-if="multiple" type="selection" width="45" ></el-table-column> <el-table-column v-else type="index" width="45"> <template #default="scope" ><span>{{ scope.$index + (currentPage - 1) * pageSize + 1 }}</span></template > </el-table-column> <slot></slot> </el-table> <div class="sc-table-select__page"> <el-pagination small background layout="prev, pager, next" :total="total" :page-size="pageSize" :current-page.sync="currentPage" @current-change="currentChange" ></el-pagination> </div> </div> </template> </el-select> </template> <script> import config from './tableSelect' export default { props: { value: { type: [String, Number, Array, Object], default: '' }, // Not Request,all Table Data tabularData: { type: Array, default: () => [] }, // 是否是需要请求 isNeedRequest: { type: Boolean, default: false }, // 数据value是否以逗号隔开 isDataJoin: { type: Boolean, default: true }, // 请求url requestUrl: { type: Function, default: Function }, params: { type: Object, default: () => {} }, placeholder: { type: String, default: '请选择' }, multiple: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, tableWidth: { type: Number, default: 400 }, mode: { type: String, default: 'popover' }, // 合并默认配置 props: { type: Object, default: () => {} }, // 合并默认配置 isNeedTitle: { type: Boolean, default: false }, // 是否需要数据过滤 isNeedDataFilter: { type: Boolean, default: false }, filterParam: { type: Object, default: () => {} } }, data() { return { loading: false, keyword: null, defaultValue: [], tableData: [], pageSize: config.pageSize, total: 0, currentPage: 1, defaultProps: { label: config.props.label, value: config.props.value, page: config.request.page, pageSize: config.request.pageSize, keyword: config.request.keyword }, formData: {}, // Not Request,Need Table Data tabularMap: {} } }, watch: { value: { handler() { this.$nextTick(() => { if (!this.isDataJoin) { if (this.multiple) { this.defaultValue = this.value || [] } else { this.defaultValue = this.value } } else { // 多选 if (this.multiple) { this.defaultValue = Array.isArray(this.value) ? this.value : this.value ? this.value.split(',') : [] this.defaultValue = (this.defaultValue || []).map(item => { return { [this.defaultProps.value]: item } }) } else { this.defaultValue = this.value ? { [this.defaultProps.value]: this.value } : '' } } this.findLabel() }) }, deep: true, immediate: true }, tabularData: { handler(val) { if (this.isNeedRequest) return this.$nextTick(() => { val.forEach(item => { this.tabularMap[item[this.defaultProps.value]] = item[this.defaultProps.label] }) this.findLabel() }) }, deep: true, immediate: true } }, created() { // bug,在这不能使用nextTick this.defaultProps = Object.assign(this.defaultProps, this.props) }, methods: { // 表格显示隐藏回调 visibleChange(visible) { if (visible) { this.currentPage = 1 this.keyword = null this.formData = {} this.getData() } else { this.findLabel() } }, // 获取表格数据 async getData() { if (this.isNeedRequest) { this.initTable() } else { this.initTabularData() } }, initTabularData() { // this.tableData = deepClone(this.tabularData) this.total = this.tabularData.length this.tableData = this.tabularData.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize) if (Object.keys(this.formData).length > 0) { const input = this.formData[this.defaultProps.label] if (input) { const arr = this.tabularData.filter((item) => { return String(item[this.defaultProps.label]).toLowerCase().match(input) }) this.total = arr.length this.tableData = arr.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize) } } // 表格默认赋值 this.$nextTick(() => { if (this.multiple) { this.defaultValue.forEach(row => { const arr = this.tableData.filter(item => item[this.defaultProps.value] === row[this.defaultProps.value]) if (arr.length > 0) { this.$refs.table.toggleRowSelection(arr[0], true) } }) } else { const arr = this.tableData.filter(item => item[this.defaultProps.value] === this.defaultValue[this.defaultProps.value]) this.$refs.table.setCurrentRow(arr[0]) } this.$refs.table.$el.querySelector('.el-table__body-wrapper').scrollTop = 0 }) }, async initTable() { this.loading = true var reqData = { [this.defaultProps.page]: this.currentPage, [this.defaultProps.pageSize]: this.pageSize, [this.defaultProps.keyword]: this.keyword } Object.assign(reqData, this.params, this.formData) var res = await this.requestUrl(reqData) var parseData = config.parseData(res) this.tableData = parseData.list this.total = parseData.total this.loading = false // 表格默认赋值 this.$nextTick(() => { if (this.multiple) { this.defaultValue.forEach((row) => { const arr = this.tableData.filter(item => item[this.defaultProps.value] === row[this.defaultProps.value]) if (arr.length > 0) { this.$refs.table.toggleRowSelection(arr[0], true) } }) } else { const arr = this.tableData.filter(item => item[this.defaultProps.value] === this.defaultValue[this.defaultProps.value]) this.$refs.table.setCurrentRow(arr[0]) } this.$refs.table.$el.querySelector('.el-table__body-wrapper').scrollTop = 0 }) }, // 插糟表单提交 formSubmit() { this.currentPage = 1 this.keyword = null this.getData() }, // 分页刷新表格 currentChange(val) { this.currentPage = val this.getData() }, // 赋值 findLabel() { this.$nextTick(() => { if (this.multiple) { this.$refs.select.selected.forEach((item) => { if (this.isNeedRequest) { item.currentLabel = item.value[this.defaultProps.label] } else { item.currentLabel = this.tabularMap[item.value[this.defaultProps.value]] } }) } else { if (this.isNeedRequest) { this.$refs.select.selectedLabel = this.defaultValue[this.defaultProps.label] || '' } else { this.$refs.select.selectedLabel = this.tabularMap[this.defaultValue[this.defaultProps.value]] || '' } } }) }, // 表格勾选事件 select(rows, row) { var isSelect = rows.length && rows.indexOf(row) !== -1 // tip:row属于rows里的数据,同一地址,所以可判断 if (isSelect) { // console.log(row, 'row') this.defaultValue.push(row) if (this.isNeedDataFilter) { var flag = false if (+row[this.filterParam.key] == this.filterParam.value) { flag = true } } this.dataFilter(flag) } else { this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] === row[this.defaultProps.value]), 1) } if (this.isDataJoin) { this.defaultValue = this.defaultValue.map(item => item[this.defaultProps.value]).join(',') } this.findLabel() this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) }, // 表格全选事件 selectAll(rows) { var isAllSelect = rows.length > 0 if (isAllSelect) { var flag = false rows.forEach(row => { var isHas = this.defaultValue.find(item => item[this.defaultProps.value] === row[this.defaultProps.value]) if (!isHas) { this.defaultValue.push(row) if (this.isNeedDataFilter) { if (+row[this.filterParam.key] == this.filterParam.value) { flag = true } } } }) this.dataFilter(flag) } else { this.tableData.forEach(row => { const index = this.defaultValue.findIndex(item => item[this.defaultProps.value] === row[this.defaultProps.value]) if (index !== -1) { this.defaultValue.splice(index, 1) } }) } if (this.isDataJoin) { this.defaultValue = this.defaultValue.map(item => item[this.defaultProps.value]).join(',') } this.findLabel() this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) }, async rowClick(row) { if (this.multiple) { // 处理多选点击行 this.$refs.table.toggleRowSelection(row) const isSelect = this.defaultValue.filter(item => item.bizid === row.bizid).length !== 0 let oldDefaultValue = [...this.defaultValue] || [] if (isSelect) oldDefaultValue = this.defaultValue.filter(item => item.bizid !== row.bizid) if (!isSelect) oldDefaultValue.push(row) this.select(oldDefaultValue || [], row) } else { this.defaultValue = '' this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) await this.$nextTick() this.defaultValue = row if (this.isDataJoin) { this.defaultValue = row[this.defaultProps.value] } this.$refs.select.blur() this.findLabel() this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) } }, // tags删除后回调 removeTag(tag) { var row = this.findRowByKey(tag[this.defaultProps.value]) this.$refs.table.toggleRowSelection(row, false) if (this.isDataJoin) { this.defaultValue = this.defaultValue.map(item => item[this.defaultProps.value]).join(',') } this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) }, // 清空后的回调 clear() { this.$emit('input', this.defaultValue) this.$emit('change', this.defaultValue) }, // 关键值查询表格数据行 findRowByKey(value) { return this.tableData.find(item => item[this.defaultProps.value] === value) }, filterMethod(keyword) { if (!keyword) { this.keyword = null return false } this.keyword = keyword this.getData() }, // 触发select隐藏 blur() { this.$refs.select.blur() }, // 触发select显示 focus() { this.$refs.select.focus() }, async getTitle() { try { await this.$nextTick() const title = [] if (!this.isNeedRequest) { const map = {} for (const item of this.tabularData) { map[item[this.defaultProps.value]] = item[this.defaultProps.label] } if (this.multiple) { for (const v of this.defaultValue || []) { title.push(map[v[[this.defaultProps.value]]]) } } else { return map[this.defaultValue[this.defaultProps.value]] || '' } } return title.length > 0 ? title.join(',') : '' } catch (error) { return '' } }, dataFilter(flag) { if (!this.isNeedRequest && this.multiple && this.isNeedDataFilter) { this.defaultValue = this.defaultValue.filter(v => { const tepArr = this.tabularData.filter(i => { if (flag) { return i[this.filterParam.key] != this.filterParam.value } else { return i[this.filterParam.key] == this.filterParam.value } }) const tepVal = tepArr.find(t => t[this.defaultProps.value] === v[this.defaultProps.value]) if (tepVal) { this.$refs.table.toggleRowSelection(tepVal, false) return false } return true }) } } } } </script> <style scoped> .sc-table-select__table { padding: 12px; } .sc-table-select__page { padding-top: 12px; } </style>
tableSelect.js
// 表格选择器配置 export default { pageSize: 20, // 表格每一页条数 parseData: function(res) { return { data: res.data, list: res.data.data.list, // 分析行数据字段结构 total: res.data.data.total, // 分析总数字段结构 msg: res.data.message, // 分析描述字段结构 code: res.data.code // 分析状态字段结构 } }, request: { page: 'page', // 规定当前分页字段 pageSize: 'pageSize', // 规定一页条数字段 keyword: 'keyword' // 规定搜索字段 }, props: { label: 'label', // 映射label显示字段 value: 'value' // 映射value值字段 } }
使用
<template> <!-- 单选用法 --> <YyTableSelect v-model="xxx" :props="props" :tabularData="table" :table-width="600" @change="change()"> <el-table-column prop="parameterName" label="参数名称"></el-table-column> <el-table-column prop="parameterScore" label="分值" width="180"></el-table-column> </YyTableSelect> <!-- 多选用法 --> <YyTableSelect v-model="value" :apiObj="apiObj" :table-width="700" multiple :props="props" @change="change" > <template #header="{ form, submit }"> <el-form :inline="true" :model="form"> <el-form-item> <el-select v-model="form.sex" placeholder="性别" clearable :teleported="false" > <el-option label="男" value="1"></el-option> <el-option label="女" value="2"></el-option> </el-select> </el-form-item> <el-form-item> <el-date-picker v-model="form.date" value-format="YYYY-MM-DD" type="date" placeholder="时间" :teleported="false" ></el-date-picker> </el-form-item> <el-form-item> <el-button type="primary" @click="submit">查询</el-button> </el-form-item> </el-form> </template> <el-table-column prop="id" label="ID" width="180"></el-table-column> </YyTableSelect> </template> <script> import YyTableSelect from '@/views/components/YyTableSelect' export default { components: { YyTableSelect }, data() { return { params: { name: '' }, value: [ { id: '1', user: 'xx' }, { id: '2', user: 'xx' } ], props: { label: 'label', value: 'value', keyword: 'keyword' } } }, computed: {}, mounted() {}, methods: { // 值变化 change(val) { console.log(val) } } } </script> <style scoped></style>
根据https://lolicode.gitee.io/scui-doc/demo/#/dashboard里的组件修改
标签:vue,default,defaultValue,value,defaultProps,item,ui,element,row From: https://www.cnblogs.com/ios9/p/18094751