表单类的组件,当label的for属性等同于表单元素的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元素的话,非常繁琐,希望封装之后可以这么使用:
<radio-component :value.sync="xxx" :options="[{text:'北京',value:'bj'}]"></radio-component>
复制代码简单传入options和value就可以使用了!
- 简单写个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>
复制代码
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
    





















![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
