vantui-自定义组件PickerField

<template>
  <van-field v-model="fieldValue"
             :label="props.label"
             :class="props.class"
             :placeholder="props.placeholder"
             is-link
             readonly
             @click="click"/>
  <van-popup v-model:show="page.showPicker" round position="bottom" @closed="closed">
    <van-search v-if="props.showSearch" v-model="page.searchKey" placeholder="输入内容搜索" :maxlength="10" autofocus
                input-align="center" @update:model-value="searchItem"></van-search>
    <van-picker
        v-model="page.pickerValues"
        :visible-option-num="props.showSearch?8:6"
        :columns="page.searchList"
        @cancel="clearPicker"
        @confirm="confirmPicker"
        cancel-button-text="清空"
        confirm-button-text="确定"
        :columns-field-names="page.fieldNames">
    </van-picker>
  </van-popup>
</template>

<script setup name="PickerField">
const props = defineProps({
  modelValue: {required: false},
  label: {type: String, default: "", required: false},
  placeholder: {type: String, default: "请选择", required: false},
  class: {type: String, default: "", required: false},
  pickerData: {type: Array, default: [], required: true},
  pickerLabelField: {type: String, default: "label", required: false},
  pickerValueField: {type: String, default: "value", required: false},
  showSearch: {type: Boolean, default: true, required: false}
});

const emit = defineEmits(["update:model-value", "confirm", "click"]);

const page = reactive({
  searchList: props.pickerData,
  pickerValues: [props.modelValue],
  showPicker: false,
  searchKey: null,
  fieldNames: {text: props.pickerLabelField, value: props.pickerValueField}
});

const fieldValue = computed(() => {
  if (page.pickerValues && page.pickerValues.length > 0 && props.pickerData) {
    let pickerVal = page.pickerValues[0];
    for (let i = 0; i < props.pickerData.length; i++) {
      let item = props.pickerData[i];
      if (item[props.pickerValueField] == pickerVal) {
        return item[props.pickerLabelField];
      }
    }
  }
  return props.modelValue;
});

watch(() => props.pickerData, (newVal) => {
  if (newVal) {
    page.searchList = newVal;
  } else {
    page.searchList = [];
  }
})

watch(() => props.modelValue, (newVal) => {
  if (newVal) {
    page.pickerValues = [newVal];
  } else {
    page.pickerValues = []
  }
})

function click(event) {
  page.showPicker = true
  emit("click", event)
}

function clearPicker() {
  page.pickerValues = [];
  page.showPicker = false;

}

function confirmPicker(selected) {
  if ((!page.pickerValues || page.pickerValues.length == 0) && page.searchList && page.searchList.length > 0) {
    page.pickerValues = [page.searchList[0][props.pickerValueField]];
  }
  page.showPicker = false;
}

function searchItem(val) {
  if (val && props.pickerData) {
    page.searchList = props.pickerData.filter(item => item[props.pickerLabelField].indexOf(val) != -1);
  } else {
    page.searchList = props.pickerData;
  }
}

function closed() {
  if (page.pickerValues && page.pickerValues.length > 0) {
    emit("update:model-value", page.pickerValues[0]);
    emit("confirm", page.pickerValues[0]);
  } else {
    emit("update:model-value", '');
    emit("confirm", '');
  }
}

</script>

<style scoped>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值