公告
版权
创建
- 在
Demo\docs-base\.vitepress\theme\components
文件夹,新建notice.vue
组件编写
md
Demo
├─ .vitepress
│ └─ config.mts
│ └─ theme
│ │ ├─ components
│ │ │ └─ notice.vue
│ │ └─ index.ts
└─ index.md
- 在 notice.vue 填入如下代码,保存
说明
- VuePress-Reco:https://theme-reco.vuejs.press/
提示
由于基于《Youbg Kbt》大佬开源的《vitepress-theme-Teek》,大佬开源的主题本身自带了仿vuepress-reco公告
,所以这里选择的是仿常见的影视页公告
vue
<script setup lang="ts">
import { ref } from "vue";
const visible = ref(true);
function closetz() {
visible.value = false;
}
setTimeout(function () {
visible.value = false;
}, 5000);
</script>
<template>
<div v-if="visible" class="notice-background" style="display: block;"></div>
<div v-if="visible" class="notice">
<h3 class="notice-title">网站公告</h3>
<div class="notice-describe">
<p>本次更新:新公告样式</p>
<p class="notice-domain">
<strong>
详细教程:
<a
href="https://vitepress.yiov.top/layout.html#%E5%85%AC%E5%91%8A"
target="_blank"
>vitepress.yiov.top</a
>
</strong>
</p>
<p>QQ 频道:******(无效二维码)</p>
<img class="notice-img" src="/qrcode.png" />
</div>
<div class="notice-footer">
<div class="notice-btn" @click="closetz">朕知道了</div>
</div>
</div>
</template>
<style scoped>
.notice-img {
z-index: 9999;
}
/* 全屏遮罩层 */
.notice-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: none;
z-index: 99;
pointer-events: none;
}
/* 通知 */
.notice {
z-index: 999;
padding: 25px;
background: #fff;
width: 350px;
position: fixed;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
border-radius: 18px;
box-sizing: border-box;
box-shadow: 0 0.25rem 0.5rem rgba(0, 0, 0, 0.05), 0 1.5rem 2.2rem rgba(0, 0, 0, 0.1);
}
@media (max-width: 640px) {
.notice {
width: 82%;
padding: 25px;
}
}
.notice-title {
text-align: center;
color: #3c3c3c;
font-size: 20px;
font-weight: 900;
}
.notice-describe p {
color: #3c3c3c;
padding: 10px 0;
font-size: 15px;
}
.notice-describe p strong {
color: #3c3c3c;
}
.notice-describe p a {
color: #eb0e0e;
}
.notice-domain {
background: #f3f5f7;
text-align: center;
border-radius: 10px;
}
/* 通知底部 */
.notice-footer {
padding: 20px 0 0;
text-align: center;
}
.notice-btn {
text-align: center;
cursor: pointer;
border-radius: 50px;
font-weight: 700;
padding: 0 30px;
color: #fff;
background: linear-gradient(to right, #1e69f5 0%, #093ce5 100%);
box-shadow: 0 10px 12px -4px rgb(0 0 0 / 40%);
line-height: 40px;
font-size: 14px;
display: inline-block;
text-wrap: nowrap;
}
</style>
vue
<script setup lang="ts">
import { ref } from "vue";
const visible = ref(true);
function closeBulletin() {
visible.value = false;
}
setTimeout(function () {
visible.value = false;
}, 5000);
</script>
<template>
<div v-if="visible" class="bulletin-wrapper" style="width: 300px;">
<div class="bulletin-title">
<span class="bulletin-icon left">
<svg
class="bulletin-icon"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 32 32"
style="width: 20px; height: 20px; font-size: 20px; color: rgb(255, 255, 255);"
>
<path
d="M27.16 8.08l-1.53 1.29a10 10 0 0 1-.29 13.23l1.47 1.4a12 12 0 0 0 .35-15.88z"
fill="currentColor"
></path>
<path
d="M21.58 12a6 6 0 0 1-.18 7.94l1.47 1.36a8 8 0 0 0 .23-10.59z"
fill="currentColor"
></path>
<path
d="M18 30a1 1 0 0 1-.71-.3L9.67 22H3a1 1 0 0 1-1-1V11a1 1 0 0 1 1-1h6.67l7.62-7.7a1 1 0 0 1 1.41 0a1 1 0 0 1 .3.7v26a1 1 0 0 1-1 1zM4 20h6.08a1 1 0 0 1 .71.3L17 26.57V5.43l-6.21 6.27a1 1 0 0 1-.71.3H4z"
fill="currentColor"
></path>
</svg>
<span>公告</span>
</span>
<svg
class="btn-close"
@click="closeBulletin"
t="1573745677073"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4448"
width="22"
height="22"
>
<path
d="M512 34.133333a486.4 486.4 0 1 0 486.4 486.4A486.4 486.4 0 0 0 512 34.133333z m209.4848 632.8064l-55.6032 55.466667-151.517867-151.125333-151.517866 151.1168-55.6032-55.466667 151.517866-151.108267L307.242667 364.714667l55.6032-55.466667 151.517866 151.125333 151.517867-151.1168 55.6032 55.466667-151.517867 151.099733z m0 0"
p-id="4449"
></path>
</svg>
</div>
<div class="bulletin-content">
<h3 class="bulletin-h3">本次更新:</h3>
<p class="bulletin-p">
公告样式,参考自
<a
class="bulletin-link"
href="https://theme-reco.vuejs.press/"
target="_blank"
>VuePress-Reco</a
>
</p>
<p class="bulletin-p">QQ 频道:******(无效二维码)</p>
<img class="bulletin-img" src="/qrcode.png" />
<hr />
<div class="btn-group">
<a class="btn" href="https://vitepress.dev/zh/" target="_blank">官网</a>
</div>
</div>
</div>
</template>
<style>
.bulletin-wrapper {
position: fixed;
top: 5rem;
right: 1rem;
z-index: 30;
box-sizing: border-box;
border-radius: 1.2rem;
overflow-y: auto;
background-color: #1b1446;
box-shadow: 0 10px 30px 0 rgb(0 0 0 / 40%);
}
.bulletin-title {
display: flex;
align-items: center;
justify-content: space-between;
color: rgb(255 255 255);
padding: 1rem;
}
.bulletin-icon {
display: inline-flex;
}
.bulletin-icon.left {
flex-direction: row;
align-items: center;
}
.bulletin-icon.left > svg {
margin-right: 0.375rem;
}
.btn-close {
cursor: pointer;
fill: currentColor;
}
.bulletin-content {
padding: 1.5rem 2rem;
background-color: #ffffff;
}
.bulletin-h3 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
color: #000000;
font-size: 19px;
font-weight: bolder;
}
.bulletin-p {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
color: #000000;
font-size: 16px;
}
.bulletin-link {
color: red;
}
.bulletin-img {
width: 100%;
}
hr {
margin-top: 1.5rem;
margin-bottom: 1.5rem;
border-top-width: 1px;
border-style: solid;
border-color: #1b1446;
}
.btn-group {
text-align: center;
}
.btn {
display: inline-block;
height: 3.5rem;
width: 3.5rem;
cursor: pointer;
border-radius: 50%;
background-color: #1b1446;
text-align: center;
line-height: 3.5rem;
color: #ffffff;
}
</style>
配置
提示
- 这里我建议使用 插槽:layout-top,配置成功即可使用
- 在
Demo\docs-base\.vitepress\theme\index.ts
中配置引入
ts
/* Demo\docs-base\.vitepress\theme\index.ts */
import NoticeContent from "./components/NoticeContent.vue";
import notice from "./components/notice.vue";
export default {
extends: Teek,
Layout: defineComponent({
name: "LayoutProvider",
setup() {
const { frontmatter } = useData();
const { start, stop } = useFooterRuntime();
watch(
frontmatter,
() => {
nextTick(() => {
if (frontmatter.value.layout === "home") start();
else stop();
});
},
{ immediate: true }
);
return () =>
h(Teek.Layout, null, {
"layout-top": () => h(notice), // 使用layout-top插槽
"Teek-notice-content": () => h(NoticeContent),
});
},
}),
};