| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 | <template>  <view    class="ui-radio ss-flex ss-col-center"    @tap="onRaido"    :class="[{ disabled: disabled }, { img: src }, ui]"    :style="[customStyle]"  >    <slot name="leftLabel"></slot>    <view      v-if="!none"      class="ui-radio-input"      :class="[isChecked ? 'cur ' + bg : unbg, src ? 'radius' : 'round']"    ></view>    <image class="ui-radio-img radius" v-if="src" :src="src" mode="aspectFill"></image>    <view class="ui-radio-content" v-else>      <slot>        <view class="ui-label-text" :style="[labelStyle]">{{ label }}</view>      </slot>    </view>    <view      v-if="ui.includes('card')"      class="ui-radio-bg round"      :class="[isChecked ? 'cur ' + bg : '']"    ></view>  </view></template><script setup>  /**   * 单选 - radio   *   *   * property {Object} customStyle 												- 自定义样式   * property {String} ui 														- radio样式Class   * property {String} modelValue													- 绑定值   * property {Boolean} disabled													- 是否禁用   * property {String} bg															- 选中时背景Class   * property {String} unbg														- 未选中时背景Class   * property {String} src														- 图片选中radio   * property {String} label														- label文本   * property {Boolean} none														- 是否隐藏raido按钮   *   * @slot default																- 自定义label样式   * @event {Function} change														- change事件   *   */  import { computed, reactive, watchPostEffect, getCurrentInstance } from 'vue';  const vm = getCurrentInstance();  // 组件数据  const state = reactive({    currentValue: false,  });  // 定义事件  const emits = defineEmits(['change', 'update:modelValue']);  // 接收参数  const props = defineProps({    customStyle: {      type: Object,      default: () => ({}),    },    ui: {      type: String,      default: 'check', //check line    },    modelValue: {      type: [String, Number, Boolean],      default: false,    },    disabled: {      type: Boolean,      default: false,    },    bg: {      type: String,      default: 'ui-BG-Main',    },    unbg: {      type: String,      default: 'borderss',    },    src: {      type: String,      default: '',    },    label: {      type: String,      default: '',    },    labelStyle: {      type: Object,      default: () => ({}),    },    none: {      type: Boolean,      default: false,    },  });  watchPostEffect(() => {    state.currentValue = props.modelValue;    emits('update:modelValue', state.currentValue);  });  // 是否选中  const isChecked = computed(() => state.currentValue);  // 点击  const onRaido = () => {    if (props.disabled) return;    state.currentValue = !state.currentValue;    emits('update:modelValue', state.currentValue);    emits('change', {      label: props.label,      value: state.currentValue,    });  };</script><style lang="scss" scoped>  .ui-radio {    display: flex;    align-items: center;    margin: 0 0.5em 0 0;    height: 18px;    .ui-radio-input {      margin: 0 0.5em 0 0;      display: inline-block;      width: 18px;      height: 18px;      vertical-align: middle;      line-height: 18px;      &::before {        content: '';        position: absolute;        width: 0;        height: 0;        background-color: currentColor;        border-radius: 18px;        @include position-center;      }    }    .ui-radio-input.cur {      position: relative;      &::before {        width: 10px;        height: 10px;        transition: $transition-base;      }    }    &:last-child {      margin: 0 0.14286em;    }    &.check {      .ui-radio-input {        &::before {          font-family: 'colorui';          content: '\e69f';          width: 18px;          height: 18px;          font-size: 0;          background-color: transparent;        }      }      .ui-radio-input.cur {        &::before {          width: 18px;          height: 18px;          font-size: 1em;          transform: scale(0.8);          text-align: center;          line-height: 18px;        }      }    }    &.line {      .ui-radio-input.cur {        &::before {          width: calc(100% - 2px);          height: calc(100% - 2px);          background-color: var(--ui-BG);        }        &::after {          content: '';          position: absolute;          width: 10px;          height: 10px;          background-color: inherit;          border-radius: 50%;          @include position-center;        }      }    }    &.lg {      .ui-radio-input {        font-size: 18px;      }    }    &.img {      position: relative;      margin: 0 0.28572em 0;      .ui-radio-input {        width: 42px;        height: 42px;        border-radius: 0px;        position: absolute;        margin: 0;        left: -1px;        top: -1px;        &::before {          width: 40px;          height: 40px;          border-radius: $radius;        }        &.cur {          width: 44px;          height: 44px;          top: -2px;          left: -2px;          border-radius: 7px !important;          opacity: 0.8;        }      }      .ui-radio-img {        width: 40px;        height: 40px;        display: block;        overflow: hidden;        border-radius: 10px;      }    }    &.card {      display: flex;      margin: 30rpx;      padding: 30rpx;      position: relative;      border-radius: $radius !important;      flex-direction: row-reverse;      justify-content: space-between;      .ui-radio-bg {        content: '';        position: absolute;        width: 200%;        height: 200%;        transform: scale(0.5);        border-radius: #{$radius * 2} !important;        z-index: 0;        left: 0;        top: 0;        transform-origin: 0 0;        background-color: var(--ui-BG);      }      .ui-radio-input {        position: relative;        z-index: 1;        margin-right: 0;      }      .ui-radio-bg::after {        content: '';        position: absolute;        width: calc(200% - 16px);        height: calc(200% - 16px);        transform: scale(0.5);        transform-origin: 0 0;        background-color: var(--ui-BG) !important;        left: 4px;        top: 4px;        border-radius: #{$radius * 2 + 8} !important;        z-index: 0;      }      .ui-radio-content {        position: relative;        z-index: 1;        display: flex;        align-items: center;        flex: 1;      }    }  }</style>
 |