共计 2314 个字符,预计需要花费 6 分钟才能阅读完成。
本人写了一个视频播放器组件,为了缩小 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>
正文完