VitePress 添加友链界面

news/2025/9/24 9:47:54/文章来源:https://www.cnblogs.com/weizwz/p/19108614

效果预览
image

友链数据存储

友链数据通常是经常需要添加和修改的,所以我们不能直接写死到页面上。这里我们单独提一个文件去存储友链数据,并且友链数据的格式基本也是类似的。

新建 docs/pages/links.md 文件,内容如下:

---
layout: weiz-link
title: 我的友链
description: 这是唯知笔记网站的友链界面,xxxxxxlinks:
- title: 鸣谢desc: 建站中学习和使用了以下博客/网站的技术和分享,特别鸣谢!🫡list:- name: VitePresslink: https://vitepress.dev/zh/avatar: https://vitepress.dev/vitepress-logo-mini.svgirregular: truedescr: 由 Vite 和 Vue 驱动的静态站点生成器- name: VitePress 快速上手教程link: https://vitepress.yiov.top/avatar: https://vitepress.dev/vitepress-logo-mini.svgirregular: truedescr: 如果你也想搭建它,那跟我一起做吧
- title: 传送门desc: 聚集众多优秀独立博客,随机传送 🚀list:- name: 十年之约link: https://foreverblog.cn/go.htmlavatar: https://img.foreverblog.cn/logo_en_default.pngdescr: 十年之约,奔赴某个独立博客的十年irregular: true- name: Web Teleporterlink: https://webteleporter.top/avatar: https://webteleporter.top/img/logo.pngdescr: 独立博客传送门
---

注:irregular 字段是对特殊图片进行处理

友链页面创建

Vitepress 中创建单独页面的方法,可以参考 VitePress 新建页面和注册组件

新建组件

新建一个文件夹 docs/.vitepress/theme/components/WLink 用来存放友链组件

WLink/index.vue

<template><div id="main"><div class="title"><h1>我的友链</h1></div><div class="content"><div class="link" v-for="(item, index) of linksData" :key="index"><div class="title-wrapper"><h3>{{ item.title }}</h3></div><p>{{ item.desc }}</p><div class="link-list"><el-row class="container-row" :gutter="24"><el-col v-for="temp of item.list" :key="temp.link" class="link-wrapper" :xs="24" :sm="12" :md="6"><LinkSite :data="temp" /></el-col></el-row></div></div></div><div class="message"><div class="title-wrapper"><h3>留链吗</h3></div><p>留恋的小伙伴,想要和我做友链 💞</p><div class="card"><p>留言请参照置顶评论里的格式,siteshot 字段非必需</p><Twikoo /></div></div></div>
</template><script setup lang='ts'>
import { useData } from 'vitepress'
import LinkSite from './LinkSite.vue'
import Twikoo from '../WTwikoo/index.vue'
import { LinkList } from '../../type/WLink'const { frontmatter: fm } = useData()const linksData = fm.value.links as LinkList[]
</script><style>
.message .twikoo {margin-top: 0;
}
</style>
<style lang='scss' scoped>
.content {margin-top: var(--weiz-spacing-8xl);margin-bottom: var(--weiz-spacing-12xl);
}
.title-wrapper {    margin: var(--weiz-spacing-8xl) 0;height: 1px;background: var(--vp-c-text-5);position: relative;> h3 {position: absolute;left: 50%;top: 50%;transform: translate(-50%) translateY(-50%);background: var(--vp-c-bg-soft);padding: 0 var(--weiz-spacing-8xl);font-size: var(--weiz-font-size-xl);font-weight: var(--weiz-font-weight-bold);line-height: var(--weiz-text-xl-line-height);text-align: center;}&+p {margin-bottom: var(--weiz-spacing-6xl);font-weight: var(--weiz-font-weight-medium);text-align: center;}
}
.link-list .el-col {margin-bottom: var(--weiz-spacing-6xl);
}
.card {padding: var(--weiz-spacing-6xl);border-radius: var(--weiz-card-border-radius);background-color: var(--vp-c-bg);box-shadow: var(--weiz-shadow);> p {margin-bottom: var(--weiz-spacing-6xl);}
}
</style>

WLink/LinkSite.vue

