vant-picker二次封装

痛点


在项目经常会遇到这样的设计,下拉选择框,在vant中没有提供直接的select组件,但是可以使用FieldPopupPicker这三个组件组合来完成。
如果页面中只有一个select这样做做也还可以,但是现在页面中有三个select就有点繁琐了,所以考虑进行组件的封装。

使用期望

<van-field-select-picker
          label="物料类型"
          placeholder="选择类型"
          v-model="materielType"
          :columns="materielTypeList"
 />

我希望是在页面中这样使用组件

新建组件

 

在项目的src/components文件夹下面新建了一个VanFieldSelectPicker.vue文件,具体代码如下,这里主要就是学习了一下组件嵌套时自定义v-model,组件中暂时也没考虑太多其他的东西,有什么问题只能遇到了再更新。
<template>
  <div>
    <van-field
      v-model="result"
      v-bind="$attrs"
      readonly
      is-link
      @click="show = !show"
    />
    <van-popup v-model="show" position="bottom">
      <van-picker
        :columns="columns"
        show-toolbar
        :title="$attrs.label"
        @cancel="show = !show"
        @confirm="onConfirm"
      />
    </van-popup>
  </div>
</template>

<script>
export default {
  model: {
    prop: "selectValue"
  },
  props: {
    columns: {
      type: Array
    },
    selectValue: {
      type: String
    }
  },
  data() {
    return {
      show: false,
      result: this.selectValue
    };
  },
  methods: {
    onConfirm(value) {
      this.result = value;
      this.show = !this.show;
    }
  },
  watch: {
    selectValue: function(newVal) {
      this.result = newVal;
    },
    result(newVal) {
      this.$emit("input", newVal);
    }
  }
};
</script>

<style></style>
 

效果

            <van-field-select-picker
              label="物料类型"
              placeholder="请选择"
              v-model="value1"
              :columns="[1, 2, 3]"
            />
            <van-field-select-picker
              label="品牌"
              placeholder="请选择"
              v-model="value2"
              :columns="[1, 2, 3]"
            />
            <van-field-select-picker
              label="规格"
              placeholder="请选择"
              v-model="value3"
              :columns="[1, 2, 3]"
            />
链接:https://www.jianshu.com/p/3c6609d5dad3

补充

实际应用中需要拿到下拉选择的id值,但用上面封装的只能拿到text,所以做了如下修改

1、组件SelectPicker.vue

<template>
    <div>
        <van-field
                v-model="result"
                v-bind="$attrs"
                readonly
                is-link
                @click="show = !show"
        />
        <van-popup v-model="show" position="bottom">
            <van-picker
                    :columns="columns"
                    show-toolbar
                    :title="$attrs.label"
                    @cancel="show = !show"
                    @confirm="onConfirm"
            />
        </van-popup>
    </div>
</template>

<script>
    export default {
        model: {
            prop: "selectValue"
        },
        props: {
            columns: {
                type: Array
            },
            selectValue: {
                type: String
            },
            name:{
                type: String  //父组件传进来一个name
            }
        },
        data() {
            return {
                show: false,
                result: this.selectValue
            };
        },
        methods: {
            onConfirm(value) {
                this.result = value.label;
                this.show = !this.show;
                this.$emit("getMessage", this.name,value.value);//把value值传给父组件
            },
        },
        watch: {
            selectValue: function(newVal) {
                this.result = newVal;
            },
            result(newVal) {
                this.$emit("input", newVal);
            }
        }
    };
</script>
<style></style>

2、父组件

<template v-else-if="item.type.name == 'picklist' >
           <input type="hidden" value="" :id=item.name>
             <select-picker
                   :label="item.label"
                    :name="item.name"
                    placeholder="请选择"
                    v-model="dataList[item.name]"
                    :columns="item.type.picklistValues"
                    @getMessage="setValue"
              />
 </template>
<script>
export default {
data() {
return {
name:'',
}
},
methods: {

      setValue(name,value){
         $("#"+name).val(value);
    },
    },
}
</script>
 



原文地址:https://www.cnblogs.com/ivy-zheng/p/13304744.html