Files
sh-app/components/nbd-select-project.vue
T
2026-06-10 14:17:54 +08:00

163 lines
3.3 KiB
Vue

<template>
<u-popup v-model="visible" mode="bottom" height="80%">
<view class="project-select">
<view class="project-select-btns">
<u-button size="mini" type="info" @click="handleCancel">取消</u-button>
<text></text>
<u-button size="mini" type="primary" @click="handleConfirm">确定</u-button>
</view>
<view class="project-select-filter">
<u-search placeholder="请输入项目名称" height="60" v-model="searchKey" :show-action="false"
@change="handleSearchKey"></u-search>
</view>
<scroll-view scroll-y="true" class="project-select-inner">
<view class="project-select-inner-wrap">
<view class="li" v-for="(item,idx) in filteredList" :key="idx"
:class="selectObj && selectObj[props.valueKey] == item[props.valueKey] ? 'active' : ''"
@click="handerChangList(item)"
>
{{ item[props.labelKey] }}
</view>
<view v-if="filteredList.length === 0" class="empty-tip">暂无匹配项目</view>
</view>
</scroll-view>
</view>
</u-popup>
</template>
<script setup>
import {
ref,
watch,
computed
} from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
searchKey: {
type: String,
default: ''
},
list: {
type: Array,
default: () => []
},
labelKey: {
type: String,
default: 'label'
},
valueKey: {
type: String,
default: 'value'
},
selectId: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:modelValue', 'cancel', 'confirm', 'searchChange'])
const visible = ref(false)
const searchKey = ref("")
const selectObj = ref(null)
// 过滤后的列表
const filteredList = computed(() => {
if (!props.searchKey) return props.list
return props.list.filter(item =>
item[props.labelKey]?.includes(props.searchKey)
)
})
watch(() => props.modelValue, (val) => {
visible.value = val
if(val){
const selectedItem = props.list.find(item => item[props.valueKey] === props.selectId)
if (selectedItem) {
selectObj.value = selectedItem
} else {
selectObj.value = null
}
}
})
watch(visible, (val) => {
emit('update:modelValue', val)
})
const handerChangList = (item)=>{
selectObj.value = item
}
// 点击取消
const handleCancel = () => {
emit('update:modelValue', false)
}
// 点击确认
const handleConfirm = () => {
emit("confirm", selectObj.value)
}
// 搜索
const handleSearchKey = (val) => {
emit('searchChange', val)
}
</script>
<style lang="scss" scoped>
.project-select {
height: 100%;
display: flex;
flex-direction: column;
background: #fff;
border-radius: 24rpx 24rpx 0 0;
.project-select-btns {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.project-select-filter {
padding: 16rpx 32rpx;
border-bottom: 1rpx solid #f0f0f0;
}
.project-select-inner {
flex: 1;
overflow-y: auto;
.project-select-inner-wrap {
padding: 0 32rpx 32rpx;
.li {
padding: 28rpx 0;
border-bottom: 1rpx solid #f5f6f8;
font-size: 28rpx;
color: #333;
transition: all 0.2s;
&:last-child {
border-bottom: none;
}
&.active {
color: $u-type-primary;
font-weight: 500;
}
}
.empty-tip {
text-align: center;
padding: 80rpx 0;
color: #999;
font-size: 26rpx;
}
}
}
}
</style>