emis-app/components/tpx-select/tpx-select.vue
2024-06-20 21:23:41 +08:00

278 lines
6.9 KiB
Vue

<template>
<view @click.stop="handleRootClick" class="" style="position: relative;">
<view @click="handleSelectSwitch">
<slot v-if="$slots.default"></slot>
<template v-else>
<default-select-input v-if="selectTextType == 'input'" :placeholder="placeholder" :show="show"
:value="value" :list="filDataList" :checkedList="filDatacheckedList"
:isWhite="isWhite" :text="text" :customStyle="customStyle"
></default-select-input>
<DefaultSelectText v-if="selectTextType == 'text'"></DefaultSelectText>
</template>
</view>
<view v-if="mode == modeEnum.sheet">
<tpx-dialog :show="show" :title="placeholder" @onClose="handleSelectSwitch">
<view style="height: calc(60vh);">
<tpx-scroll-view :resObject="filResObject" :searchParam="filDataSearchParam" :getListFun="getListFun" size="sm" :showLoadedAll="false" @onListChange="onListChange">
<view v-if="showKeyWord" class="mb-10">
<tpx-input v-model:value="keyword" placeholder="请输入关键字" @change="handleKeyWordChange"></tpx-input>
</view>
<content-items :value="value" :list="filDataList" :checkedList="filDatacheckedList" :minChecked="minChecked" :type="type"
:text="text" :vdataType="vdataType" :transKeyVal="transKeyVal"
@onChange="handleDataItemChange"
></content-items>
</tpx-scroll-view>
</view>
</tpx-dialog>
</view>
<view v-if="mode == modeEnum.drop && show" class="md-drop-cont">
<tpx-scroll-view :maxHeight="dropMaxHeight" :resObject="filResObject" :searchParam="filDataSearchParam" :getListFun="getListFun" size="sm" :showLoadedAll="false" @onListChange="onListChange">
<view v-if="showKeyWord" class="mb-10">
<tpx-input v-model:value="keyword" placeholder="请输入关键字" @change="handleKeyWordChange"></tpx-input>
</view>
<content-items :value="value" :list="filDataList" :minChecked="minChecked" :type="type"
:text="text" :vdataType="vdataType" :transKeyVal="transKeyVal"
@onChange="handleDataItemChange"
></content-items>
</tpx-scroll-view>
<!-- 多选drop需要确认按钮 -->
<u-button v-if="type=='multiple'" @click="handleSelectSwitch" custom-style="margin:10rpx 0 40rpx 0;border-radius: 16rpx;height: 56rpx;font-size: 24rpx;" type="primary" plain="true">确定</u-button>
</view>
</view>
</template>
<script>
import ContentItems from "./content-items"
import DefaultSelectInput from "./default-select-input"
import DefaultSelectText from "./default-select-text"
import { transListKeyTitle } from "@/common/util"
import { pageEventNames } from "@/common/enum"
const modeEnum = {
sheet: 'sheet',
drop: 'drop'
}
const selectDropEventName = "selectDropEventName"
export default {
computed: {
filDataList() {
let list = (this.getListFun ? this.resObject.list : this.list) || []
if(this.transKeyVal) {
list = transListKeyTitle({ ...this.transKeyVal, list: list })
}
// if(!this.getListFun && this.keyword) {
// list = list.filter(t=> t.title?.indexOf?.(this.keyword) > -1)
// }
return list
},
filDataSearchParam() {
let filedName = this.searchFiledName
return {
...this.searchParam,
searchValue: this.keyword, // 默认
[filedName]: this.keyword,
}
},
filDatacheckedList() {
let list = (this.getListFun ? this.resObject.checkedList : this.checkedList)
if(Array.isArray(list) && this.transKeyVal) {
list = transListKeyTitle({ ...this.transKeyVal, list: list })
}
return list
},
filResObject() {
let res = this.getListFun ? this.resObject : { list: this.list, total: this.list.length }
return res
},
showKeyWord() {
// 查接口的列表才有搜索
let bl = !!this.getListFun
return bl
}
},
components: {
ContentItems, DefaultSelectInput, DefaultSelectText
},
props: {
isWhite: {
default () {
return false
}
},
customStyle: {
default () {
return ''
}
},
minChecked: {
default () {
return 1
}
},
type: {
default () {
return "single" // single | multiple
}
},
placeholder: {
default () {
return "请选择"
}
},
mode: {
default () {
return modeEnum.sheet
}
},
value: {
default () {
return ""
}
},
dropMaxHeight: {
default () {
return 400
}
},
list: {
default () {
return []
}
},
checkedList: {
},
searchParam: {
default () {
return {}
}
},
getListFun: {
default () {
return null
}
},
resObject: {
default () {
return {
list: []
}
}
},
transKeyVal: {
default () {
return null
// {
// // valKey: '',
// // titleKey: ''
// }
}
},
text: {
default () {
return ''
}
},
vdataType: {
default () {
return 'string' // string | array
}
},
disabled: {
default () {
return false
}
},
selectTextType: {
default () {
return 'input' // 选择框样式 input | text
}
},
},
data() {
return {
componentId: uni.$u.guid(20),
show: false,
modeEnum: Object.assign({}, modeEnum),
keyword: '',
// searchFiledName: this.transKeyVal?.['searchKey'] || '_searchValue',
searchFiledName: this.transKeyVal?.['titleKey'] || '_searchValue'
}
},
created() {
uni.$on(pageEventNames.globalClick, this.handleDocumentClick);
uni.$on(selectDropEventName, this.listenSelectDrop);
},
unmounted() {
uni.$off(pageEventNames.globalClick, this.handleDocumentClick);
uni.$off(selectDropEventName, this.listenSelectDrop);
},
methods: {
handleDocumentClick(){
this.show = false
},
listenSelectDrop(e) {
// 忽略当前组件发出的事件消息
if(e != this.componentId) {
this.show = false
}
},
handleSelectSwitch() {
if(this.disabled) {
return
}
// this.$emit('update:show', !this.show)
this.show = !this.show
},
handleDataItemChange(val, text, checkedList) {
this.$emit('onChange', val, text, checkedList)
this.$emit('update:value', val)
this.$emit('update:text', text)
this.$emit('update:checkedList', checkedList)
if(this.resObject) {
this.$emit('update:resObject', {
...this.resObject,
checkedList
})
}
if(this.type == "single") {
this.handleSelectSwitch()
}
},
onListChange(val){
this.$emit('update:resObject', val)
},
handleRootClick() {
uni.$emit(selectDropEventName, this.componentId)
},
handleKeyWordChange(val) {
}
}
}
</script>
<style scoped lang="scss">
.md-drop-cont{
position: absolute;
background-color: #fff;
border-radius: 10rpx;
border: 2rpx solid #ebeef5;;
top: calc(100% + 8px);
left: 0;
right: 0;
z-index: 10;
padding: 20rpx;
box-sizing: border-box;
border-radius: 6px;
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
}
</style>