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 实现
原创声明: 该文章为原创文章,转载请注明出处。
所有评论(0)