I wrote a video player component, in order to reduce the volume of NPM package used in the components are their own packaging

The switch switch component is present in the work component, but will this component encapsulate itself? This article teaches you how to implement a Vue3 version of the Switch component using a simple HTML element implementation.

Take a look at the status of the legend switch

Click to view preview vue3 implementation switch component

Why is my component simple? The HTML code is pretty simple to start with

<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>
Copy the code

Here’s the logic

1. The d-switch element: the outer layer of the switch box defines the background color and width and height of the classis-checked control on and off style. If you look closely at this switch component I don’t use @click events because click events are implemented through this input element. The input value can also be customized with true-value and false-value 3. d-switch_action: This element is the round white dot in the switch. 4. It is important to note that the current state of the component is obtained by clicking on input, so set z-index of input to 1, overwriting the SPAN tag, and setting opacity to 0. So you see the style of the SPAN tag, but you’re actually clicking on the input event

<style lang='less' scoped>
.d-switch {
    position: relative;
    height: 18px;
    transition: background 0.2 s;
    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.2 s;
        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>
Copy the code

Finally, add the props properties and events

import { computed, ref, nextTick } from 'vue'
const props = defineProps({
    modelValue: {  // The binding value must be equal to active-value or inactive-value. The default value is Boolean. If it is vue2, the binding is' value '
        type: [Number.String.Boolean],},trueValue: { // Switch value when opened You can customize the value when the component is opened
        type: [Number.String.Boolean].default: true,},falseValue: { // Switch value when closed You can customize the value when the component is closed
        type: [Number.String.Boolean].default: true,},activeColor: { // Background color when switch is on
        type: [String].default: '#409EFF',}})const emits = defineEmits(['update:modelValue'.'change'])

// Get the input element
const input = ref(null)
// Check whether the current component is open
const checked = computed(() = > {
    // The value of the V-model binding === the value of the component's custom open value must be determined
    return props.modelValue === props.trueValue
})
// Input gets the current input event
const handleInput = () = > {
    nextTick(() = > {
        const val = input.value.checked
        emits("update:modelValue", val); // Switch clicked state is passed to V-Model
        emits("change", val); // Add the change event to the component})};Copy the code

Use the sample

<template>
  <div>Value {{value1}}<my_switch v-model="value1"></my_switch>
  </div>
</template>

<script setup>
import my_switch from "./my_switch"; // Insert the previous file (directory of your own)
import {ref} fron 'vue'
let value1 = ref(false)
</script>
Copy the code