feat: 添加 ModuleSwitcher 组件及其子组件,更新 Husky 配置文档

This commit is contained in:
zhongyidian committed 2025-09-14 11:45:45 +08:00
1 parent cf7a5d5e81
commit b9c6308d59
5 files changed
+87 -1

No files matched your search

@@ -0,0 +1,79 @@
<template>
<div
:style="{ backgroundImage: getBackgroundImage(currentImage) }"
:class="['module-btn', module.className, { selected: isSelected }]"
>
<div :class="['btn-mask', module.maskConfig.className]" @click="$emit('click')"></div>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { getBackgroundImage } from '@/utils'
// 定义模块类型
type ModuleType = 'vlog' | 'film' | 'interview'
// 模块配置接口
interface ModuleConfig {
type: ModuleType
normalImage: string
selectedImage: string
className: string
maskConfig: {
className: string
position: string
size: string
transform: string
}
}
// Props定义
interface Props {
module: ModuleConfig
isSelected: boolean
}
// Emits定义
interface Emits {
(e: 'click'): void
}
const props = defineProps<Props>()
defineEmits<Emits>()
// 计算当前显示的图片
const currentImage = computed(() => {
return props.isSelected ? props.module.selectedImage : props.module.normalImage
})
</script>
<style scoped>
.module-btn {
position: absolute;
transition:
transform 0.2s ease,
z-index 0.2s ease;
z-index: 1;
pointer-events: none;
}
.btn-mask {
position: absolute;
cursor: pointer;
pointer-events: auto;
}
.module-btn:hover {
z-index: 10;
}
.module-btn:active {
/* transform: scale(0.95); */
}
/* 确保选中的按钮在最上层 */
.module-btn.selected {
z-index: 20;
}
</style>
@@ -0,0 +1,119 @@
<template>
<div class="module-switcher">
<ModuleButton
v-for="module in moduleConfigs"
:key="module.type"
:module="module"
:is-selected="selectedModule === module.type"
@click="selectModule(module.type)"
/>
</div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { IMAGE_PATHS } from '@/utils'
import ModuleButton from './ModuleButton.vue'
// 定义模块类型
type ModuleType = 'vlog' | 'film' | 'interview'
// 模块配置接口
interface ModuleConfig {
type: ModuleType
normalImage: string
selectedImage: string
className: string
maskConfig: {
className: string
position: string
size: string
transform: string
}
}
// Props定义
interface Props {
modelValue?: ModuleType
}
// Emits定义
interface Emits {
(e: 'update:modelValue', value: ModuleType): void
(e: 'change', value: ModuleType): void
}
const props = withDefaults(defineProps<Props>(), {
modelValue: 'vlog'
})
const emit = defineEmits<Emits>()
// 当前选中的模块
const selectedModule = ref<ModuleType>(props.modelValue)
// 模块配置
const moduleConfigs: ModuleConfig[] = [
{
type: 'vlog',
normalImage: IMAGE_PATHS.ACTION.MODULE_BTN1,
selectedImage: IMAGE_PATHS.ACTION.SELECTED_BTN1,
className: 'w-[1235px] h-[830px] left-1/2 -translate-x-1/2 -bottom-6',
maskConfig: {
className: 'left-10 bottom-[240px] w-[500px] h-[100px] -rotate-[15deg]',
position: 'left-10 bottom-[240px]',
size: 'w-[500px] h-[100px]',
transform: '-rotate-[15deg]'
}
},
{
type: 'film',
normalImage: IMAGE_PATHS.ACTION.MODULE_BTN2,
selectedImage: IMAGE_PATHS.ACTION.SELECTED_BTN2,
className: 'w-[1087px] h-[822px] left-[calc(50%+50px)] -translate-x-1/2 -bottom-4',
maskConfig: {
className: 'left-[16em] bottom-[50px] w-[500px] h-[100px]',
position: 'left-[16em] bottom-[50px]',
size: 'w-[500px] h-[100px]',
transform: ''
}
},
{
type: 'interview',
normalImage: IMAGE_PATHS.ACTION.MODULE_BTN3,
selectedImage: IMAGE_PATHS.ACTION.SELECTED_BTN3,
className: 'w-[943px] h-[822px] right-[320px] -bottom-4',
maskConfig: {
className: 'right-[0em] bottom-[200px] w-[420px] h-[100px] rotate-[15deg]',
position: 'right-[0em] bottom-[200px]',
size: 'w-[420px] h-[100px]',
transform: 'rotate-[15deg]'
}
}
]
// 选择模块
const selectModule = (module: ModuleType) => {
if (selectedModule.value === module) return
selectedModule.value = module
emit('update:modelValue', module)
emit('change', module)
}
// 监听外部值变化
watch(
() => props.modelValue,
newValue => {
selectedModule.value = newValue
}
)
</script>
<style scoped>
.module-switcher {
position: relative;
width: 100%;
height: 1000px;
}
</style>
@@ -0,0 +1 @@
export { default as ModuleSwitcher } from './ModuleSwitcher.vue'