本人写了一个视频播放器组件,为了缩小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-value
和false-value
自定义
d-switch_action
:这个元素就是开关里的圆色白点。- 很重要的一点,因为这个组件是通过点击input获取到以后状态,所以这里要把
input
的z-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>