用vue简单封装单选组件

表单类的组件,当labelfor属性等同于表单元素的ID的时候,点击label就会触发相应的表单元素的点击事件,为一些场景提供方便。

这边根据业务场景,简单封装一个单选组件。

单选的基本使用

先看下官方单选的基本使用案例

<div id="example-4">
  <input type="radio" id="one" value="One" v-model="picked">
  <label for="one">One</label>
  <br>
  <input type="radio" id="two" value="Two" v-model="picked">
  <label for="two">Two</label>
  <br>
  <span>Picked: {{ picked }}</span>
</div>
<script>
new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})
</script>
复制代码

radio_2

封装单选组件

显然,实际业务使用中,这么一个个写radio元素的话,非常繁琐,希望封装之后可以这么使用:

<radio-component :value.sync="xxx" :options="[{text:'北京',value:'bj'}]"></radio-component>
复制代码

简单传入optionsvalue就可以使用了!

  • 简单写个id的生成方法
  • 考虑到父组件更好的调用,直接使用了sync语法糖,当然也可以使用v-model语法糖,个人觉得前者更好理解
  • 这里的label内部的内容,在实际项目中,可以换成任意的标签和组件,增加灵活性
<template>
  <div class="radio-button-box" style="display: flex">
    <div v-for="(item, index) in optionsWithId" :key="index">
      <input type="radio" hidden :value="item.value" :id="item.id" />
      <label :for="item.id" @click="clickRadio(item)">
        <!-- 此处可以任意更换别的组件或者标签 -->
        <button :class="{ btn: true, selected: value === item.value }">
          {{ item.text }}
        </button>
      </label>
    </div>
  </div>
</template>
<script>
/**
 * 本组件本质是单选,options可以自定义,但必须有text和value,默认两个选项
 * value是必传项,这里值发生变化的话,通过sync语法糖修改父组件的value,从而改变这里的value
 *
 * 使用方式:<radio-component :value.sync="xxx"></radio-component>
 */

export default {
  name: 'RadioComponent',
  props: {
    options: { required: true, type: Array },
    value: { required: true }
  },
  computed: {
    optionsWithId() {
      // 给每项手动加个id
      this.options.forEach(item => {
        item.id = `radio${Math.random()
          .toString()
          .slice(3, 13)}`;
      });
      return this.options;
    }
  },
  methods: {
    clickRadio(item) {
      this.$emit("update:value", item.value);
    }
  }
};
</script>
<style scoped>
.radio-button-box {
  display: flex;
}
.btn {
  margin-right: 20px;
  padding: 5px 10px;
  border: 1px solid;
  font-size: 12px;
}
.btn.selected {
  background-color: #69f;
  color: #fff;
}
</style>

复制代码

使用单选组件

使用的话,其实没啥,存入两个属性就行

<template>
  <div>
    <h1>单选组件的使用!</h1>
    <radio-component :value.sync="city" :options="options"></radio-component>
  </div>
</template>
<script>
import RadioComponent from "./components/RadioComponent.vue";
export default {
  name: "App",
  components: { RadioComponent },
  data() {
    return {
      city: null,
      options: [
        { text: "北京", value: "bj" },
        { text: "上海", value: "sh" }
      ]
    };
  }
};
</script>
复制代码

radio_3.gif

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享