feat: 添加ehsselect组件

This commit is contained in:
caoqianming 2024-08-01 13:44:32 +08:00
parent 80b90d7d03
commit d101916362
5 changed files with 312 additions and 3 deletions

View File

@ -0,0 +1,78 @@
<template>
<div class="sc-select">
<div v-if="initloading" class="sc-select-loading">
<el-icon class="is-loading"><el-icon-loading /></el-icon>
</div>
<el-select v-bind="$attrs" :loading="loading" @visible-change="visibleChange" :value-on-clear="null">
<el-option v-for="item in options" :key="item[id]" :label="item[name]" :value="objValueType ? item : item[id]">
<slot name="option" :data="item"></slot>
</el-option>
</el-select>
</div>
</template>
<script>
export default {
props: {
apiObj: { type: Object, default: () => {} },
objValueType: { type: Boolean, default: false },
params: { type: Object, default: () => ({}) },
id: {type: String, default: 'id'},
name: {type: String, default: 'name'},
showName: {type: String, default: null},
},
data() {
return {
loading: false,
options: [],
initloading: false
}
},
created() {
//options
if(this.hasValue()){
this.initloading = true
this.getRemoteData()
}
},
methods: {
//
visibleChange(ispoen){
if(ispoen && this.options.length==0 && this.apiObj){
this.getRemoteData()
}
},
//
async getRemoteData(){
this.loading = true
var query = Object.assign({page:0}, this.params)
var res = await this.apiObj.req(query)
this.loading = false
this.initloading = false
if (this.$attrs.modelValue !== null && !res.some(option => option[this.id] === this.$attrs.modelValue)) {
this.options = [{ [this.id]: this.$attrs.modelValue, [this.name]: this.showName }, ...res];
}else{
this.options = res
}
},
//
hasValue(){
if(Array.isArray(this.$attrs.modelValue) && this.$attrs.modelValue.length <= 0){
return false
}else if(this.$attrs.modelValue){
return true
}else{
return false
}
}
}
}
</script>
<style scoped>
.sc-select {display: inline-block;position: relative;min-width: 120px;}
.sc-select-loading {position: absolute;top:0;left:0;right:0;bottom:0;background: #fff;z-index: 100;border-radius: 5px;border: 1px solid #EBEEF5;display: flex;align-items: center;padding-left:10px;}
.sc-select-loading i {font-size: 14px;}
.dark .sc-select-loading {background: var(--el-bg-color-overlay);border-color: var(--el-border-color-light);}
</style>

View File

@ -0,0 +1,225 @@
<template>
<el-select style="width: 200px" ref="select" v-model="defaultValue" :size="size" :clearable="clearable" :multiple="multiple" :collapse-tags="collapseTags" :collapse-tags-tooltip="collapseTagsTooltip" :filterable="filterable" :placeholder="placeholder" :disabled="disabled" :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" :data="tableData" :height="245" :highlight-current-row="!multiple" @row-click="click" @select="select" @select-all="selectAll">
<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" v-model:currentPage="currentPage" @current-change="reload"></el-pagination>
</div>
</div>
</template>
</el-select>
</template>
<script>
import config from "@/config/tableSelect";
export default {
props: {
modelValue: null,
apiObj: { type: Object, default: () => {} },
params: { type: Object, default: () => {} },
placeholder: { type: String, default: "请选择" },
size: { type: String, default: "default" },
clearable: { type: Boolean, default: false },
multiple: { type: Boolean, default: false },
filterable: { type: Boolean, default: false },
collapseTags: { type: Boolean, default: false },
collapseTagsTooltip: { type: Boolean, default: false },
disabled: { type: Boolean, default: false },
tableWidth: {type: Number, default: 400},
mode: { type: String, default: "popover" },
props: { 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: {}
}
},
computed: {
},
watch: {
modelValue:{
handler(){
this.defaultValue = this.modelValue
this.autoCurrentLabel()
},
deep: true
}
},
mounted() {
this.defaultProps = Object.assign(this.defaultProps, this.props);
this.defaultValue = this.modelValue
this.autoCurrentLabel()
},
methods: {
//
visibleChange(visible){
if(visible){
this.currentPage = 1
this.keyword = null
this.formData = {}
this.getData()
}else{
this.autoCurrentLabel()
}
},
//
async getData(){
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.apiObj.req(reqData);
var parseData = config.parseData(res)
this.tableData = parseData.rows;
this.total = parseData.total;
this.loading = false;
//
this.$nextTick(() => {
if(this.multiple){
this.defaultValue.forEach(row => {
var setrow = this.tableData.filter(item => item[this.defaultProps.value]===row[this.defaultProps.value] )
if(setrow.length > 0){
this.$refs.table.toggleRowSelection(setrow[0], true);
}
})
}else{
var setrow = this.tableData.filter(item => item[this.defaultProps.value]===this.defaultValue[this.defaultProps.value] )
this.$refs.table.setCurrentRow(setrow[0]);
}
this.$refs.table.setScrollTop(0)
})
},
//
formSubmit(){
this.currentPage = 1
this.keyword = null
this.getData()
},
//
reload(){
this.getData()
},
//options
autoCurrentLabel(){
this.$nextTick(() => {
if(this.multiple){
this.$refs.select.selected.forEach(item => {
item.currentLabel = item.value[this.defaultProps.label]
})
}else{
this.$refs.select.selectedLabel = this.defaultValue[this.defaultProps.label]
}
})
},
//
select(rows, row){
var isSelect = rows.length && rows.indexOf(row) !== -1
if(isSelect){
this.defaultValue.push(row)
}else{
this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
}
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
},
//
selectAll(rows){
var isAllSelect = rows.length > 0
if(isAllSelect){
rows.forEach(row => {
var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
if(!isHas){
this.defaultValue.push(row)
}
})
}else{
this.tableData.forEach(row => {
var isHas = this.defaultValue.find(item => item[this.defaultProps.value] == row[this.defaultProps.value])
if(isHas){
this.defaultValue.splice(this.defaultValue.findIndex(item => item[this.defaultProps.value] == row[this.defaultProps.value]), 1)
}
})
}
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
},
click(row){
if(this.multiple){
//
}else{
this.defaultValue = row
this.$refs.select.blur()
this.autoCurrentLabel()
this.$emit('update:modelValue', this.defaultValue);
this.$emit('change', this.defaultValue);
}
},
//tags
removeTag(tag){
var row = this.findRowByKey(tag[this.defaultProps.value])
this.$refs.table.toggleRowSelection(row, false);
this.$emit('update:modelValue', this.defaultValue);
},
//
clear(){
this.$emit('update:modelValue', 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();
}
}
}
</script>
<style scoped>
.sc-table-select__table {padding:4px;}
.sc-table-select__page {padding-top: 4px;}
</style>

View File

@ -14,10 +14,10 @@ export default {
request: { request: {
page: 'page', //规定当前分页字段 page: 'page', //规定当前分页字段
pageSize: 'page_size', //规定一页条数字段 pageSize: 'page_size', //规定一页条数字段
keyword: 'keyword' //规定搜索字段 keyword: 'search' //规定搜索字段
}, },
props: { props: {
label: 'label', //映射label显示字段 label: 'name', //映射label显示字段
value: 'value', //映射value值字段 value: 'id', //映射value值字段
} }
} }

View File

@ -1,8 +1,12 @@
import ehsUserSelect from './components/ehsSelect/userselect' import ehsUserSelect from './components/ehsSelect/userselect'
import ehsEpSelect from './components/ehsSelect/epselect' import ehsEpSelect from './components/ehsSelect/epselect'
import ehsSelect from './components/ehsSelect/select'
import ehsTableSelect from './components/ehsSelect/tableSelect'
export default { export default {
install(app) { install(app) {
app.component('ehsUserSelect', ehsUserSelect); app.component('ehsUserSelect', ehsUserSelect);
app.component('ehsEpSelect', ehsEpSelect); app.component('ehsEpSelect', ehsEpSelect);
app.component('ehsSelect', ehsSelect);
app.component('ehsTableSelect', ehsTableSelect);
} }
} }

View File

@ -21,6 +21,7 @@ import scForm from './components/scForm'
import scTitle from './components/scTitle' import scTitle from './components/scTitle'
import scWaterMark from './components/scWaterMark' import scWaterMark from './components/scWaterMark'
import scQrCode from './components/scQrCode' import scQrCode from './components/scQrCode'
import scIconSelect from './components/scIconSelect'
import scStatusIndicator from './components/scMini/scStatusIndicator' import scStatusIndicator from './components/scMini/scStatusIndicator'
import scTrend from './components/scMini/scTrend' import scTrend from './components/scMini/scTrend'
@ -68,6 +69,7 @@ export default {
app.component('scUserSelect', scUserSelect); app.component('scUserSelect', scUserSelect);
app.component('scTrend', scTrend); app.component('scTrend', scTrend);
app.component('scFire', scFire); app.component('scFire', scFire);
app.component('scIconSelect', scIconSelect);
//注册全局指令 //注册全局指令
app.directive('auth', auth) app.directive('auth', auth)