<template><div class="link-item"><a :href="data.link" :title="data.name" target="_blank"><div class="link-icon"><img v-if="!imageFailed" :class="{ irregular: data.irregular }" :src="data.avatar" @error="handleImageError()" :alt="data.name" /><!-- 替代内容:显示首字母 --><span v-else class="iconPlaceholder">{{ data.name.charAt(0) }}</span></div><div class="link-info"><div class="link-name">{{ data.name }}</div><div class="link-desc" :title="data.descr">{{ data.descr }}</div></div></a></div>
</template><script setup lang="ts">
import { ref } from 'vue'
import { Link } from '../../type/WLink'const props = defineProps<{ data: Link }>()
const data = props.data// 记录图片加载状态
const imageFailed = ref(false)// 处理图片加载失败
const handleImageError = () => {imageFailed.value = true // 更新加载状态
}
</script><style lang="scss" scoped>
.link-item {position: relative;overflow: hidden;width: 100%;height: 100px;display: inline-block;border-radius: var(--weiz-card-border-radius);background-color: var(--vp-c-bg);box-shadow: var(--weiz-shadow);&:hover {.link-icon > img,.iconPlaceholder {transform: scale(2.4);&.irregular {transform: scale(1.6);}}.link-info {margin-left: 20px;}}> a {position: relative;z-index: 1;height: 100%;display: flex;align-items: center;}.link-icon {flex: 0 0 auto;width: 100px;height: 100%;overflow: hidden;display: flex;align-items: center;justify-content: center;transition: var(--weiz-transition-6);> img {width: 60px;height: 60px;border-radius: 50%;vertical-align: top;object-fit: cover;transition: var(--weiz-transition-6);&[src^="https://vitepress.dev/"]{border-radius: 0;}&.irregular {object-fit: contain;}}.iconPlaceholder {font-size: var(--weiz-font-size-3xl);font-weight: var(--weiz-font-weight-bold);display: inline-block;transition: var(--weiz-transition-6);}}.link-info {flex: 1;height: 100%;display: flex;flex-direction: column;justify-content: center;transition: var(--weiz-transition-6);}.link-name {width: 100%;font-size: var(--weiz-font-size-st);line-height: var(--weiz-text-st-line-height);font-weight: var(--weiz-font-weight-semibold);margin-bottom: var(--weiz-spacing-2xl);white-space: nowrap;overflow: hidden;text-overflow: ellipsis;transition: var(--weiz-transition-6);}.link-desc {width: 100%;padding-right: var(--weiz-spacing-6xl);font-weight: var(--weiz-font-weight-semibold);color: var(--vp-c-text-2);line-height: var(--weiz-text-xs-line-height);overflow: hidden;display: -webkit-box;-webkit-box-orient: vertical;-webkit-line-clamp: 3;line-clamp: 3;transition: var(--weiz-transition-6);}
}
</style>

.vitepress/theme/type/WLink.ts

export interface LinkList {// 标题title: string// 描述desc: string// 列表list: Link[]
}export interface Link {// 站点名称name: string// 站点链接link: string// 头像/站点logoavatar: string// 头像不规则irregular?: boolean// 站点描述descr: string// 站点缩略图siteshot?: string
}

组件注册

新建的组件需要在主题配置中心进行注册,注册后就可以在 md页面 中使用了。比如我们 links.md 文件中的开头 layout: weiz-link

docs/.vitepress/theme/index.ts

import WLink from './components/WLink/index.vue' // 友链页export default {enhanceApp({ app }) {// 注册全局组件app.component('weiz-link', WLink)}
}

附带评论

在组件内集成评论,直接使用评论组件,比如我的是 <Twikoo /> 评论。
Twikoo 评论的集成方式,可参考 VitePress 集成 Twikoo 评论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/915516.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

跨网文件摆渡软件:企业数据安全高效传输的关键解决方案!

在数字化时代,企业为保障核心数据安全,普遍采用网络隔离策略,将内网与外网、研发网与办公网等不同网络环境分隔开来。然而,业务协同中跨网文件传输的需求始终存在,跨网文件摆渡软件应运而生。这类软件是专门用于在…

洛谷题单指南-进阶数论-P1495 【模板】中国剩余定理(CRT)/ 曹冲养猪

原题链接:https://www.luogu.com.cn/problem/P1495 题意解读:求方程组x ≡ bi (mod ai), i∈[1,n]的最小正整数解,所有的ai互质。 解题思路: 1、中国剩余定理 设方程组为(a1,a2,a3互质):x ≡ b1 (mod a1) x ≡…

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南

第十四届蓝桥杯青少组C++选拔赛[2022.12.18]第二部分编程题(4、充电站) - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-…

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板

界面控件DevExpress WinForms中文教程:Data Grid - 搜索/查找面板DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用…

c语言之自定义memcpy

