vue自定义组件之单选框组件

为了解决原生单选框样式与网页整体风格不匹配的问题,本文介绍了如何创建一个自定义Vue单选框组件。该组件支持v-model双向绑定、disabled属性禁用、label属性定义值以及点击触发change事件。提供了详细的代码实现、使用方法和动画效果展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于原生的单选框的样式太丑,在网页中使用与整体的样式不搭配。因此需要自定义样式
实现功能
  1. 自定义v-model,使组件之间数据能够进行双向绑定。
  2. 使用disabled属性禁用radio。
  3. 使用label属性定义radio的值。
  4. 当用户点击radio时触发组件上绑定的change事件。

代码实现

  1. template
<template>
  <label role="radio" aria-checked="true" class="lg-radio"
  :class="{'checked': checked, 'disabled': disabled}">
    <span class="lg-radio__icon"></span>
    <input type="radio" ref="radio" class="lg-radio__original" :value="label" @click="select"
    :disabled='disabled'>
    <span class="lg-radio__label">
      <slot></slot>
    </span>
  </label>
</template>
  1. script
<script>
export default {
  name: 'lg-radio',
  // 自定义v-model,使用change事件更新model的值
  model: {
    prop: 'model',
    event: 'change'
  },
  props: {
    label: {
      type: [Number, String],
      required: true
    },
    // 这里的model指的是上面定义的v-model的prop
    model: {
      type: [Number, String],
      required: true
    },
    disabled: {
      type: Boolean,
      default: false
    }
  },
  data () {
    return {
      checked: false
    }
  },
  methods: {
    select () {
      this.$emit('change', this.$refs.radio.value)
    }
  },
  watch: {
    // 监听model值的改变,以便更新checked的值
    model: function (val) {
      this.checked = val === this.label
    }
  },
  mounted () {
    this.select()
  }
}
</script>
  1. style
<style scoped>
.lg-radio{
  font-size: 14px;
  color: #4a4949;
  font-weight: 500;
  cursor: pointer;
  outline: none;
  display: inline-block;
  text-align: left;
  margin: 0 20px 0 0;
}
.lg-radio.checked{
  color: #21b4e0;
}
.lg-radio.disabled {
  border-color: #ccc;
  opacity: 0.6;
  cursor: no-drop;
}
.lg-radio__icon {
  width: 14px;
  height: 14px;
  display: inline-block;
  border: 1px solid #c5c5c5;
  border-radius: 50%;
  margin-right: 6px;
  vertical-align: -2px;
  position: relative;
}
.lg-radio__icon::after{
  content: '';
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  display: inline-block;
  top: 3px;
  left: 3px;
  background: rgba(33, 180, 224, 0);
  transform: scale(0);
  transition: all 0.5s ease;
}
.lg-radio.checked .lg-radio__icon{
  border-color: #21b4e0;
}
.lg-radio.checked .lg-radio__icon::after{
  background: rgba(33, 180, 224, 1);
  transform: scale(1);
}
.lg-radio__original {
  display: none;
  outline: medium none!important;
}
</style>

在父组件中使用

// 首先导入
import {lgRadio, lgSearch} from '../../common/index'

// 然后在父组件中使用
<lg-radio v-model="user.sex" label='1'><i class="iconfont lg-boy"></i></lg-radio>
<lg-radio v-model="user.sex" label='0'><i class="iconfont lg-girl"></i></lg-radio>

效果图

初始:

初始

选中后,在选中的过程中会有动画:
选中

详细代码请看https://github.com/Lz-y/Vue-Components/blob/master/radio.vue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值