<template v-slot>
<el-select
ref="selectLazyLoad"
v-model="currentFieldInfo"
v-selectLazyLoad:pageNum="loadMoreData(pageNum)"
class="w-100"
:loading="loading"
filterable
:multiple="fieldInfo.fieldType === 'multipleSelection'"
clearable
remote
:remote-method="onSearch"
:placeholder="fieldInfo.fieldName"
empty-text="暂无数据"
no-data-text="无匹配数据"
no-match-text="无匹配数据"
@visible-change="onChangeVisible"
@clear="clearSelect"
@focus="focusSelect"
>
<el-option v-for="item in fieldOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
<script>
import Vue from 'vue'
import { getOptPageList } from '@/api/problemManage/problemManage.js'
import { throttleFirstExt } from '@/utils/common'
export default {
name: 'SelectLazyLoad',
props: {
fieldInfo: {
type: Object,
default: () => { }
},
fieldValue: {
type: Object,
default: () => { }
},
categoryCode: {// 分类编码(问题分类编码、工单分类编码)
type: String,
default: () => ''
}
},
data() {
return {
fieldOptions: [],
pageNum: 1,
currentFieldInfo: '',
allowSearchFlag: true, // 是否允许检索, 防止连续输入时未组装好数据就再次检索
page: {
// 查询后端所用参数对象, 可根据自己需求变更请求参数对象
page: 1,
limit: 20
},
queryParam: {
factoryId: '',
fieldCode: '',
fieldValue: '',
param: {
code: ''
}
},
inputValue: '',
loading: false,
noMoreData: false
}
},
computed: {
getFieldInfo() {
// 父组件用来筛选fieldCode
return this.fieldInfo
}
},
watch: {
currentFieldInfo: {
// 选中数据改变时,调用父组件的setBranchNumber方法,并传入选中的值
handler(val) {
if (val) {
this.$emit('update:fieldValueInfo', this.currentFieldInfo)
this.$emit('setFieldInfo')
} else {
this.$emit('update:fieldValueInfo', '')
this.$emit('setFieldInfo')
}
}
},
pageNum: {
// 当前页数改变时, 重新触发查询
handler(val) {
if (val) {
this.page.page = val
this.queryBranchData('', true)
}
}
}
},
created() {
// 组件实例创建后(data和methods已经初始化完毕), 请求后端数据
this.queryBranchData()
this.selectLazyLoad()
},
mounted() {
// 为了使父组件获取到fieldIndex属性
this.$emit('setFieldInfo')
// 添加下拉图标
const rulesDom = this.$refs['selectLazyLoad'].$el.querySelector(
'.el-input .el-input__suffix .el-input__suffix-inner .el-input__icon'
) // 找到dom
rulesDom.classList.add('el-icon-arrow-up')
},
methods: {
loadMoreData() {
// 数据到底部继续滑动,会自动触发页数+1
return () => {
this.pageNum += 1
}
},
onSearch(val) {
// 检索功能, 后端可以支持模糊检索
this.fieldOptions = []
if (
this.fieldInfo.fieldType === 'radioSelection' &&
val &&
this.$refs.selectLazyLoad.selectedLabel === val
) {
if (this.allowSearchFlag && val.length > 0) {
// 输入超过两个字符进行检索
// this.allowSearchFlag = false;
this.pageNum = 1
this.queryParam.fieldValue = val
this.queryBranchData()
}
} else if (this.fieldInfo.fieldType === 'multipleSelection' && val) {
this.pageNum = 1
this.queryParam.fieldValue = val
this.queryBranchData()
} else {
this.initData()
}
},
queryBranchData: throttleFirstExt(function(param, appendFlag) {
if (
this.fieldInfo.fieldType === 'radioSelection' &&
this.$refs.selectLazyLoad &&
this.$refs.selectLazyLoad.selectedLabel !== this.queryParam.fieldValue
) {
this.queryParam.fieldValue = ''
}
this.queryParam.fieldCode = this.fieldInfo.fieldCode
this.queryParam.param.code = this.categoryCode
if (!this.noMoreData) {
getOptPageList(this.queryParam, this.page).then((response) => {
this.noMoreData = !response.data.data.length
response.data.data.forEach((item) => {
this.fieldOptions.push({
label: item.fieldValue,
value: item.fieldValue
})
})
})
}
}, 200),
initData() {
this.noMoreData = false
this.pageNum = 1
this.queryParam.fieldValue = ''
this.fieldOptions = []
this.queryBranchData()
},
clearSelect() {
// 清空下拉框选中的值,会向后端重新查询第一页的数据
this.initData()
},
focusSelect() {
// 光标触发下拉框时,如果下拉框数据为空,则向后端查询第一页数据
if (this.fieldOptions.join() === '') {
this.initData()
}
},
onChangeVisible(val) {
if (val) {
this.initData()
} else {
this.noMoreData = false
this.pageNum = 1
this.queryParam.fieldValue = ''
this.fieldOptions = []
}
const rulesDom = this.$refs['selectLazyLoad'].$el.querySelector(
'.el-input .el-input__suffix .el-input__suffix-inner .el-input__icon'
) // 找到dom
if (val) {
rulesDom.classList.add('is-reverse') // 对dom新增class
} else {
rulesDom.classList.remove('is-reverse') // 对dom新增class
}
},
getFactoryId(factoryId) {
this.queryParam.factoryId = factoryId
},
selectLazyLoad() {
// el-select组件数据过多,使用翻页加载数据指令
Vue.directive('selectLazyLoad', {
bind(el, binding) {
const SELECT_WRAP_DOM = el.querySelector(
'.el-select-dropdown .el-select-dropdown__wrap'
)
SELECT_WRAP_DOM.addEventListener('scroll', function() {
// toFixed:把this.scrollTop转换为整数,兼容不同版本浏览器
const condition =
this.scrollHeight - this.scrollTop <= this.clientHeight
if (condition) binding.value()
})
}
})
},
// 父组件调用回显fieldValue
echoData(fieldInfo) {
if (fieldInfo.fieldValue) {
this.currentFieldInfo = fieldInfo.fieldValue
} else {
this.currentFieldInfo = null
}
}
}
}
</script>
<style scoped>
.w-100 {
width: 100%;
}
</style>