Vue2移动端(H5项目)项目基于vant实现select单选(支持搜索、回显、自定义下拉label展示功能)

一 最终效果

在这里插入图片描述

二、参数配置

1、代码示例:

<t-select
     v-model="formData.materialNo"
      valueKey="materialNo"
      showLabel="materialName"
      labelKey="label"
      label="判定品级"
      input-align="right"
      placeholder="请选择判定品级"
      right-icon="arrow"
      :list="judgingMaterialList"
        />

2、配置参数(t-select Attributes)继承van-field和van-picker的属性

参数说明类型默认值
v-model选中的valueKey值,页面展示是:showLabellString-
list下拉数据源Array-
valueKey下拉选择传给后台的keyStringkey
labelKey下拉选择显示labelStringlabel
isSearch是否显示搜索框Booleanfalse
showLabelvan-field显示的文本String-
searchPlaceholder搜索提示语String请输入搜索内容

3、events 事件

事件名说明返回值
emitVal点击确定按钮时触发选中的对象

三、源码

<template>
  <div class="t-select">
    <van-field v-bind="fieldAttrs" :value="text" @click="clickField" />
    <van-popup v-model="isShow" position="bottom">
      <van-field
        v-model="searchVal"
        :placeholder="searchPlaceholder"
        @input="search"
        v-if="isSearch"
        clearable
        input-align="left"
      />
      <van-picker
        v-on="$listeners"
        v-bind="$attrs"
        ref="picker"
        @change="changeVal"
        :value-key="labelKey"
        :columns="columnsData"
        show-toolbar
        @confirm="onConfirm"
        @cancel="isShow = false"
      />
    </van-popup>
  </div>
</template>

<script>
export default {
  name: 'TSelect',
  props: {
    // 下拉数据源
    list: {
      type: Array,
      default: () => []
    },
    val: { default: null },
    // 下拉选择传给后台的key
    valueKey: {
      type: String,
      default: 'key',
    },
    // 下拉选择显示label
    labelKey: {
      type: String,
      default: 'label',
    },
    // 是否显示搜索框
    isSearch: {
      type: Boolean,
      default: false
    },
    // van-field显示的文本
    showLabel: {
      type: String
    },
    searchPlaceholder: {
      type: String,
      default: '请输入搜索内容'
    }
  },
  model: {
    prop: 'val',
    event: 'emitVal'
  },
  data() {
    return {
      isShow: false,
      columnsData: this.list,
      searchVal: '',
      text: '',
    }
  },
  watch: {
    val: {
      handler(newVal) {
        // 赋值回显
        if (newVal) {
          const findItem = this.list.find((item) => item[this.valueKey] == newVal)
          this.text = findItem[this.showLabel || this.labelKey]
        }
      },
      deep: true,
      immediate: true
    },
    list: {
      handler(newVal) {
        this.columnsData = newVal
      },
      deep: true,
      immediate: true
    }
  },
  computed: {
    fieldAttrs() {
      return {
        readonly: true,
        clickable: true,
        ...this.$attrs
      }
    }
  },
  methods: {
    clickField() {
      this.isShow = true
      this.$emit('clickField', true)
    },
    onConfirm(value) {
      // console.log('点击确定', value)
      this.$emit('emitVal', value[this.valueKey], value)
      this.text = value[this.showLabel || this.labelKey]
      this.isShow = false
    },
    changeVal() {
      this.$emit('change')
    },
    clear() {
      this.text = ''
      this.$emit('emitVal', null)
    },
    // 搜索
    search(val) {
      // console.log('搜索', val)
      if (val) {
        this.columnsData = this.columnsData.filter(item => {
          return item[this.labelKey].indexOf(val) > -1
        })
      } else {
        this.columnsData = JSON.parse(JSON.stringify(this.list))
      }
    },
  }
}
</script>


相关文章

基于ElementUi再次封装基础组件文档


基于ant-design-vue再次封装基础组件文档


vue3+ts基于Element-plus再次封装基础组件文档

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wocwin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值