web技术支持| 基于vue3实现自己的组件库第三章:Checkbox组件

大家好今天的内容是基于vue3实现自己的组件库系列第二章,本文默认你会安装和创建vue3项目,如果不会请参考vue官网

Checkbox.vue Template

<template>
    <div :class='["v-checkbox", { border }, 
    { disabled: proxyDisabled || disabled || computedDisabled }, 
    { medium: border && (size || proxySize) === "medium" },
    { small: border && (size || proxySize) === "small" },
    { mini: border && (size || proxySize) === "mini" },
    { "v-radio-checked": computedChecked && !computedDisabled }]' 
    @click.stop='handleChecked'>
        <input type="checkbox" :checked='computedChecked' :disabled='disabled' :name='name || modelValue || proxyValue' :value='label'>
        <span :class='["v-radio-input", { checked: computedChecked }, { indeterminate }]'></span>
        <span :class='["v-radio-label", { active: computedChecked }]'>
            <slot></slot>
        </span>
    </div>
</template>

Checkbox.vue Script

<script>
import { inject, computed } from 'vue';
import VairCheckout from '@/types/checkout';
export default {
    name: 'checkbox',
    props: VairCheckout,
    setup (props, ctx) {
        const proxyValue = inject('proxyValue');
        const proxyDisabled = inject('proxyDisabled');
        const proxySize = inject('proxySize');
        const proxyMin = inject('proxyMin');
        const proxyMax = inject('proxyMax');
        const update = inject('update');

        const handleChecked = () => {
            if (!props.disabled && !computedDisabled.value) {
                if (proxyValue) {
                    ctx.emit('change', props.label);
                    update(props.label);
                } else {
                    const value = props.modelValue? false : true;
                    ctx.emit('update:modelValue', value);
                    ctx.emit('change', value);
                }
            }
        };

        const computedDisabled = computed(() => {
            var bool = false;
            if (proxyMax || proxyMin) {
                if (proxyMax && proxyValue.value.length >= proxyMax.value) {
                    if (!computedChecked.value) {
                        bool = true;
                    }
                } else if (proxyMin && proxyValue.value.length <= proxyMin.value) {
                    if (computedChecked.value) {
                        bool = true;
                    }
                }
            }
            return bool;
        });

        const computedChecked = computed(() => {
            if (proxyValue) { // 如果是被 checkbox-group 组件包裹着的话就判断数组中有没有符合的值
                return proxyValue.value.find(item => item === props.label);
            } else {
                return props.modelValue;
            }
        });

        return {
            handleChecked,
            proxyDisabled,
            computedChecked,
            computedDisabled,
            proxyValue,
            proxySize
        }
    }
}
</script>

Checkbox.js

const VairCheckout = {
    modelValue: null, // 绑定值
    name: String, // 原生 name 属性
    label: [Number, String, Boolean], // Checkbox 的 value
    size: String, // Radio 的尺寸,仅在 border 为真时有效
    indeterminate: { // 设置 indeterminate 状态,只负责样式控制
        type: Boolean,
        default: () => {
            return false
        }
    },
    border: { // 是否显示边框
        type: Boolean,
        default: () => {
            return false
        }
    },
    disabled: { // 是否禁用
        type: Boolean,
        default: () => {
            return false
        }
    },
};

// Event
    // change (label)

export default VairCheckout;

Checkbox.vue Style

<style lang='less' scoped>
@import url('../../assets/css/animation.css');
.v-checkbox {
    display: flex;
    align-items: center;
    cursor: pointer;
    transition: .3s;
    margin-right: 30px;
    &:last-child {
        margin-right: 0;
    }
    input {
        display: none;
    }
    .v-radio-input {
        border: 1px solid#dcdfe6;
        width: 14px;
        height: 14px;
        position: relative;
        box-sizing: border-box;
        border-radius: 2px;
        transition: .3s;
        &:after {
            box-sizing: content-box;
            content: "";
            border: 1px solid #fff;
            border-left: 0;
            border-top: 0;
            height: 7px;
            left: 4px;
            position: absolute;
            top: 1px;
            transform: rotate(45deg) scaleY(0);
            width: 3px;
            transition: transform .15s ease-in .05s;
            transform-origin: center;
        }
    }
    .indeterminate {
        background-color: #409eff;
        border-color: #409eff;
        position: relative;
        &:after {
            content
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值