一. Checkbox-Group 组件提供的属性和事件
1.1 属性
以下是 checkbox-Group
组件提供的属性:
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
value / v-model | 绑定值 | array | -- | -- |
size | 多选框组尺寸,仅对按钮形式的 Checkbox 或带有边框的 Checkbox 有效 | string | medium / small / mini | -- |
disabled | 是否禁用 | boolean | -- | false |
min | 可被勾选的 checkbox 的最小数量 | number | -- | -- |
max | 可被勾选的 checkbox 的最大数量 | number | -- | -- |
text-color | 按钮形式的 Checkbox 激活时的文本颜色 | string | -- | #ffffff |
fill | 按钮形式的 Checkbox 激活时的填充色和边框色 | string | -- | #409EFF |
1.2 事件
事件名称 | 说明 | 回调参数 |
---|---|---|
change | 当绑定值变化时触发的事件 | 更新后的值 |
二. 按照步骤去实现 Checkbox-Group 组件的属性和事件
- 注册组件。
checkbox-group
的基本template
部分。- 绑定值
v-model
的处理。 - 禁用
disabled
属性的处理。 - 可被勾选的最小数量
min
,最大数量max
的处理。 - 尺寸
size
属性的处理。 - 接收
text-color
和fill
属性,用于后续讲解的checkbox-button
组件。
三. Checkbox 组件属性和事件的具体实现
3.1 注册组件
新建一个 checkbox-group.vue
文件,设置组件的 name
和 componentName
都为 ElCheckboxGroup
。
在 main.js
文件里面引入这个组件,并且使用 Vue.component
来全局注册这个组件。
3.2 checkbox-group 的基本 template 部分
html
<template>
<div class="el-checkbox-group" role="group" aria-label="checkbox-group">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'ElCheckboxGroup',
componentName: 'ElCheckboxGroup',
}
</script>
- 一个
div
标签内部包裹父组件内部传过来的内容,div
设置属性role="group"
,aria-label="checkbox-group"
。 aria-label
属性为无障碍 API,用来给元素增加标签描述,接收字符串为参数。
3.3 绑定值 v-model 的处理
实现步骤:
- 新建一个文件,文件内部引入
checkbox-group
组件,并且在checkbox-group
组件内容写入三个checkbox
组件,给checkbox
组件增加label
属性,checkbox-group
组件增加v-model
绑定值。
html
<template>
<el-checkbox-group v-model="checkList">
<el-checkbox :label="1">备选项1</el-checkbox>
<el-checkbox :label="2">备选项2</el-checkbox>
<el-checkbox :label="3">备选项3</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
data() {
return {
checkList: [1]
}
}
}
</script>
- 在
checkbox-group
组件中用props
使用默认的value
属性用来接收v-model
的绑定值。
js
props: {
value: {}
}
- 在
checkbox
组件中设置计算属性isGroup
来判断该多选框是否被包含在多选框组里面。如果被包含在多选框组里面,则用变量_checkboxGroup
保存多选框组的信息。
js
isGroup() {
// parent 变量保存组件的父级元素信息
let parent = this.$parent;
while (parent) {
if (parent.$options.componentName !== 'ElCheckboxGroup') {
// 如果父级的 componentName 不是 ElCheckboxGroup 则继续向上查找
parent = parent.$parent;
} else {
// 如果父级的 componentName 是 ElCheckboxGroup
// 用变量 _checkboxGroup 保存父级信息,并且返回 true
this._checkboxGroup = parent;
return true;
}
}
return false;
},
- 在
checkbox
组件中设置计算属性store
根据多选框还是多选框组来获取不同的value
值。判断_checkboxGroup
是否存在,如果存在,则取多选框组的值,否则取多选框的值。
js
store() {
return this._checkboxGroup ? this._checkboxGroup.value : this.value;
},
- 修改计算属性
model
的getter
和setter
方法,新增判断如果是多选框组,则获取/设置多选框组的值,否则获取/设置多选框的值。
(1)getter
方法修改成如果 isGroup
是 true
,则取计算属性 store
的值,否则还是取之前 checkbox
的 value
值。
js
computed: {
...
model: {
get() {
return this.isGroup
? this.store : this.value !== undefined
? this.value : this.selfModel;
},
}
}
(2)setter
方法修改成如果 isGroup
是 true
,则向上查找并触发多选框组的 input
方法。
js
import Emitter from 'element-ui/src/mixins/emitter';
mixins: [Emitter],
computed: {
...
model: {
set(val) {
if (this.isGroup) {
this.dispatch('ElCheckboxGroup', 'input', [val]);
} else {
this.$emit('input', val);
this.selfModel = val;
}
},
}
}
- 在
handleChange
方法中增加如果是多选框组,则触发checkbox-group
组件的change
方法。
js
methods: {
handleChange(ev) {
...
// 需要放在 nextTick 中,否则得到的是上一次的值
this.$nextTick(() => {
if (this.isGroup) {
this.dispatch('ElCheckboxGroup', 'change', [this._checkboxGroup.value]);
}
});
}
}
- 选中状态在之前讲
checkbox
组件时已经处理过为数组时的选中了。
3.4 禁用 disabled 属性的处理
实现步骤:
- 在引入
checkbox-group
组件的文件中增加disabled
属性。
html
<template>
<el-checkbox-group v-model="checkList" disabled>
<el-checkbox :label="1">备选项1</el-checkbox>
<el-checkbox :label="2">备选项2</el-checkbox>
<el-checkbox :label="3">备选项3</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
data() {
return {
checkList: [1]
}
},
}
</script>
checkbox-group
组件中用props
接收disabled
属性。
js
props: {
disabled: Boolean,
}
- 修改
checkbox
组件中的计算属性isDisabled
,判断isGroup
是否为true
,如果为true
则获取多选框组的disabled
属性。
js
computed: {
isDisabled() {
return this.isGroup
? this._checkboxGroup.disabled || this.disabled
: this.disabled
},
}
3.5 可被勾选的最小数量 min,最大数量 max 的处理
实现步骤:
- 引入
checkbox-group
组件的文件中增加最小数量min
,最大数量max
这两个属性。
html
<template>
<el-checkbox-group v-model="checkList" :min="1" :max="2">
<el-checkbox :label="1">备选项1</el-checkbox>
<el-checkbox :label="2">备选项2</el-checkbox>
<el-checkbox :label="3">备选项3</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
data() {
return {
checkList: [1]
}
},
}
</script>
- 在
checkbox-group
组件中使用props
接收min
和max
。
js
props: {
min: Number,
max: Number,
}
- 在
checkbox
组件的data
中增加变量isLimitExceeded
,用于判断勾选数量是否超出限制。
js
data() {
return {
...
isLimitExceeded: false
}
}
- 修改计算属性
model
,判断如果超出了最小、最大限制则将变量isLimitExceeded
设置为true
,并且不能触发checkbox-group
组件的input
方法。
js
computed: {
...
model: {
...
set(val) {
if (this.isGroup) {
(this._checkboxGroup.min !== undefined &&
val.length < this._checkboxGroup.min &&
(this.isLimitExceeded = true));
(this._checkboxGroup.max !== undefined &&
val.length > this._checkboxGroup.max &&
(this.isLimitExceeded = true));
this.isLimitExceeded === false &&
this.dispatch('ElCheckboxGroup', 'input', [val]);
} else {
this.$emit('input', val);
this.selfModel = val;
}
}
}
}
- 在
handleChange
方法中增加判断如果isLimitExceeded
已经超出了限制,则不能触发change
方法。
js
methods: {
handleChange(ev) {
if (this.isLimitExceeded) return;
...
}
}
- 增加计算属性
isLimitDisabled
,判断此次点击之后该checkbox
是否会被禁止点击。如果min
或max
有任意属性存在,分两种情况:
第一种:当已选数量大于等于最大限制数量时,禁用没有选中的checkbox
。
第二种:当已选数量小于等于最小限制数量时,禁用已经选中的checkbox
。
js
computed: {
isLimitDisabled() {
const { max, min } = this._checkboxGroup;
return !!(max || min) &&
(this.model.length >= max && !this.isChecked) ||
(this.model.length <= min && this.isChecked);
},
}
- 修改计算属性
isDisabled
,增加isLimitDisabled
的判断。
js
computed: {
...
isDisabled() {
return this.isGroup
? this._checkboxGroup.disabled || this.disabled || this.isLimitDisabled
: this.disabled
},
...
}
3.6 尺寸 size 属性的处理
实现步骤:
- 引入
checkbox-group
组件的文件中增加size
属性,size="mini"
,并且在每一个checkbox
上面增加border
属性。
html
<template>
<el-checkbox-group v-model="checkList" size="mini">
<el-checkbox :label="1" border>备选项1</el-checkbox>
<el-checkbox :label="2" border>备选项2</el-checkbox>
<el-checkbox :label="3" border>备选项3</el-checkbox>
</el-checkbox-group>
</template>
<script>
export default {
data() {
return {
checkList: [1]
}
},
}
</script>
- 在
checkbox-group
组件中使用props
获取传入的size
属性。
js
props: {
size: String,
}
- 在
checkbox-group
组件中设置计算属性checkboxGroupSize
监听size
属性的改变。
js
computed: {
checkboxGroupSize() {
return this.size;
}
}
- 在
checkbox
组件中修改计算属性checkboxSize
,如果isGroup
为true
,优先获取checkbox-group
传入的size
。
js
computed: {
...
checkboxSize() {
return this.isGroup
? this._checkboxGroup.checkboxGroupSize || this.size
: this.size;
}
}
3.7 接收 text-color 和 fill 属性,用于后续讲解的 Checkbox-button 组件
在 checkbox-group
组件中使用 props
接收传入的 text-color
和 fill
属性,这两个属性是 checkbox-button
组件使用到的。
js
props: {
...
fill: String,
textColor: String
}
四. 整体代码详解
包含 Checkbox-Group
与 Form
组件相互作用的部分。
html
<template>
<div class="el-checkbox-group" role="group" aria-label="checkbox-group">
<slot></slot>
</div>
</template>
<script>
import Emitter from '../../utils/mixins/emitter';
export default {
name: 'ElCheckboxGroup',
mixins: [Emitter],
inject: {
elFormItem: {
default: ''
}
},
componentName: 'ElCheckboxGroup',
props: {
value: {}, // checkbox-group 的 value 值
disabled: Boolean,
min: Number, // 最小限制数量
max: Number, // 最大限制数量
size: String,
fill: String, // checkbox-button 组件样式用到的 fill 填充
textColor: String // checkbox-button 组件样式用到的 textColor 文字颜色
},
computed: {
// 获取 Form-Item 组件的 elFormItemSize 变量
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
// Checkbox-Group 组件的尺寸计算
checkboxGroupSize() {
// 优先级:group-size > Form-Item > Form
return this.size || this._elFormItemSize;
}
},
watch: {
value(value) {
// 监听 value 值的变化,当 value 值改变时,向 Form-Item 组件派发 el.form.change 自定义事件
this.dispatch('ElFormItem', 'el.form.change', [value]);
}
}
}
</script>