You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
138 lines
4.2 KiB
138 lines
4.2 KiB
|
3 years ago
|
<template>
|
||
|
|
<view class="s-checkbox" :class="c_class" :style="custom_style" @click="handleClick">
|
||
|
|
<slot :scopeParams="scopeParams" :checked="checked">
|
||
|
|
<slot name="icon" :scopeParams="scopeParams" :checked="checked">
|
||
|
|
<s-icon name="success" :size="iconSize" :custom-class="icon_class" :custom-style="icon_style" />
|
||
|
|
</slot>
|
||
|
|
<view v-if="$isDef(label) || labelSlot" class="s-checkbox__label" :style="label_style">
|
||
|
|
<slot name="label" :scopeParams="scopeParams" :checked="checked">{{ label }}</slot>
|
||
|
|
</view>
|
||
|
|
</slot>
|
||
|
|
</view>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script>
|
||
|
|
import componentMixin from '../../mixins/componentMixin';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* s-checkbox 单选框
|
||
|
|
* @description 单选框用于有一个选择,用户只能选择其中一个的场景。搭配s-checkbox-group使用
|
||
|
|
* @property {*} name 标识符
|
||
|
|
* @property {*} label 描述文字
|
||
|
|
* @property {Boolean} disabled 是否禁用单选框
|
||
|
|
* @property {String} shape = [round] 形状
|
||
|
|
* @property {Number|String} iconSize 图标大小
|
||
|
|
* @property {String} checkedColor 单选框的选中状态颜色
|
||
|
|
* @property {String|Object} labelStyle 描述样式
|
||
|
|
* @property {Boolean} labelSlot 是否使用描述信息插槽
|
||
|
|
* @method {Function} toggle(checked) 切换选中状态,传 true 为选中,false 为取消选中,不传参为取反 checked?: boolean
|
||
|
|
* @event {Function} click (event) 点击事件
|
||
|
|
* @event {Function} change (checked) 当绑定值变化时触发的事件
|
||
|
|
* @example <s-checkbox :name="" label="单选框" />
|
||
|
|
*/
|
||
|
|
export default {
|
||
|
|
name: 'SCheckbox',
|
||
|
|
mixins: [componentMixin],
|
||
|
|
props: {
|
||
|
|
value: {
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
name: {
|
||
|
|
default: '',
|
||
|
|
},
|
||
|
|
label: {
|
||
|
|
default: '',
|
||
|
|
},
|
||
|
|
disabled: Boolean,
|
||
|
|
shape: {
|
||
|
|
type: String,
|
||
|
|
default: 'square',
|
||
|
|
},
|
||
|
|
iconSize: [Number, String],
|
||
|
|
checkedColor: String,
|
||
|
|
labelStyle: [String, Object],
|
||
|
|
labelSlot: Boolean,
|
||
|
|
},
|
||
|
|
computed: {
|
||
|
|
c_class() {
|
||
|
|
return this.$mergeClass({
|
||
|
|
's-checkbox--checked': this.checked,
|
||
|
|
's-checkbox--disabled': this.isDisabeld,
|
||
|
|
}, this.custom_class);
|
||
|
|
},
|
||
|
|
checked() {
|
||
|
|
return this.value || this.$sCheckboxGroup?.value.includes(this.name);
|
||
|
|
},
|
||
|
|
checked_color() {
|
||
|
|
return this.checkedColor || this.$sCheckboxGroup?.checkedColor;
|
||
|
|
},
|
||
|
|
isDisabeld() {
|
||
|
|
return this.disabled || this.$sCheckboxGroup?.disabled;
|
||
|
|
},
|
||
|
|
icon_class() {
|
||
|
|
return this.$mergeClass('s-checkbox__icon', {
|
||
|
|
[`s-checkbox__icon--${this.shape}`]: this.shape,
|
||
|
|
});
|
||
|
|
},
|
||
|
|
icon_style() {
|
||
|
|
const style = {};
|
||
|
|
if (this.checked && this.checked_color) {
|
||
|
|
style.backgroundColor = this.checked_color;
|
||
|
|
style.borderColor = this.checked_color;
|
||
|
|
}
|
||
|
|
return this.$mergeStyle(style);
|
||
|
|
},
|
||
|
|
label_style() {
|
||
|
|
return this.$mergeStyle(this.labelStyle);
|
||
|
|
},
|
||
|
|
},
|
||
|
|
created() {
|
||
|
|
this.$sCheckboxGroup = this.$getParentUntil('SCheckboxGroup');
|
||
|
|
if (this.$sCheckboxGroup) {
|
||
|
|
this.$sCheckboxGroup.checkboxGroup.push(this);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
beforeDestroy() {
|
||
|
|
if (this.$sCheckboxGroup) {
|
||
|
|
this.$sCheckboxGroup.checkboxGroup = this.$sCheckboxGroup.checkboxGroup.filter(context => context !== this);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
methods: {
|
||
|
|
handleClick(e) {
|
||
|
|
if (!this.isDisabeld) {
|
||
|
|
this.$emit('click', e);
|
||
|
|
this.toggle();
|
||
|
|
}
|
||
|
|
},
|
||
|
|
toggle(bool) {
|
||
|
|
let checked = !this.checked;
|
||
|
|
if (typeof bool !== 'undefined') {
|
||
|
|
checked = !!bool;
|
||
|
|
if (checked === this.checked) return;
|
||
|
|
}
|
||
|
|
this.$emit('input', checked);
|
||
|
|
this.$emit('change', checked);
|
||
|
|
if (this.$sCheckboxGroup) {
|
||
|
|
const max = parseInt(this.$sCheckboxGroup.max);
|
||
|
|
const names = [...this.$sCheckboxGroup.value];
|
||
|
|
if (checked) {
|
||
|
|
if (max > 0 && names.length >= max) {
|
||
|
|
this.$sCheckboxGroup.$emit('max', names);
|
||
|
|
} else if (!names.includes(this.name)) {
|
||
|
|
names.push(this.name);
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
const index = names.indexOf(this.name);
|
||
|
|
if (index > -1) {
|
||
|
|
names.splice(index, 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
this.$sCheckboxGroup.updateValue(names);
|
||
|
|
}
|
||
|
|
},
|
||
|
|
},
|
||
|
|
};
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style lang="scss" src="./index.scss"></style>
|