RadioGroup 組件實現思路

基於 組件進行二次封裝的 RadioGroup 組件javascript

RadioGroup 組件的難點在於:
  • radioradioGroup 之間的聯動關係、數據綁定關係,使得 radio 能夠單獨使用或者組合;
  • 利用插槽能夠方便擴展 radio

1. 實例

最終效果

代碼html

<!-- 基礎用法 -->
<fat-radio v-model="otherValue" :value="1">
    <fat-hover-tip type="right-center">
        <template slot="hover-part">あらがき ゆい</template>
    <template slot="tip-part">
        <img src="/static/img/gakki.jpg" style="width: 100px" alt="示意圖">
    </template>
    </fat-hover-tip>
</fat-radio>
<fat-radio v-model="otherValue" :value="2">
    <fat-hover-tip type="right-center">
        <template slot="hover-part">石原さとみ</template>
        <template slot="tip-part">
            <img src="/static/img/u=4046980169,286278015&fm=26&gp=0.jpg" style="width: 100px" alt="示意圖" >
        </template>
    </fat-hover-tip>
</fat-radio>
<!-- 禁用狀態 -->
<fat-radio-group v-model="anotherValue">
    <fat-radio :value="1">備選項</fat-radio>
    <fat-radio :value="2" disabled>備選項</fat-radio>
</fat-radio-group>
複製代碼

實例地址:RadioGroup 實例java

代碼地址:Github UI-Librarygit

2. 原理

Radiogithub

首先單獨實現 Radio 組件,它是由 labelinput 兩部分構成,主要區分兩個狀態,checked 以及 disabledapi

<template>
  <label
    :class="[ 'radio-item', { 'is-checked': value === model }, { 'is-disabled': isDisabled } ]"
    @click.stop="handleClick"
  >
    <!-- checked 時展現被選中狀態 -->
    <span class="radio-inner"></span>
    <input
      class="f-hide"
      type="radio"
      :disabled="isDisabled"
      v-bind="$attrs"
      :value="model"
      @click.stop
    >
    <!-- 提示文案(可插入組件) -->
    <slot></slot>
  </label>
</template>

<script>
export default {
    props: {
        value: {
            type: [String, Number],
            required: true
        },
        disabled: {
            type: [Boolean],
            default: false
        },
        propValue: {
            type: [String, Number]
        }
    },
    model: {
        prop: "propValue",
        event: "select"
    },
    computed: {
        isGroup() {
            return this.$parent.$options._componentTag === "fat-radio-group";
        },
        isDisabled() {
            return this.$parent.disabled || this.disabled;
        },
        model: {
            get() {
                return this.isGroup ? this.$parent.value : this.propValue;
            },
            set(newValue) {
                this.isGroup ? this.$parent.$emit("select", newValue) : this.$emit("select", newValue);
            }
        }
    },
    methods: {
        handleClick(event) {
            !this.isDisabled && (this.model = this.value);
        }
    }
};
</script>
複製代碼

因爲須要實現 Radio 能夠單獨使用的,因此不採用 provide / inject api,而是利用 this.$parent.$options._componentTag 判斷,當前組件是否爲 Group。同時實現數據的傳遞bash

model: {
    get() {
        return this.isGroup ? this.$parent.value : this.propValue;
    },
    set(newValue) {
        this.isGroup ? this.$parent.$emit("select", newValue) : this.$emit("select", newValue);
    }
}
複製代碼

一樣,也是依據 isGroup 進行區分,來選擇是 $emit 父組件仍是子組件。ide

RadioGroup工具

則是在 Radio 的外部包裹一層 Group 用於,實現組的概念post

<template>
  <div :class="[ 'radio-group' ]" name="radio-group">
    <slot></slot>
  </div>
</template>
<script> export default { name: "radio-group", props: { value: { type: [String, Number] }, disabled: { type: Boolean } }, model: { prop: "value", event: "select" }, watch: { value(newValue) { this.$emit("change", newValue); } } }; 複製代碼

3. 總結

RadioGroup 組件的開發,主要是父子組件之間的數據傳遞以及相關的結構分離。

往期文章:

原創聲明: 該文章爲原創文章,轉載請註明出處。

相關文章
相關標籤/搜索