使用Vue3封装的切换主题开关

本文介绍了如何使用Vue3封装一个切换主题的组件,组件包含白天和黑夜两种状态,支持自定义状态标识。通过具名插槽和自定义事件进行交互,并详细说明了食用方法。同时探讨了在组件中使用CSS变量控制主题色的可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

组件介绍

第一次封装正经组件,更加深刻地感受到了Vue的强大及其带来的便利,记录一下😄打算多搞几个练Vue3

这是一个绑定了两个自定义事件、两个具名插槽的组件,可以切换白天、黑夜两种状态,因为放了两个slot插槽因此支持自定义状态标识

食用方法

1.由于使用的是具名插槽,因此需要在该组件注册至父组件后,在组件内放入两个带有v-slottemplate标签
2.需要通过v-slot传值daynight来分别表示白天与黑夜的主题
3.daynight需要是一个函数
4.若插槽内不传入任何内容,则默认补充汉字“日”与“月”

码上掘金

码上掘金可以嵌套组件吗?这样似乎不好展示效果

代码

组件:

  • 组件内对可能会发生样式变化的容器设置了transition并设置在0.3s完成过渡
  • 组件内使用了ref来获取DOM节点
  • 为了增加稍微丝滑一点的效果,开关中间的圆形按钮会变宽后变窄
  • situation是非常重要的变量,表示目前的主题状态,当发生改变时将调用父组件传入的对应函数daynight,且容器样式将会发生改变
<template lang=""><div class="slip-outer"><div class="slip-block" ref="block"></div><div class="inner"><div class="day" ref="day" @click="changeToDay"><slot name="day">日</slot></div><div class="night" ref="night" @click="changeToNight"><slot name="night">月</slot></div></div></div>
</template>
<script> import { ref, watch } from 'vue'export default {name: 'ChangeStyle',setup(props, context) {let situation = ref(true)const block = ref(null)const day = ref(null)const night = ref(null)function changeToDay() {if (!situation.value) {situation.value = true}}function changeToNight() {if (situation.value) {situation.value = false}}function changeWidth() {block.value.style.width = '50px'setTimeout(() => {block.value.style.width = '30px'}, 80)}watch(situation, (newValue) => {changeWidth()if (newValue === true) {context.emit('day')block.value.style.left = '2px'block.value.style.backgroundColor='#fff'night.value.style.color = '#000'} else {context.emit('night')block.value.style.left = '38px'block.value.style.backgroundColor='#000'night.value.style.color = '#fff'}})return {changeToDay,changeToNight,block,night,day,situation}}} </script>
<style scoped> .slip-outer {height: 30px;width: 70px;border-radius: 15px;background-color: rgb(221, 221, 221);box-shadow: 0px 2px 5px rgb(140, 140, 140) inset;position: relative;}.slip-block {height: 26px;width: 30px;border-radius: 13px;background-color: #fff;position: absolute;z-index: 0;top: 2px;left: 2px;box-shadow: 0px 2px 2px rgb(140, 140, 140);transition: 0.3s;}.inner {display: flex;width: 70px;cursor: pointer;}.inner div {z-index: 1;width: 50%;line-height: 30px;text-align: center;} </style> 

使用实例:

  • 该实例展示的是父组件中使用如上组件的情况
  • 可以像下方实例那样使用CSS变量来更方便地控制主题色(:root.demo中背景色的内容)
  • 函数daynight在控制CSS变量以快速且方便地控制主题色
<template lang=""><div><ChangeStyle @day="day" @night="night"><template v-slot:day>231</template><template v-slot:night>132</template></ChangeStyle><div class="demo" ref:demo></div></div>
</template>
<script> import ChangeStyle from './ChangeStyle.vue';import { ref } from 'vue'export default {name: 'DemoDoc',components: {ChangeStyle},setup(props) {const demo = ref(null)function day() {console.log('day');document.documentElement.style.setProperty('--theme','#fff')}function night() {console.log('night');document.documentElement.style.setProperty('--theme','#000')}return {day,night,demo}}} </script>
<style scoped> :root {--theme: '#fff';}.demo {width: 100px;height: 100px;background-color: var(--theme);border: 1px solid #000;} </style> 

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值