7
0
0

Fuwari魔改-加入留言板

文章摘要
|

前言

这个效果参考了此仓库,可以的话,也请给原仓库点点 star。我们接下来就开始。

修改导航栏链接

首先我们要去src/types/config.ts更改inkPreset 的内容:

// src/types/config.ts
export enum LinkPreset {
	Home = 0,
	Archive = 1,
	About = 2,
+	Message = 3,
}

这一步是为了在导航栏加入留言板的链接跳转。

接下来我们要去加入链接的名字。

找到文件src\i18n\i18nKey.ts,加入以下内容:

	// src/i18n/i18nKey.ts
	author = "author",
	publishedAt = "publishedAt",
	license = "license",
+	message = "message",

然后更改src\i18n\languages\zh_CN.ts,在下面加入一行 :

// src\i18n\languages\zh_CN.ts
	[Key.more]: "更多",
[Key.author]: "作者",
[Key.publishedAt]: "发布于",
[Key.license]: "许可协议",





接下来前往src\constants\link-presets.ts,我们加入这几行:

// src\constants\link-presets.ts
import I18nKey from "@i18n/i18nKey";
import { i18n } from "@i18n/translation";
import { LinkPreset, type NavBarLink } from "@/types/config";
export const LinkPresets: { [key in LinkPreset]: NavBarLink } = {
[LinkPreset.Home]: {
name: i18n(I18nKey.home),
url: "/",
},
[LinkPreset.About]: {
name: i18n(I18nKey.about),
url: "/about/",
},
[LinkPreset.Archive]: {
name: i18n(I18nKey.archive),
url: "/archive/",
},

这样,我们加入导航栏的准备就做好了,最后去src\config.ts修改最后的地方即可。

// src\config.ts
export const navBarConfig: NavBarConfig = {
	links: [
		LinkPreset.Home,
		LinkPreset.Archive,
		LinkPreset.About,
+		LinkPreset.Message,
		{
			name: "GitHub",
			url: "https://github.com/saicaca/fuwari", // Internal links should not include the base path, as it is automatically added
			external: true, // Show an external link icon and will open in a new tab
		},
	],
};

现在你的导航栏应该会多出一个叫做“留言”的 Tab,我们接下来只需要实现界面即可。

新建留言界面与组件

新建组件

首先我们要新建这个信件组件出来,所以我们先新建src\components\EnvelopeComment.astro作为我们的组件,内容如下:

// src\components\EnvelopeComment.astro
---
import { envelopeConfig } from "../config";
import type { EnvelopeCommentConfig } from "../types/config";
import ImageWrapper from "./misc/ImageWrapper.astro";
export interface Props extends EnvelopeCommentConfig {}
const {
title = envelopeConfig.title,
cover = envelopeConfig.cover,
line = envelopeConfig.line,
beforeimg = envelopeConfig.beforeimg,
afterimg = envelopeConfig.afterimg,
message = envelopeConfig.message,
bottom = envelopeConfig.bottom,
height = envelopeConfig.height,
} = Astro.props;
<div id="maincontent">
<div id="form-wrap">
<img
id="beforeimg"
class="no-lightbox"
src={beforeimg}
alt="envelope before"
/>
<div id="envelope">
<form>
<div class="formmain" style="pointer-events: none;">
<ImageWrapper
class="headerimg no-lightbox"
src={cover}
alt="cover"
/>
<div class="comments-main">
<h3
class="title3"
style="text-decoration: none; color: var(–theme-color, #49b1f5); text-align: center; margin:10px"
>
{title}
</h3>
<div
class="comments"
style="text-align: center; border-bottom: #ddd 1px solid; border-left: #ddd 1px solid; padding-bottom: 20px; background-color: #eee; margin: 15px 0px; padding-left: 20px; padding-right: 20px; border-top: #ddd 1px solid; border-right: #ddd 1px solid; padding-top: 20px;"
>
{message.map((msg) => <div>{msg}</div>)}
</div>
<div
class="bottomcontent"
style="text-align: center; margin-top: 40px;"
>
<img
class="bottomimg no-lightbox"
src={line}
alt="line"
/>
</div>
<p
class="bottomhr"
style="font-size: 12px; text-align: center; color: #999;"
>
{bottom}
</p>
</div>
</div>
</form>
</div>
<img
id="afterimg"
class="no-lightbox"
src={afterimg}
alt="envelope after"
/>
</div>
</div>
<style define:vars={{ height }}>
@media screen and (max-width: 600px) {
#beforeimg,
#afterimg {
display: none !important;
}
}
@media screen and (min-width: 600px) {
    #article-container img {
        margin: 0 auto 0rem;
    }

    #form-wrap {
        overflow: hidden;
        height: 447px;
        position: relative;
        top: 0px;
        transition: all 1s ease-in-out 0.3s;
        z-index: 0;
    }

    #form-wrap:hover {
        height: var(--height);
        top: -200px;
    }

    #beforeimg {
        position: absolute;
        bottom: 126px;
        left: 0px;
        background-repeat: no-repeat;
        width: 530px;
        height: 317px;
        z-index: -100;
        pointer-events: none;
    }

    #afterimg {
        position: absolute;
        bottom: -2px;
        left: 0;
        background-repeat: no-repeat;
        width: 530px;
        height: 259px;
        z-index: 100;
        pointer-events: none;
    }

    #envelope {
        position: relative;
        overflow: visible;
        width: 500px;
        margin: 0px auto;
        transition: all 1s ease-in-out 0.3s;
        padding-top: 200px;
    }

    #maincontent {
        width: 530px;
        margin: 20px auto 0;
    }

    .formmain {
        background: white;
        width: 95%;
        max-width: 800px;
        margin: auto auto;
        border-radius: 5px;
        border: 1px solid;
        overflow: hidden;
        -webkit-box-shadow: 0px 0px 20px 0px #000000;
        box-shadow: 0px 0px 20px 0px #000000;
    }
}

