| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <template>
- <view class="cwg-combox">
- <template v-if="disabled">
- <view class="disabled-text">{{ innerText }}</view>
- </template>
- <template v-if="!disabled">
- <!-- 可搜索模式 -->
- <uni-combox v-if="filterable" v-model="innerText" :candidates="textList" :clearable="clearable" :options="options"
- :placeholder="placeholder?placeholder:t('placeholder.choose')" :disabled="disabled" @input="handleComboxChange" />
- <!-- 普通下拉模式 -->
- <uni-data-select v-else v-model="innerValue" :localdata="options" :clear="clearable"
- :placeholder="placeholder?placeholder:t('placeholder.choose')" :multiple="multiple" :disabled="disabled" @change="handleSelectChange" :needSpace="needSpace" :emptyTips="t('Documentary.tradingCenter.item143')">
- <template #selected v-if="$slots.selected">
- <slot name="selected"></slot>
- </template>
- </uni-data-select>
- </template>
- </view>
- </template>
- <script setup>
- import { ref, computed, watch, onMounted } from 'vue'
- import { useI18n } from 'vue-i18n'
- const { t } = useI18n()
- const props = defineProps({
- value: [String, Number, Array],
- options: {
- type: Array,
- default: () => []
- },
- filterable: {
- type: Boolean,
- default: false
- },
- placeholder: String,
- clearable: {
- type: Boolean,
- default: true
- },
- multiple: {
- type: Boolean,
- default: false
- },
- disabled: Boolean,
- needSpace: {
- type: Boolean,
- default: false
- },
- })
- const emit = defineEmits(['update:value', 'change'])
- /**
- * 内部状态
- */
- const innerValue = ref(props.value)
- const innerText = ref()
- /**
- * 提取 text 列表(给 combox 用)
- */
- const textList = computed(() =>
- props.options.map(item => item.text)
- )
- /**
- * value → text 映射
- */
- const updateTextByValue = (val) => {
- if (!val) {
- innerText.value = ''
- return
- }
- const item = props.options.find(i => i.value === val)
- innerText.value = item ? item.text : ''
- }
- /**
- * 组件挂载时初始化
- */
- onMounted(() => {
- if (props.value) {
- innerValue.value = props.value
- updateTextByValue(props.value)
- }
- })
- /**
- * value 改变时同步内部状态
- */
- watch(
- () => props.value,
- (val) => {
- innerValue.value = val
- updateTextByValue(val)
- }
- )
- /**
- * options 改变时重新计算显示文本(回显)
- */
- watch(
- () => props.options,
- () => {
- if (props.value) {
- updateTextByValue(props.value)
- }
- },
- { deep: true }
- )
- /**
- * 普通 select 改变
- */
- const handleSelectChange = (val) => {
- // console.log(val, props.options, 1111)
- innerValue.value = val
- updateTextByValue(val)
- emit('update:value', val)
- emit('change', val)
- }
- /**
- * combox 改变
- */
- const handleComboxChange = (text) => {
- const item = props.options.find(i => i.text === text)
- if (item) {
- innerValue.value = item.value
- emit('update:value', item.value)
- emit('change', item.value)
- }
- }
- </script>
- <style lang="scss" scoped>
- @import "@/uni.scss";
- .cwg-combox {
- font-size: px2rpx(16);
- //background-color: var(--bs-secondary-bg);
- /* 穿透修改 uni-data-select 内部列表最大高度,使其可以滚动 */
- :deep(.uni-select__selector-scroll) {
- max-height: px2rpx(200);
- /* 限制最高约 200px (约 5~6 个选项的高度) */
- overflow-y: auto;
- }
- }
- .disabled-text {
- height: px2rpx(35);
- padding: 0 px2rpx(12);
- border-radius: px2rpx(4);
- line-height: 1;
- font-size: px2rpx(16);
- background: transparent;
- display: flex;
- align-items: center;
- //justify-content: center;
- color: var(--input-disabled-text-color);
- border: 1px solid #e5e5e5;
- border-radius: 4px;
- background-color: var(--input-disabled-bg-color) !important;
- }
- </style>
|