feat: improve SocialLinks component accessibility

This commit is contained in:
Cat Tom 2025-03-26 02:12:54 +08:00
parent e903c54a10
commit f065e16c61

View File

@ -2,6 +2,7 @@
import { ref, computed } from "vue";
import { useMouseInElement } from "@vueuse/core";
import { useTheme } from "vuetify";
import WechatModal from "./WechatModal.vue";
const theme = useTheme();
const cardRef = ref(null);
@ -52,7 +53,6 @@ const props = defineProps({
hoverColor: "#2DC100",
ariaLabel: "扫描我的微信二维码",
qrCode: new URL("./assets/wechat-qr.png", import.meta.url).href,
showQr: false,
},
],
validator: (platforms) =>
@ -68,16 +68,16 @@ const props = defineProps({
});
//
const qrStates = ref({});
const showWechatModal = ref(false);
const currentQrCode = ref("");
const toggleQrCode = (platform) => {
if (platform.qrCode) {
qrStates.value[platform.name] = !qrStates.value[platform.name];
emit("showWechat", qrStates.value[platform.name]);
currentQrCode.value = platform.qrCode;
showWechatModal.value = !showWechatModal.value;
}
};
const emit = defineEmits(["showWechat"]);
//
const platformsWithQr = computed(() =>
props.socialPlatforms.filter((p) => p.qrCode)
@ -106,29 +106,14 @@ const openLink = (url) => {
<template>
<div ref="cardRef" class="social-links-card" :style="cardTransform">
<!-- 微信二维码弹窗 -->
<TransitionGroup name="fade" tag="div" class="qr-container">
<div
v-for="platform in platformsWithQr"
v-show="qrStates[platform.name]"
:key="`qr-${platform.name}`"
class="qr-code"
>
<img
v-if="qrStates[platform.name]"
:src="platform.qrCode"
loading="lazy"
:alt="`${platform.name}二维码`"
/>
<button
class="qr-close"
@click="toggleQrCode(platform)"
aria-label="关闭二维码"
>
&times;
</button>
</div>
</TransitionGroup>
<!-- 使用WechatModal组件 -->
<WechatModal
v-model="showWechatModal"
:qr-code="currentQrCode"
title="微信扫码添加"
hint="打开微信扫一扫,添加我为好友"
@closed="currentQrCode = ''"
/>
<!-- 社交链接主体 -->
<div class="social-grid">
@ -268,72 +253,6 @@ const openLink = (url) => {
opacity: 0.15;
}
/* 二维码样式 */
.qr-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
pointer-events: none;
}
.qr-code {
background: white;
padding: 1.5rem;
border-radius: 1rem;
text-align: center;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
position: relative;
pointer-events: auto;
}
.qr-code img {
width: 180px;
height: 180px;
display: block;
margin: 0 auto;
}
.qr-close {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: transparent;
border: none;
font-size: 1.5rem;
cursor: pointer;
color: #666;
width: 2rem;
height: 2rem;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s ease;
}
.qr-close:hover {
background: #f0f0f0;
color: #333;
}
/* 过渡动画 */
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: scale(0.95);
}
/* 响应式调整 */
@media (max-width: 768px) {
.social-grid {
@ -349,14 +268,5 @@ const openLink = (url) => {
.social-icon {
font-size: 1.4rem;
}
.qr-code {
padding: 1rem;
}
.qr-code img {
width: 150px;
height: 150px;
}
}
</style>
</style>