/* 夜间模式 */
:global([data-theme=&quot;dark&quot;]) .formmain {
    background: #323232;
}

:global([data-theme=&quot;dark&quot;]) .comments {
    background: #5a5a5a !important;
}

</style>

当然这里我把原作者的可配置模式抄过来了,所以这里需要再次修改一些东西:
来到src\types\config.ts,添加如下内容:

import type { AUTO_MODE, DARK_MODE, LIGHT_MODE } from "@constants/constants";
export type SiteConfig = {
title: string;
subtitle: string;
lang:
	| &quot;en&quot;
	| &quot;zh_CN&quot;
	| &quot;zh_TW&quot;
	| &quot;ja&quot;
	| &quot;ko&quot;
	| &quot;es&quot;
	| &quot;th&quot;
	| &quot;vi&quot;
	| &quot;tr&quot;
	| &quot;id&quot;;

themeColor: {
	hue: number;
	fixed: boolean;
};
banner: {
	enable: boolean;
	src: string;
	position?: &quot;top&quot; | &quot;center&quot; | &quot;bottom&quot;;
	credit: {
		enable: boolean;
		text: string;
		url?: string;
	};
};
toc: {
	enable: boolean;
	depth: 1 | 2 | 3;
};

favicon: Favicon[];

};
export type Favicon = {
src: string;
theme?: "light" | "dark";
sizes?: string;
};
export enum LinkPreset {
Home = 0,
Archive = 1,
About = 2,
Message = 3,
}
export type NavBarLink = {
name: string;
url: string;
external?: boolean;
};
export type NavBarConfig = {
links: (NavBarLink | LinkPreset)[];
};
export type ProfileConfig = {
avatar?: string;
name: string;
bio?: string;
links: {
name: string;
url: string;
icon: string;
}[];
};
export type LicenseConfig = {
enable: boolean;
name: string;
url: string;
};
export type LIGHT_DARK_MODE =
| typeof LIGHT_MODE
| typeof DARK_MODE
| typeof AUTO_MODE;
export type BlogPostData = {
body: string;
title: string;
published: Date;
description: string;
tags: string[];
draft?: boolean;
image?: string;
category?: string;
prevTitle?: string;
prevSlug?: string;
nextTitle?: string;
nextSlug?: string;
};
export type ExpressiveCodeConfig = {
theme: string;
};
+export interface EnvelopeCommentConfig {

这就 OK 了,信封组件就这样子被我们写好可以工作了。

新建留言界面

最后我们新建文件src\pages\message.astro,让我们的组件在上面展示出来:

// src\pages\message.astro
---
import EnvelopeComment from "@components/EnvelopeComment.astro";
import I18nKey from "../i18n/i18nKey";
import { i18n } from "../i18n/translation";
import MainGridLayout from "../layouts/MainGridLayout.astro";

<MainGridLayout
title={i18n(I18nKey.message)}
description={i18n(I18nKey.message)}
>
<div
class="flex w-full rounded-[var(–radius-large)] overflow-hidden relative min-h-32"
>
<div class="card-base z-10 px-9 py-6 relative w-full">
<EnvelopeComment />
</div>
</div>
</MainGridLayout>

保存之后,尝试一些pnpm dev,看看你希望的画面有没有出来?什么?没有?什么都没有?那大概是你还没配置好:

src\config.ts,粘贴并按照你想的去修改以下的配置选项:

//src\config.ts
export const envelopeConfig: Required<EnvelopeCommentConfig> = {
	title: "来自作者的留言,
	cover: "https://unpkg.zhimg.com/hexo-butterfly-envelope/lib/violet.jp,
	line: "https://npm.elemecdn.com/hexo-butterfly-envelope/lib/line.png",
	beforeimg: "https://npm.elemecdn.com/hexo-butterfly-envelope/lib/before.png",
	afterimg: " https://npm.elemecdn.com/hexo-butterfly-envelope/lib/after.png",
	message: [
		"有什么想问的?",
		"有什么想说的?",
		"有什么想吐槽的?",
		"哪怕是有什么想吃的,都可以告诉我哦~",
	],
	bottom: "自动书记人偶竭诚为您服务!",
	height: "1050px",
};

好了,你再去看看,现在是不是正常了?

如果你觉得这些图片不喜欢,那么按照之前写的去挑选你喜欢的图像,然后配置上去即可。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

Fuwari魔改-加入留言板
/archives/fuwarimo-gai-jia-ru-liu-yan-ban
作者
Leave_Time(时泠)
发布于
2025-11-26
许可协议
CC BY-NC-SA 4.0

评论