mirror of
https://github.com/caojiezi2003/Snavigation.git
synced 2024-11-23 10:59:46 +00:00
fix: 去除自定义弹窗
This commit is contained in:
parent
fcf83ff50f
commit
9aaa9bfea6
6
.env
6
.env
@ -1,5 +1,5 @@
|
||||
# 搜索框提示词
|
||||
VITE_INPUT_TIP = "想要搜点什么"
|
||||
|
||||
# 进入欢迎词
|
||||
VITE_WELCOME_TEXT = "欢迎访问本站"
|
||||
|
||||
# 搜索框提示词
|
||||
VITE_INPUT_TIP = "想要搜点什么"
|
38
README.md
38
README.md
@ -8,6 +8,7 @@
|
||||
> 重构中,尚未完成
|
||||
|
||||
### Demo
|
||||
|
||||
> 由于 `CDN` 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
|
||||
|
||||
- [Snavigation](https://nav.imsyy.top)
|
||||
@ -21,22 +22,27 @@
|
||||
- [x] 网站背景自定义
|
||||
- [x] 数据备份及恢复
|
||||
- [x] 移动端适配
|
||||
* [ ] 切换搜索引擎
|
||||
* [ ] 设置
|
||||
* [ ] 备份
|
||||
- [x] 切换搜索引擎
|
||||
- [x] 设置
|
||||
- [x] 备份
|
||||
|
||||
* [ ] 一言
|
||||
* [ ] 书签
|
||||
* [ ] 备忘
|
||||
|
||||
### 配置
|
||||
|
||||
修改项目的部分默认设置可前往根目录下的 `.env` 文件中修改
|
||||
|
||||
### 部署
|
||||
|
||||
* **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
|
||||
- **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
|
||||
|
||||
> node > 16.16.0
|
||||
> npm > 8.15.0
|
||||
|
||||
* 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
|
||||
* 在 `终端` 中输入:
|
||||
- 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
|
||||
- 在 `终端` 中输入:
|
||||
|
||||
```bash
|
||||
# 安装 pnpm
|
||||
@ -51,27 +57,27 @@ pnpm dev
|
||||
# 构建
|
||||
pnpm build
|
||||
```
|
||||
|
||||
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,
|
||||
> 也可使用 [Vercel](https://vercel.com/) 或 [Cloudflare Pages](https://pages.cloudflare.com/) 等托管平台一键自动部署
|
||||
|
||||
|
||||
### 技术栈
|
||||
|
||||
* [Vue](https://cn.vuejs.org/)
|
||||
* [Vite](https://vitejs.cn/vite3-cn/)
|
||||
* [Pinia](https://pinia.vuejs.org/zh/)
|
||||
* [iconfont](https://www.iconfont.cn/)
|
||||
- [Vue](https://cn.vuejs.org/)
|
||||
- [Vite](https://vitejs.cn/vite3-cn/)
|
||||
- [Pinia](https://pinia.vuejs.org/zh/)
|
||||
- [iconfont](https://www.iconfont.cn/)
|
||||
|
||||
### API
|
||||
|
||||
* [小歪 API](https://api.ixiaowai.cn/)
|
||||
* [缙哥哥 API](https://www.dujin.org/3618.html)
|
||||
* [Hitokoto 一言](https://hitokoto.cn/)
|
||||
- [小歪 API](https://api.ixiaowai.cn/)
|
||||
- [缙哥哥 API](https://www.dujin.org/3618.html)
|
||||
- [Hitokoto 一言](https://hitokoto.cn/)
|
||||
|
||||
### 鸣谢
|
||||
|
||||
本站部分样式及功能参考自
|
||||
|
||||
* [青柠起始页](https://limestart.cn/)
|
||||
- [青柠起始页](https://limestart.cn/)
|
||||
|
||||
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a> <a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a> <a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2022-%E7%84%A1%E5%90%8D-red"></a>
|
||||
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a> <a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a> <a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>
|
||||
|
@ -57,8 +57,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<!-- Notification -->
|
||||
<Notification />
|
||||
</main>
|
||||
<div v-else id="loading">
|
||||
<img src="/icon/logo.png" alt="logo" class="logo" />
|
||||
|
@ -12,7 +12,7 @@
|
||||
"icon": "bing"
|
||||
},
|
||||
"google": {
|
||||
"name": "谷歌",
|
||||
"name": "Google",
|
||||
"url": "https://www.google.com/search?q=",
|
||||
"translation": "https://translate.google.com/?text=",
|
||||
"icon": "google"
|
||||
|
@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<n-tabs class="func" size="large" justify-content="space-evenly" animated>
|
||||
<n-tab-pane name="link" tab="捷径"> 即将完善 </n-tab-pane>
|
||||
<n-tab-pane name="link" tab="捷径">
|
||||
<n-h6 prefix="bar"> 常用 </n-h6>
|
||||
</n-tab-pane>
|
||||
<n-tab-pane name="note" tab="便签"> 即将完善 </n-tab-pane>
|
||||
<n-tab-pane name="more" tab="更多"> 还能有啥呢 😢 </n-tab-pane>
|
||||
</n-tabs>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { NTabs, NTabPane } from "naive-ui";
|
||||
import { NTabs, NTabPane, NH6 } from "naive-ui";
|
||||
</script>
|
||||
|
@ -44,6 +44,13 @@ const status = statusStore();
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
.desc {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
.name {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -7,9 +7,28 @@
|
||||
class="set-item cover"
|
||||
:content-style="{ flexDirection: 'column', alignItems: 'flex-start' }"
|
||||
>
|
||||
<div class="desc">
|
||||
<div class="name">
|
||||
<span class="title">壁纸偏好</span>
|
||||
<span class="tip">设置站点背景图片</span>
|
||||
<span class="tip"
|
||||
>除默认以外的其他选项可能会导致页面载入缓慢</span
|
||||
>
|
||||
</div>
|
||||
<n-space>
|
||||
<Transition name="fade" mode="out-in">
|
||||
<n-button
|
||||
v-if="backgroundType !== 0"
|
||||
strong
|
||||
secondary
|
||||
@click="changeBackground(0, true)"
|
||||
>
|
||||
恢复默认
|
||||
</n-button>
|
||||
</Transition>
|
||||
<n-button strong secondary @click="customCover">
|
||||
自定义
|
||||
</n-button>
|
||||
</n-space>
|
||||
</div>
|
||||
<n-grid
|
||||
class="cover-selete"
|
||||
@ -85,6 +104,13 @@
|
||||
</div>
|
||||
<n-switch v-model:value="showSeconds" :round="false" />
|
||||
</n-card>
|
||||
<n-card class="set-item">
|
||||
<div class="name">
|
||||
<span class="title">时钟显零</span>
|
||||
<span class="tip">是否在时钟小于 10 时补 0</span>
|
||||
</div>
|
||||
<n-switch v-model:value="showZeroTime" :round="false" />
|
||||
</n-card>
|
||||
<n-h6 prefix="bar"> 搜索框 </n-h6>
|
||||
<n-card class="set-item">
|
||||
<div class="name">
|
||||
@ -143,10 +169,11 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { h, ref } from "vue";
|
||||
import {
|
||||
NTabs,
|
||||
NTabPane,
|
||||
NSpace,
|
||||
NCard,
|
||||
NSwitch,
|
||||
NSelect,
|
||||
@ -167,6 +194,7 @@ const {
|
||||
autoFocus,
|
||||
autoInputBlur,
|
||||
showSeconds,
|
||||
showZeroTime,
|
||||
showSuggestions,
|
||||
urlJumpType,
|
||||
} = storeToRefs(set);
|
||||
@ -181,9 +209,32 @@ const backgroundTypeArr = [
|
||||
];
|
||||
|
||||
// 切换壁纸
|
||||
const changeBackground = (type) => {
|
||||
const changeBackground = (type, reset = false) => {
|
||||
if (reset) {
|
||||
$dialog.warning({
|
||||
title: "壁纸恢复",
|
||||
content: "确认恢复默认壁纸?若当前为自定义壁纸,你的自定义壁纸将丢失!",
|
||||
positiveText: "恢复",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: () => {
|
||||
backgroundType.value = 0;
|
||||
$message.info("已恢复为默认壁纸,刷新后生效");
|
||||
},
|
||||
});
|
||||
return;
|
||||
}
|
||||
backgroundType.value = type;
|
||||
$message.success("壁纸设置成功,刷新后生效");
|
||||
$message.success(`已切换为${backgroundTypeArr[type].name},刷新后生效`);
|
||||
};
|
||||
|
||||
// 自定义壁纸
|
||||
const customCover = () => {
|
||||
$dialog.warning({
|
||||
title: "警告",
|
||||
content: "你确定?",
|
||||
positiveText: "确定",
|
||||
negativeText: "不确定",
|
||||
});
|
||||
};
|
||||
|
||||
// 链接跳转方式
|
||||
@ -200,10 +251,12 @@ const urlJumpTypeOptions = [
|
||||
|
||||
// 站点重置
|
||||
const resetSite = () => {
|
||||
$noti.dialog({
|
||||
$dialog.warning({
|
||||
title: "站点重置",
|
||||
content: "确认重置站点为默认状态?你的全部数据以及自定义设置都将丢失!",
|
||||
clickVerify: () => {
|
||||
positiveText: "重置",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: () => {
|
||||
localStorage.clear();
|
||||
$message.info("站点重置成功,即将刷新");
|
||||
setTimeout(() => {
|
||||
@ -250,11 +303,13 @@ const recoverSite = async () => {
|
||||
const jsonData = await file.text();
|
||||
const data = JSON.parse(jsonData);
|
||||
// 恢复数据
|
||||
$noti.dialog({
|
||||
$dialog.warning({
|
||||
title: "站点恢复",
|
||||
content: "确认使用该恢复文件?你现有的数据以及自定义设置都将被覆盖!",
|
||||
clickVerify: () => {
|
||||
const isSuccess = set.recoverSiteData(data);
|
||||
positiveText: "恢复",
|
||||
negativeText: "取消",
|
||||
onPositiveClick: async () => {
|
||||
const isSuccess = await set.recoverSiteData(data);
|
||||
if (isSuccess) {
|
||||
$message.info("站点恢复成功,即将刷新");
|
||||
setTimeout(() => {
|
||||
@ -264,7 +319,7 @@ const recoverSite = async () => {
|
||||
$message.error("站点数据恢复失败,请重试");
|
||||
}
|
||||
},
|
||||
clickCancel: () => {
|
||||
onNegativeClick: () => {
|
||||
recoverRef.value.value = null;
|
||||
},
|
||||
});
|
||||
@ -286,7 +341,7 @@ const recoverSite = async () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10px;
|
||||
border-radius: 8px;
|
||||
background-color: var(--main-background-light-color);
|
||||
transition: background-color 0.3s, box-shadow 0.3s;
|
||||
&.check {
|
||||
@ -294,7 +349,7 @@ const recoverSite = async () => {
|
||||
&::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
border-radius: 14px;
|
||||
border-radius: 12px;
|
||||
top: -4px;
|
||||
left: -4px;
|
||||
right: -4px;
|
||||
|
@ -1,169 +0,0 @@
|
||||
<template>
|
||||
<!-- 自定义通知组件 -->
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
<div
|
||||
v-show="notiShow"
|
||||
class="notification"
|
||||
:style="{ zIndex: notizIndex }"
|
||||
>
|
||||
<div class="notification-mask" @click="allNoti.close()" />
|
||||
<Transition name="fadeDown">
|
||||
<div v-if="notiShow" :class="['notification-content', notiType]">
|
||||
<div class="header">
|
||||
<SvgIcon iconName="icon-info" />
|
||||
<div class="title" v-html="notiTitle" />
|
||||
</div>
|
||||
<div class="content" v-html="notiContent" />
|
||||
<div class="actions">
|
||||
<button class="btn" @click="notiCancel">取消</button>
|
||||
<button class="btn" @click="notiVerify">确定</button>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, ref } from "vue";
|
||||
import { findMaxZIndex } from "@/utils/domTools";
|
||||
|
||||
// 弹窗数据
|
||||
const notiShow = ref(false);
|
||||
const notiTitle = ref(null);
|
||||
const notiContent = ref(null);
|
||||
const notiType = ref("dialog");
|
||||
const notizIndex = ref(2000);
|
||||
const notiClickVerify = ref(null);
|
||||
const notiClickCancel = ref(null);
|
||||
|
||||
// 全部方法
|
||||
const allNoti = {
|
||||
dialog: (options) => {
|
||||
if (
|
||||
typeof options === "undefined" ||
|
||||
options === null ||
|
||||
(typeof options === "object" && Object.keys(options).length === 0)
|
||||
) {
|
||||
return console.error("Noti:请传入必要数据");
|
||||
}
|
||||
// 获取配置
|
||||
const { title, content, clickVerify, clickCancel } = options;
|
||||
if (!title || !content) return console.error("Noti:参数错误或不完整");
|
||||
// 更改数据
|
||||
notiTitle.value = title;
|
||||
notiContent.value = content;
|
||||
notiClickVerify.value = clickVerify;
|
||||
notiClickCancel.value = clickCancel;
|
||||
notizIndex.value = findMaxZIndex();
|
||||
notiShow.value = true;
|
||||
},
|
||||
close: () => {
|
||||
notiShow.value = false;
|
||||
notiTitle.value = null;
|
||||
notiContent.value = null;
|
||||
notiType.value = null;
|
||||
notiClickVerify.value = null;
|
||||
notiClickCancel.value = null;
|
||||
notizIndex.value = 2000;
|
||||
},
|
||||
};
|
||||
|
||||
// 取消事件
|
||||
const notiCancel = () => {
|
||||
if (typeof notiClickCancel.value === "function") {
|
||||
notiClickCancel.value();
|
||||
}
|
||||
allNoti.close();
|
||||
};
|
||||
|
||||
// 确认事件
|
||||
const notiVerify = () => {
|
||||
if (typeof notiClickVerify.value === "function") {
|
||||
notiClickVerify.value();
|
||||
}
|
||||
allNoti.close();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 挂载至全局
|
||||
window.$noti = allNoti;
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--main-notification-background-color);
|
||||
backdrop-filter: blur(40px);
|
||||
.notification-mask {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
.notification-content {
|
||||
width: 60vw;
|
||||
height: auto;
|
||||
max-width: 700px;
|
||||
min-width: min(24rem, 100vw);
|
||||
border-radius: 8px;
|
||||
color: var(--main-text-color);
|
||||
background-color: var(--main-background-light-color);
|
||||
box-shadow: var(--main-box-shadow);
|
||||
z-index: 1;
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
.i-icon {
|
||||
font-size: 24px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
padding: 0 20px;
|
||||
font-size: 15px;
|
||||
}
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
padding: 20px;
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
padding: 9px 16px;
|
||||
border-radius: 8px;
|
||||
outline: none;
|
||||
border: none;
|
||||
font-family: "HarmonyOS_Regular", sans-serif;
|
||||
background-color: var(--main-background-light-color);
|
||||
color: var(--main-text-color);
|
||||
transition: background-color 0.3s;
|
||||
&:last-child {
|
||||
margin-left: 12px;
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--main-background-hover-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -168,7 +168,6 @@ const pressKeyboard = (event) => {
|
||||
const changeEngine = () => {
|
||||
status.setSiteStatus("focus", false);
|
||||
status.setEngineChangeStatus(!status.engineChangeStatus);
|
||||
console.log(status.engineChangeStatus);
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -65,7 +65,7 @@ const weatherData = ref({});
|
||||
|
||||
// 更新时间
|
||||
const updateTimeData = () => {
|
||||
timeData.value = getCurrentTime();
|
||||
timeData.value = getCurrentTime(set.showZeroTime);
|
||||
};
|
||||
|
||||
// 获取天气数据
|
||||
|
@ -4,8 +4,6 @@ import { createPinia } from "pinia";
|
||||
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
||||
// IconFont
|
||||
import SvgIcon from "@/components/SvgIcon.vue";
|
||||
// Notification
|
||||
import Notification from "@/components/Notification.vue";
|
||||
// 主组件
|
||||
import App from "@/App.vue";
|
||||
// 全局样式
|
||||
@ -20,6 +18,5 @@ pinia.use(piniaPluginPersistedstate);
|
||||
|
||||
// 挂载
|
||||
app.use(pinia);
|
||||
app.component("Notification", Notification);
|
||||
app.component("SvgIcon", SvgIcon);
|
||||
app.mount("#app");
|
||||
|
@ -23,6 +23,8 @@ const useSetDataStore = defineStore("setData", {
|
||||
timeStyle: "one",
|
||||
// 是否显秒
|
||||
showSeconds: false,
|
||||
// 是否显零
|
||||
showZeroTime: true,
|
||||
// 是否显示搜索建议
|
||||
showSuggestions: true,
|
||||
// 跳转方式
|
||||
|
@ -23,7 +23,7 @@ const useStatusDataStore = defineStore("statusData", {
|
||||
},
|
||||
setSiteStatus(value, alsoChange = true) {
|
||||
this.siteStatus = value;
|
||||
this.searchInputValue = "";
|
||||
if (value !== "focus") this.searchInputValue = "";
|
||||
if (alsoChange) this.engineChangeStatus = false;
|
||||
},
|
||||
setEngineChangeStatus(value) {
|
||||
|
@ -32,6 +32,13 @@ body {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
// NButton
|
||||
.n-button {
|
||||
background-color: var(--main-background-light-color);
|
||||
border-radius: 8px;
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
// NMessage
|
||||
.n-message-container {
|
||||
top: 20px !important;
|
||||
@ -82,6 +89,46 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
// NModal
|
||||
.n-modal-container {
|
||||
.n-modal-mask {
|
||||
backdrop-filter: blur(40px);
|
||||
}
|
||||
// n-dialog
|
||||
.n-dialog {
|
||||
border-radius: 8px;
|
||||
--n-icon-color: var(--main-text-color);
|
||||
--n-color: var(--main-background-light-color);
|
||||
.n-dialog__title {
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
.n-dialog__icon {
|
||||
font-size: 24px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
.n-dialog__content {
|
||||
font-size: 15px;
|
||||
}
|
||||
.n-button {
|
||||
height: auto;
|
||||
padding: 9px 16px;
|
||||
transition: background-color 0.3s;
|
||||
--n-border: none;
|
||||
--n-border-hover: none;
|
||||
--n-border-focus: none;
|
||||
--n-border-pressed: none;
|
||||
--n-text-color-pressed: var(--main-text-color);
|
||||
--n-color-pressed: var(--main-background-hover-color);
|
||||
--n-text-color: var(--main-text-color);
|
||||
--n-text-color-hover: var(--main-text-color);
|
||||
--n-color-focus: var(--main-background-hover-color);
|
||||
--n-text-color-focus: var(--main-text-color);
|
||||
--n-color-hover: var(--main-background-hover-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Transition 动画
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
|
@ -2,7 +2,7 @@
|
||||
* 获取当前时间
|
||||
* @returns {Object} 时间对象
|
||||
*/
|
||||
export const getCurrentTime = () => {
|
||||
export const getCurrentTime = (ShowZero = true) => {
|
||||
const time = new Date();
|
||||
// 格式化
|
||||
const formatTime = (value) => (value < 10 ? "0" + value : value);
|
||||
@ -10,7 +10,7 @@ export const getCurrentTime = () => {
|
||||
const year = time.getFullYear();
|
||||
const month = time.getMonth() + 1;
|
||||
const day = formatTime(time.getDate());
|
||||
const hour = formatTime(time.getHours());
|
||||
const hour = ShowZero ? formatTime(time.getHours()) : time.getHours();
|
||||
const minute = formatTime(time.getMinutes());
|
||||
const second = formatTime(time.getSeconds());
|
||||
const weekdayArr = ["日", "一", "二", "三", "四", "五", "六"];
|
||||
|
Loading…
Reference in New Issue
Block a user