CheckboxGroup 元件與 RadioGroup 元件類似,但是也存在不同點,在於 CheckboxGroup 為多選組,並且需要 Checkbox 可以單獨使用。基於 元件進行二次封裝的 CheckboxGroup 元件
1. 例項
程式碼
<!-- 基礎用法 -->
<fat-checkbox-group v-model="anotherValue">
<fat-checkbox value="あらがき ゆい">
<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-checkbox>
<fat-checkbox value="石原さとみ">
<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-checkbox>
</fat-checkbox-group>
複製程式碼
例項地址:CheckboxGroup 例項
程式碼地址:Github UI-Library
2. 原理
Checkbox
首先單獨實現 Checkbox 元件,它是由 label
和 input
兩部分構成,主要區分兩個狀態,checked
以及 disabled
。
<template>
<label
:class="[
'checkbox-item',
{ 'is-checked': isChecked },
{ 'is-disabled': isDisabled }
]"
@click.stop="handleClick"
>
<span class="checkbox-input">
<fat-icon name="check"/>
</span>
<input
v-if="false"
type="checkbox"
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, Boolean]
}
},
model: {
prop: "propValue",
event: "select"
},
computed: {
isGroup() {
return this.$parent.$options._componentTag === "fat-checkbox-group";
},
isDisabled() {
return this.$parent.disabled || this.disabled;
},
isChecked() {
const { isGroup, model } = this;
if (!isGroup) return model;
const {
value,
$parent: { value: selectItems }
} = this;
return selectItems.some(item => item === value);
},
model: {
get() {
return this.isGroup ? this.$parent.value : this.propValue;
},
set(newValue) {
const { isGroup, isChecked } = this;
if (isGroup) {
isChecked
? this.$parent.deleteItem(newValue)
: this.$parent.selectItem(newValue);
} else {
this.$emit("select", newValue);
}
}
}
},
methods: {
handleClick(event) {
const { isDisabled, isGroup, model, value } = this;
if (!isDisabled) {
this.model = isGroup ? value : !model;
}
}
}
};
</script>
複製程式碼
同 Radio
一樣,由於需要實現 Checkout
可以單獨使用的,所以不採用 provide / inject
api,而是利用 this.$parent.$options._componentTag
判斷,當前元件是否為 Group
。
同時,依據當前元件是否為 Group
來定義 isDisabled
、isChecked
等狀態的判斷條件,例如
isChecked() {
const { isGroup, model } = this;
if (!isGroup) return model;
const {
value,
$parent: { value: selectItems }
} = this;
return selectItems.some(item => item === value);
}
複製程式碼
如果當前為多選組,就會利用 some
來判斷當前 Checkout 的 value 是否在其中,然後如果單獨使用,則直接返回 model
。
同樣,model
的值也是依據 isGroup
進行區分
model: {
get() {
return this.isGroup ? this.$parent.value : this.propValue;
},
set(newValue) {
const { isGroup, isChecked } = this;
if (isGroup) {
isChecked ? this.$parent.deleteItem(newValue)
: this.$parent.selectItem(newValue);
} else {
this.$emit("select", newValue);
}
}
}
複製程式碼
CheckboxGroup
則是在 Checkbox 的外部包裹一層 Group 用於,實現組的概念
<template>
<div class="checkbox-group-wrapper" name="checkbox-group">
<slot></slot>
</div>
</template>
<script>
export default {
name: "checkbox-group",
props: {
value: { type: Array, required: true },
disabled: { type: Boolean }
},
model: {
prop: "value",
event: "select"
},
watch: {
value(newValue) {
this.$emit("change", newValue);
}
},
methods: {
selectItem(item) {
const { value } = this;
this.$emit("select", [...value, item]);
},
deleteItem(item) {
const { value: selectItems } = this;
this.$emit(
"select",
selectItems.filter(selectitem => selectitem !== item)
);
}
}
};
</script>
複製程式碼
在 Checkbox-Group
內維護了
methods: {
selectItem(item) {
const { value } = this;
this.$emit("select", [...value, item]);
},
deleteItem(item) {
const { value: selectItems } = this;
this.$emit(
"select",
selectItems.filter(selectitem => selectitem !== item)
);
}
}
複製程式碼
用於和 Checkbox
通訊,如果當前是多選組的形式,則需要利用 selectItem
以及 deleteItem
來對其進行增減。
3. 總結
Checkbox-Group 元件的開發,主要是父子元件之間的資料傳遞。
往期文章:
- 從零實現Vue的元件庫(零)- 基本結構以及構建工具
- 從零實現Vue的元件庫(一)- Toast 實現
- 從零實現Vue的元件庫(二)- Slider 實現
- 從零實現Vue的元件庫(三)- Tabs 實現
- 從零實現Vue的元件庫(四)- File-Reader 實現
- 從零實現Vue的元件庫(五)- Breadcrumb 實現
- 從零實現Vue的元件庫(六)- Hover-Tip 實現
- 從零實現Vue的元件庫(七)- Message-Box 實現
- 從零實現Vue的元件庫(八)- Input 實現
- 從零實現Vue的元件庫(九)- InputNumber 實現
- 從零實現Vue的元件庫(十)- Select 實現
- 從零實現Vue的元件庫(十一)- Date-picker 實現
- 從零實現Vue的元件庫(十二)- Table 實現
- 從零實現Vue的元件庫(十三)- Pagination 實現
- 從零實現Vue的元件庫(十四)- RadioGroup 實現
- 從零實現Vue的元件庫(十五)- CheckboxGroup 實現
原創宣告: 該文章為原創文章,轉載請註明出處。