本人写了一个视频播放器组件,为了缩小npm包的体积外面用到的组件都是本人封装的

工作中switch开关组件组件中都有,然而这个组件本人会封装吗?这篇文章教大家使用简略的html元素实现就能实现一个Vue3版本的switch组件。

先看一下图例 开关的状态


vue3实现switch开关组件

为什么说我这个组件简略呢?
先上html代码 非常简单

<template>    <div class="d-switch" :class="{ 'is-checked': checked }">        <input            class="d-switch__input"            ref="input"            type="checkbox"            :checked="checked"            @change="handleInput"            :true-value="trueValue"            :false-value="falseValue"        />        <span class="d-switch_action"></span>    </div></template>

这里解释一下逻辑

1.d-switch元素:最外层就是开关的盒子 用来定义背景色和宽高 通过 classis-checked管制开和关的款式
2.d-switch__input元素:认真看一下这个开关组件里我并没有应用@click事件,是因为click事件都是通过这个input元素实现的。input的值也能够通过true-valuefalse-value 自定义

  1. d-switch_action:这个元素就是开关里的圆色白点。
  2. 很重要的一点,因为这个组件是通过点击input获取到以后状态,所以这里要把inputz-index设置为1,笼罩在span标签下面,而后把opacity设置为0.这样你看到的是 span标签的款式,然而你点击的其实是input触发的事件
<style lang='less' scoped>.d-switch {    position: relative;    height: 18px;    transition: background 0.2s;    width: v-bind(width);    background: rgb(117, 117, 117);    border-radius: 10px;    display: inline-flex;    align-items: center;    vertical-align: middle;    .d-switch__input {        position: relative;        z-index: 1;        margin: 0;        width: 100%;        height: 100%;        opacity: 0;    }    .d-switch_action {        position: absolute;        transition: 0.2s;        left: 2px;        top: 2px;        z-index: 0;        height: 14px;        width: 14px;        background: #fff;        border-radius: 50%;    }    &.is-checked {        background: v-bind(activeColor);        .d-switch_action {            left: 100%;            background: #fff;            margin-left: -18px;        }    }}</style>

最初是增加props属性和事件

import { computed, ref, nextTick } from 'vue'const props = defineProps({    modelValue: {  //绑定值,必须等于active-value或inactive-value,默认为Boolean类型  如果是vue2 这里绑定是 `value`        type: [Number, String, Boolean],    },    trueValue: { //switch 关上时的值 能够自定义组件关上的时的值         type: [Number, String, Boolean],        default: true,    },    falseValue: { //    switch 敞开时的值  能够自定义组件敞开的时的值         type: [Number, String, Boolean],        default: true,    },    activeColor: { //switch 关上时的背景色        type: [String],        default: '#409EFF',    }})const emits = defineEmits(['update:modelValue', 'change'])//获取input元素const input = ref(null)//判断以后组件是否是关上状态const checked = computed(() => {    //因为能够自定义关上和敞开的值 所以这里必须判断 v-model绑定的值 === 组件自定义关上的值    return props.modelValue === props.trueValue})//input事件 获取以后input事件const handleInput = () => {    nextTick(() => {        const val = input.value.checked        emits("update:modelValue", val); // 开关点击后的状态传给v-model          emits("change", val); //给组件减少change 事件    })};

应用示例

<template>  <div>    获取的值{{value1}}    <my_switch v-model="value1"></my_switch>  </div></template><script setup>import my_switch from "./my_switch"; //这里引入上一个文件(目录本人定)import {ref} fron 'vue'let value1 = ref(false)</script>