vant 封装一个多选弹框组件

<template>

  <div class="dh-field ">

    <div class="van-hairline--bottom">

      <van-field

        v-model="resultLabel"

        v-bind="$attrs"

        readonly

        :is-link="$attrs.disabled === undefined"

        error-message-align="left"

        input-align="left"

        @click="showPopu($attrs.disabled)"

        class="dh-cell"

      />

      <van-popup v-model="show" position="bottom" class="" >

        <div class="van-picker__toolbar">

          <button type="button" class="van-picker__cancel" @click="cancel">取消</button>

          <div class="van-ellipsis van-picker__title">{{ $attrs.label }}</div>

          <button type="button" class="van-picker__confirm" @click="onConfirm">确认</button>

        </div>

        <div class="checkbox-con" style="max-height:264px;overflow-y:auto">

          <van-field v-model="searchVal" placeholder="搜索" @input="search" v-if="isSearch" input-align="left"/>

          <van-cell title="全选">

            <template #right-icon>

              <van-checkbox name="all" @click="toggleAll" v-model="checkedAll"/>

            </template>

          </van-cell>

          <van-checkbox-group v-model="checkboxValue" @change="change" ref="checkboxGroup">

            <van-cell-group>

              <van-cell

                v-for="(item, index) in columnsData"

                clickable

                :key="item[option.value]"

                :title="item[option.label]"

                @click="toggle(index)"

              >

                <template #right-icon>

                  <van-checkbox :name="item[option.value]" ref="checkboxes" />

                </template>

              </van-cell>

            </van-cell-group>

          </van-checkbox-group>

        </div>

      </van-popup>

    </div>

  </div>

</template>

<script>

import mixin from '@/views/myvisit/add/mixin'

// 封装VanFieldCheckbox组件

// https://www.jianshu.com/p/65861e3a7b55

import {

  CellGroup as VanCellGroup,

  Cell as VanCell,

  Field as VanField,

  Popup as VanPopup,

  Checkbox as VanCheckbox,

  CheckboxGroup as VanCheckboxGroup

} from 'vant'

export default {

  components: {

    VanCell,

    VanCellGroup,

    VanField,

    VanPopup,

    VanCheckbox,

    VanCheckboxGroup

  },

  name: 'VanFieldCheckbox',

  mixins: [mixin],

  model: {

    prop: 'selectValue'

  },

  props: {

    columns: {

      type: Array,

      default: function () {

        return []

      }

    },

    selectValue: {

      type: Array,

      default: function () {

        return []

      }

    },

    option: {

      type: Object,

      default: function () {

        return { label: 'label', value: 'value' }

      }

    },

    isSearch: {

      type: Boolean,

      default: false

    }

  },

  computed: {

    resultLabel: {

      get () {

        const res = this.columns.filter(item => {

          return this.resultValue.indexOf(item[this.option.value]) > -1

        })

        const resLabel = res.map(item => {

          return item[this.option.label]

        })

        return resLabel.join(',')

      },

      set () {

      }

    }

  },

  data () {

    return {

      show: false,

      searchVal: '',

      columnsData: JSON.parse(JSON.stringify(this.columns)),

      checkboxValue: JSON.parse(JSON.stringify(this.selectValue)),

      checkedAll: false,

      resultValue: JSON.parse(JSON.stringify(this.selectValue))

    }

  },

  methods: {

    search (val) {

      if (val) {

        this.columnsData = this.columnsData.filter(item => {

          return item[this.option.label].indexOf(val) > -1

        })

      } else {

        this.columnsData = JSON.parse(JSON.stringify(this.columns))

      }

    },

    getData (val) {

      const res = this.columnsData.filter(item => {

        return val.indexOf(item[this.option.value]) > -1

      })

      return res

    },

    onConfirm () {

      this.resultValue = this.checkboxValue

      this.show = !this.show

      this.$emit('confirm', this.resultValue, this.getData(this.resultValue))

    },

    change (val) {

      this.$emit('change', val, this.getData(this.resultValue))

    },

    cancel () {

      this.show = !this.show

      this.$emit('cancel', this.resultValue)

    },

    toggle (index) {

      this.$refs.checkboxes[index].toggle()

    },

    toggleAll (all) {

      this.$refs.checkboxGroup.toggleAll(this.checkedAll)

    },

    showPopu (disabled) {

      this.columnsData = JSON.parse(JSON.stringify(this.columns))

      this.checkboxValue = JSON.parse(JSON.stringify(this.selectValue))

      this.resultValue = JSON.parse(JSON.stringify(this.selectValue))

      if (disabled !== undefined && disabled !== false) {

        return false

      } else {

        this.show = !this.show

      }

    }

  },

  watch: {

    selectValue: function (newVal) {

      this.resultValue = newVal

    },

    resultValue (val) {

      this.searchVal = ''

      this.columnsData = JSON.parse(JSON.stringify(this.columns))

      this.$emit('input', val)

    },

    columnsData: {

      handler (val) {

        if (val.length && val.length === this.checkboxValue.length) {

          this.checkedAll = true

        } else {

          this.checkedAll = false

        }

      },

      immediate: true

    },

    checkboxValue: {

      handler (val) {

        if (val.length && val.length === this.columnsData.length) {

          this.checkedAll = true

        } else {

          this.checkedAll = false

        }

      },

      immediate: true

    }

  }

}

</script>

<style lang="less" scoped>

.dh-field {

  padding: 0 16px;background:#fff;

  .dh-cell.van-cell{padding: 10px 0;}

  .dh-cell.van-cell--required::before{left: -8px;}

  .van-popup{border-radius: 20px 20px 0 0;}

}

</style>

父组件引用

import VanFieldCheckbox from '../../../components/VanFieldCheckbox'

<van-field-checkbox

            label="选择联系人名称"

            placeholder="点击选择联系人"

            v-model="value2"

            :columns="contactlist"

            label-width="100"

            :rules="[{ required: true, message: '请选择联系人' }]"

            :option="{label:'contractName',value:'id'}"

            @confirm="confirm"

          />

value2: [

      ], // checkbox选中的value

async confirm (data1, data2) { // select确定,

      // tips 正常获取值,用不到这个方法,用v-model获取值即可,这个方法是告诉你,可以获取任何你想要的数据

      // data1 是当前选中数据的value的数组

      // data2 是当前选中数据的整个obj集合

    },

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值