• vant实现select效果,单选和多选


    官方推荐picker,但是我们项目用picker还要搭配Popup和cell、field,维护太太麻烦,所以自己封装一个

    select单选

    //封装VanFieldSelectPicker组件
    <template>
      <div>
        <van-field
          v-model="resultLabel"
          v-bind="$attrs"
          readonly
          is-link
          input-align="right"
          @click="show = !show"
        />
        <van-popup v-model="show" position="bottom">
          <van-picker
            v-bind="$attrs"
            :columns="columns"
            show-toolbar
            @cancel="cancel"
            @confirm="onConfirm"
            @change="change"
            :value-key="this.option.label"
          />
        </van-popup>
      </div>
    </template>
    
    <script>
    export default {
      name: 'VanFieldSelectPicker',
      model: {
        prop: 'selectValue'
      },
      props: {
        columns: {
          type: Array,
          default: function () {
            return []
          }
        },
        selectValue: {
          type: [String, Number],
          default: ''
        },
        option: {
          type: Object,
          default: function () {
            return { label: 'label', value: 'value' }
          }
        }
      },
      computed: {
        resultLabel: {//双向绑定的数据做修改需要用get/set
          get () {
            const res = this.columns.filter(item => {
              return item[this.option.value] === this.resultValue
            })
            return res.length ? res[0][this.option.label] : ''
          },
          set () {
    
          }
        }
      },
      data () {
        return {
          show: false,//Popup是否弹出
          resultValue: this.selectValue //初始选中数据
        }
      },
      methods: {
        onConfirm (value, index) {//确定
          this.resultValue = value[this.option.value]
          this.show = !this.show
          this.$emit('confirm', value, index, this.resultValue)
        },
        change (val, index) {//当数据改变
          this.$emit('change', val, index, this.resultValue)
        },
        cancel (val, index) {//取消
          this.show = !this.show
          this.$emit('cancel', val, index, this.resultValue)
        }
      },
      watch: {
        selectValue: function (newVal) {//监听变化初始赋值
          this.resultValue = newVal
        },
        resultValue (val) {//当所选数据变化,组件model的双向绑定
          this.$emit('input', val)
        }
      }
    }
    </script>
    
    <style></style>
    
    

    使用(建议全局注册)

    <van-field-select-picker
              label="单选select"
              placeholder="请选择"
              v-model="value1"
              :columns="columns"
              :option="{label:'name',value:'code'}"
              @confirm="confirm2"
          />
    data:
    value1: '1', // select选中的value
    columns: [// 如果可选数据不是label-value,需要配置下option,如果是就不需要配置
            { name: '我是选中的label', code: '1', other: '额外数据' },
            { name: '我也是选中的label33333', code: '2', other: '额外数据' },
            { name: '我是选中的label', code: '21', other: '额外数据' },
            { name: '我也是选中的label555555555', code: '22', other: '额外数据' },
            { name: '我是选中的label', code: '11', other: '额外数据' },
            { name: '我也是选中的label', code: '52', other: '额外数据' },
            { name: '我是选中的label', code: '71', other: '额外数据' },
            { name: '我也是选中的label', code: '72', other: '额外数据' }
          ]
    
    methods:
    confirm2 (data1, index, data2) { // checkbox确定,
        // tips 正常获取值,用不到这个方法,用v-model获取值即可,这个方法是告诉你,可以获取任何你想要的数据
        // data1 当前这一条的obj数据
        // index 当前选择的索引
        // data2 当前这一条数据的value
          console.log(data1, data2, index)
          this.value4 = data1
        }
    

    Events 同 vant-picker

    |-confirm -- 点击完成按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
    |-cancel -- 点击取消按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
    |-change -- 选项改变时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|

    属性

    label-width ---------------------------label的一个宽度设置

    label="单选select"---------------------label文字

    :columns="columns"---------------------可选择的数据,只接受key-value格式的对象集合,[1,2,3]不可以

    :option="{label:'name',value:'code'}"--数据的配置格式,默认label(显示的文字),value(具体值)

    checkbox多选

    //封装VanFieldCheckbox组件
    <template>
      <div>
        <van-field
          v-model="resultLabel"
          v-bind="$attrs"
          readonly
          is-link
          input-align="right"
          @click="show = !show"
        />
        <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-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 columns"
                  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>
    </template>
    
    <script>
    export default {
      name: 'VanFieldCheckbox',
      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' }
          }
        }
      },
      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,
          checkboxValue: JSON.parse(JSON.stringify(this.selectValue)),
          checkedAll: false,
          resultValue: JSON.parse(JSON.stringify(this.selectValue))
        }
      },
      methods: {
        getData (val) {//过滤出所选数据的obj集合
          const res = this.columns.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) {//cell点击事件,同步checkbox
          this.$refs.checkboxes[index].toggle()
        },
        toggleAll (all) {//全选
          this.$refs.checkboxGroup.toggleAll(this.checkedAll)
        }
      },
      watch: {
        selectValue: function (newVal) {
          this.resultValue = newVal
        },
        resultValue (val) {
          this.$emit('input', val)
        },
        checkboxValue (val) {//监听数据变化,判断全选的状态
          if (val.length !== this.columns.length) {
            this.checkedAll = false
          } else {
            this.checkedAll = true
          }
        }
      }
    }
    </script>
    
    <style>
    .van-cell__title{text-align: left;}
    </style>
    
    

    使用

     <van-field-checkbox
            label="多选checkbox"
            placeholder="请选择"
            v-model="value2"
            :columns="columns"
            label-width="100"
            :option="{label:'name',value:'code'}"
            @confirm="confirm"
          />
    
    data:
     value2: ['1'], // checkbox选中的value
          columns: [// 如果可选数据不是label-value,需要配置下option,如果是就不需要配置
            { name: '我是选中的label', code: '1', other: '额外数据' },
            { name: '我也是选中的label33333', code: '2', other: '额外数据' },
            { name: '我是选中的label', code: '21', other: '额外数据' },
            { name: '我也是选中的label555555555', code: '22', other: '额外数据' },
            { name: '我是选中的label', code: '11', other: '额外数据' },
            { name: '我也是选中的label', code: '52', other: '额外数据' },
            { name: '我是选中的label', code: '71', other: '额外数据' },
            { name: '我也是选中的label', code: '72', other: '额外数据' }
          ]
    
    methods:
    confirm (data1, data2) { // select确定,
        // tips 正常获取值,用不到这个方法,用v-model获取值即可,这个方法是告诉你,可以获取任何你想要的数据
        // data1 是当前选中数据的value的数组
        // data2 是当前选中数据的整个obj集合
          console.log(data1, data2)
          this.value3 = data2
        },
    

    Events 同 vant-picker

    |-confirm -- 点击完成按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
    |-cancel -- 点击取消按钮时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|
    |-change -- 选项改变时触发 -- 单列:选中[整个数据]的值,选中值对应的索引,选中的value-|

    属性

    label-width ---------------------------label的一个宽度设置

    label="单选select"---------------------label文字

    :columns="columns"---------------------可选择的数据,只接受key-value格式的对象集合,[1,2,3]不可以

    :option="{label:'name',value:'code'}"--数据的配置格式,默认label(显示的文字),value(具体值)

  • 相关阅读:
    Autofac的基本使用---4、使用Config配置
    Autofac的基本使用---3、泛型类型
    Autofac的基本使用---2、普通类型
    Autofac的基本使用---1、前言
    MVC中Autofac的使用
    EF快速入门--直接修改(简要介绍ObjectContext处理机制)
    EF生成模型时Disigner中无信息
    C语言关键字-volatile
    linux内核分析之内存管理
    (转)Linux SLUB 分配器详解
  • 原文地址:https://www.cnblogs.com/ysx215/p/14144051.html
Copyright © 2020-2023  润新知