void *Memcpy(void *dest, const void *src, size_t count) { cout<<"sizeof(dest)是:"<<sizeof(dest)<<endl;int bytelen=count/sizeof(dest); /*按CPU位宽拷贝*/int slice=count%si…

国产芯片处理板卡:7-基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡

基于国产化FT-M6678+JFM7K325T的6U CPCI信号处理卡一、板卡概述本板卡系我公司自主研发,基于6U CPCI的通用高性能信号处理平台。板卡采用一片国产8核DSP FT-C6678和一片国产FPGA JFM7K325T-2FFG900作为主处理器。为您…

一文详解纷享销客CRM Agent平台3大核心能力(附应用场景与案例)

AI 技术加速渗透业务场景,智能体(Agent)已成为企业提效增长的关键工具 —— 它可助力销售快速掌握客户经营情况、辅助运营规避数据操作差错、帮助新人高效获取业务知识,在营销、销售、服务全链路实现 “数据洞察 -…

php网站开发实训总结东莞网络营销全网推广

简介&#xff1a;企业想要拥有领先的数据分析能力&#xff0c;自研往往需要投入巨大的人力和财力。 Quick BI作为唯一一个连续两年入选Gartner魔力象限的中国BI产品&#xff0c;具备强大的全链路开放集成能力&#xff0c;可以轻松的与企业原有系统匹配融合&#xff0c;帮助企业…

QOJ #5076. Prof. Pang and Ants 题解

Description 在庞教授的大房子边上,有一群包含 \(m\) 只蚂蚁的蚁群,居住在有 \(n\) 个洞口的洞穴里。 它们会外出寻找食物。食物在庞教授的大冰箱里,蚂蚁们试图从里面偷出食物来。 特别的, 一只蚂蚁需要 \(1\) 秒从…

微信小程序(uniapp)PDF预览完整实现方案

微信小程序(uniapp)PDF预览完整实现方案Posted on 2025-09-24 09:36 且行且思 阅读(0) 评论(0) 收藏 举报在微信小程序开发中,PDF文件预览是常见的业务需求。本文将提供一套基于uniapp的完整解决方案,涵盖从后…

发现5个宝藏文件摆渡系统 2025年企业首选的摆渡方案是这个!

文件摆渡系统作为解决网络隔离后业务交互的重要工具,其作用和价值不言而喻。不过对于企业的价值究竟是正面的,还是负面的,这就要看用的什么文件摆渡系统了。本文中我们就介绍5种文件摆渡系统,我们来看看首选的摆渡…

如何打开谷歌网站网站备案网站

文章目录 一、文档转换器 & 文本拆分器文本拆分器 二、开始使用文本拆分器三、按字符进行拆分四、代码分割 (Split code)1、PythonTextSplitter2、JS3、Markdown4、Latex5、HTML6、Solidity 五、MarkdownHeaderTextSplitter1、动机2、Use case 六、递归按字符分割七、按tok…

基金网站建设网站建设运营知识

移动应用程序开发的增长速度比以往任何时候都快。几乎每个企业都需要移动应用程序来保持市场竞争力。由于像 React Native 这样的跨平台移动应用程序开发框架允许公司使用单一源代码和单一编程语言构建 iOS 和 Android 应用程序&#xff0c; Flutter是 Google 支持的另一个热门…

BilldDesk:基于Vue3+WebRTC+Nodejs+Electron的开源远程桌面控制 - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

css-轮播图效果

<!DOCTYPE html> <html lang="zh-EN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"&g…

aspnetcore使用websocket实时更新商品信息

aspnetcore使用websocket实时更新商品信息先演示一下效果,再展示代码逻辑。中间几次调用过程省略。。。 暂时只用到了下面四个项目1.产品展示页面中第一次通过接口去获取数据库的列表数据/// <summary> /// 获取…

漏洞挖掘实战:如何定制化模糊测试技术

本文深入探讨如何定制化模糊测试工具syzkaller来挖掘Linux内核漏洞。从基础架构解析到实战技巧,涵盖权限设置、网络接口测试、结果筛选机制以及七种独特漏洞发现方法,适合安全研究人员参考。适配模糊测试以挖掘漏洞 …

css-遮罩层效果

<!DOCTYPE html> <html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">&…

nuxt3中使用pdfjs-dist实现pdf转换canvas实现浏览

获取 pdfjsLib.GlobalWorkerOptions.workerSrc 的cdn链接地址https://cdnjs.com/libraries/pdf.js 代码 https://files.cnblogs.com/files/li-sir/cspdf.zip?t=1758676920&download=true

查看linux部署网站的TLS版本号

curl https://域名 -version无可奈何花落去,似曾相识燕归来