[Practical experience] The picker selector package in vant makes your form selection easier

foreword

For the selector component, the picker component in vant is a very suitable choice. It not only provides flexible configuration options, but also can be easily combined with other vant components to help us quickly build beautiful and easy-to-use mobile pages. In this article, I will introduce how to perform secondary packaging based on vant 's picker component to better meet actual business needs.


Implementation ideas

  1. First define a subcomponent page to encapsulate the selector;
  2. Introduce and register the encapsulation component (subcomponent) in the parent component (the page used), and then use it in the page. In the parent component, bind multiple attributes to the label (registered component name), and the attribute needs to be passed to mount The value of is received by receiving data propsin the subcomponent (encapsulation file);
  3. Customize the determined event in the child component. After calling this event, the child component this.$emit('自定义事件名',要传递的数据)sends the data that the parent component can listen to, and finally the parent component listens to the child component event, calls the event and receives the passed data.

defined parameters

parameter describe
selectValue bind valuemodel
keyValue bound keyfield
keyLabel bound valuefield
columns The bound optiondata source
required Whether to display red *check
rules Validation rules
required Is it required?
confirm The selected callback function

package file

<template>
  <div>
    <van-field v-model="textValue" v-bind="$attrs" :name="$attrs.name" :rules="rules" :required="required" :readonly="readonly"
      :is-link="islink" @click="show = !show" />
    <van-popup v-model="show" get-container="body" position="bottom">
      <van-picker :columns="columns" show-toolbar :value-key="keyValue" :title="$attrs.label" @cancel="show = !show" @confirm="onConfirm">
        <template #option="option">
          {
   
   { option[keyLabel] }}
        </template>
      </van-picker>
    </van-popup>
  </div>
</template>

<script>
export default {
      
      
  props: {
      
      
    required: {
      
      
      type: Boolean,
    },
    readonly: {
      
      
      type: Boolean,
    },
    islink: {
      
      
      type: Boolean,
    },
    columns: {
      
      
      type: Array,
    },
    rules: {
      
      
      type: Array,
    },
    selectValue: {
      
      
      type: String,
    },
    keyValue: {
      
      
      type: String,
    },
    keyLabel: {
      
      
      type: String,
    },
  },
  data() {
      
      
    return {
      
      
      show: false,
      textValue: "",
      selectOptions: [],
    };
  },
  methods: {
      
      
    onConfirm(obj) {
      
      
      this.textValue = obj.label;
      this.show = !this.show;
      this.$emit("confirm", obj);
    },
    formatterValue(value) {
      
      
      let str = "";
      if (!this.columns.length || !value.length) {
      
      
        str = "";
      } else {
      
      
        let oArr = this.columns.filter((item) => {
      
      
          return item[this.keyValue].toString() == value.toString();
        });
        str = oArr[0][this.keyLabel];
      }

      return str;
    },
    //根据key值格式化成picker需要的option格式
    formatColumnsByKey() {
      
      
      let arr = [];
      let value = this.keyValue ? this.keyValue : "value";
      let label = this.keyLabel ? this.keyLabel : "label";
      this.columns.map((item) => {
      
      
        arr.push({
      
      
          label: item[label],
          value: item[value],
        });
      });
      this.selectOptions = arr;
    },
  },
  watch: {
      
      
    columns: {
      
      
      handler(newValue) {
      
      
        this.textValue = this.formatterValue(
          this.selectValue ? this.selectValue : ""
        );
      },
      deep: true,
      immediate: true,
    },
    selectValue: {
      
      
      handler(newValue) {
      
      
        this.textValue = this.formatterValue(newValue ? newValue : "");
      },
      deep: true,
      immediate: true,
    },
  },
};
</script>

use file

<template>
  <div>
    <van-form validate-first>
      <VanSelect name="qylx" label="企业类型" placeholder="请选择企业类型" :selectValue="qylx" :keyValue="`value`" :keyLabel="`label`" :required="true"
        :readonly="true" :columns="qylxOption" :rules="rules.qybh" @confirm="qylxConfirm" />
      <div class="btnBomBox">
        <van-button round size="small" block @click="submitOn" type="info">提交</van-button>
      </div>
    </van-form>
  </div>
</template>

<script>
import VanSelect from "@/components/vanSelect/index";
export default {
      
      
  components: {
      
      
    VanSelect,
  },
  data() {
      
      
    return {
      
      
      qylx: "",
      qylxOption: [
        {
      
       label: "自营企业", value: "1" },
        {
      
       label: "其他企业", value: "2" },
      ],
      rules: {
      
      
        qybh: [
          {
      
      
            required: true,
            message: "请选择企业类型",
          },
        ],
      },
    };
  },
  methods: {
      
      
    // 点击确定
    qylxConfirm(value) {
      
      
      this.qylx = value.value;
    },
    // 提交
    submitOn() {
      
      
      console.log(this.qylx);
    },
  },
};
</script>

<style scoped>
.btnBomBox {
      
      
  padding: 0px 16px;
  display: flex;
  justify-content: center;
}
</style>

achieve effect

insert image description here

Guess you like

Origin blog.csdn.net/Shids_/article/details/131086409