fix: 去除自定义弹窗

This commit is contained in:
imsyy 2023-08-10 17:48:56 +08:00
parent fcf83ff50f
commit 9aaa9bfea6
15 changed files with 172 additions and 228 deletions

6
.env
View File

@ -1,5 +1,5 @@
# 搜索框提示词
VITE_INPUT_TIP = "想要搜点什么"
# 进入欢迎词 # 进入欢迎词
VITE_WELCOME_TEXT = "欢迎访问本站" VITE_WELCOME_TEXT = "欢迎访问本站"
# 搜索框提示词
VITE_INPUT_TIP = "想要搜点什么"

View File

@ -8,6 +8,7 @@
> 重构中,尚未完成 > 重构中,尚未完成
### Demo ### Demo
> 由于 `CDN` 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存 > 由于 `CDN` 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
- [Snavigation](https://nav.imsyy.top) - [Snavigation](https://nav.imsyy.top)
@ -21,22 +22,27 @@
- [x] 网站背景自定义 - [x] 网站背景自定义
- [x] 数据备份及恢复 - [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 > node > 16.16.0
> npm > 8.15.0 > npm > 8.15.0
* 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录 - 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
*`终端` 中输入: -`终端` 中输入:
```bash ```bash
# 安装 pnpm # 安装 pnpm
@ -51,27 +57,27 @@ pnpm dev
# 构建 # 构建
pnpm build pnpm build
``` ```
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器, > 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,
> 也可使用 [Vercel](https://vercel.com/) 或 [Cloudflare Pages](https://pages.cloudflare.com/) 等托管平台一键自动部署 > 也可使用 [Vercel](https://vercel.com/) 或 [Cloudflare Pages](https://pages.cloudflare.com/) 等托管平台一键自动部署
### 技术栈 ### 技术栈
* [Vue](https://cn.vuejs.org/) - [Vue](https://cn.vuejs.org/)
* [Vite](https://vitejs.cn/vite3-cn/) - [Vite](https://vitejs.cn/vite3-cn/)
* [Pinia](https://pinia.vuejs.org/zh/) - [Pinia](https://pinia.vuejs.org/zh/)
* [iconfont](https://www.iconfont.cn/) - [iconfont](https://www.iconfont.cn/)
### API ### API
* [小歪 API](https://api.ixiaowai.cn/) - [小歪 API](https://api.ixiaowai.cn/)
* [缙哥哥 API](https://www.dujin.org/3618.html) - [缙哥哥 API](https://www.dujin.org/3618.html)
* [Hitokoto 一言](https://hitokoto.cn/) - [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>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<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>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<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>

View File

@ -57,8 +57,6 @@
</div> </div>
</div> </div>
</Transition> </Transition>
<!-- Notification -->
<Notification />
</main> </main>
<div v-else id="loading"> <div v-else id="loading">
<img src="/icon/logo.png" alt="logo" class="logo" /> <img src="/icon/logo.png" alt="logo" class="logo" />

View File

@ -12,7 +12,7 @@
"icon": "bing" "icon": "bing"
}, },
"google": { "google": {
"name": "谷歌", "name": "Google",
"url": "https://www.google.com/search?q=", "url": "https://www.google.com/search?q=",
"translation": "https://translate.google.com/?text=", "translation": "https://translate.google.com/?text=",
"icon": "google" "icon": "google"

View File

@ -1,11 +1,13 @@
<template> <template>
<n-tabs class="func" size="large" justify-content="space-evenly" animated> <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="note" tab="便签"> 即将完善 </n-tab-pane>
<n-tab-pane name="more" tab="更多"> 还能有啥呢 😢 </n-tab-pane> <n-tab-pane name="more" tab="更多"> 还能有啥呢 😢 </n-tab-pane>
</n-tabs> </n-tabs>
</template> </template>
<script setup> <script setup>
import { NTabs, NTabPane } from "naive-ui"; import { NTabs, NTabPane, NH6 } from "naive-ui";
</script> </script>

View File

@ -44,6 +44,13 @@ const status = statusStore();
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.desc {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
}
.name { .name {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View File

@ -7,9 +7,28 @@
class="set-item cover" class="set-item cover"
:content-style="{ flexDirection: 'column', alignItems: 'flex-start' }" :content-style="{ flexDirection: 'column', alignItems: 'flex-start' }"
> >
<div class="desc">
<div class="name"> <div class="name">
<span class="title">壁纸偏好</span> <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> </div>
<n-grid <n-grid
class="cover-selete" class="cover-selete"
@ -85,6 +104,13 @@
</div> </div>
<n-switch v-model:value="showSeconds" :round="false" /> <n-switch v-model:value="showSeconds" :round="false" />
</n-card> </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-h6 prefix="bar"> 搜索框 </n-h6>
<n-card class="set-item"> <n-card class="set-item">
<div class="name"> <div class="name">
@ -143,10 +169,11 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { h, ref } from "vue";
import { import {
NTabs, NTabs,
NTabPane, NTabPane,
NSpace,
NCard, NCard,
NSwitch, NSwitch,
NSelect, NSelect,
@ -167,6 +194,7 @@ const {
autoFocus, autoFocus,
autoInputBlur, autoInputBlur,
showSeconds, showSeconds,
showZeroTime,
showSuggestions, showSuggestions,
urlJumpType, urlJumpType,
} = storeToRefs(set); } = 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; 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 = () => { const resetSite = () => {
$noti.dialog({ $dialog.warning({
title: "站点重置", title: "站点重置",
content: "确认重置站点为默认状态?你的全部数据以及自定义设置都将丢失!", content: "确认重置站点为默认状态?你的全部数据以及自定义设置都将丢失!",
clickVerify: () => { positiveText: "重置",
negativeText: "取消",
onPositiveClick: () => {
localStorage.clear(); localStorage.clear();
$message.info("站点重置成功,即将刷新"); $message.info("站点重置成功,即将刷新");
setTimeout(() => { setTimeout(() => {
@ -250,11 +303,13 @@ const recoverSite = async () => {
const jsonData = await file.text(); const jsonData = await file.text();
const data = JSON.parse(jsonData); const data = JSON.parse(jsonData);
// //
$noti.dialog({ $dialog.warning({
title: "站点恢复", title: "站点恢复",
content: "确认使用该恢复文件?你现有的数据以及自定义设置都将被覆盖!", content: "确认使用该恢复文件?你现有的数据以及自定义设置都将被覆盖!",
clickVerify: () => { positiveText: "恢复",
const isSuccess = set.recoverSiteData(data); negativeText: "取消",
onPositiveClick: async () => {
const isSuccess = await set.recoverSiteData(data);
if (isSuccess) { if (isSuccess) {
$message.info("站点恢复成功,即将刷新"); $message.info("站点恢复成功,即将刷新");
setTimeout(() => { setTimeout(() => {
@ -264,7 +319,7 @@ const recoverSite = async () => {
$message.error("站点数据恢复失败,请重试"); $message.error("站点数据恢复失败,请重试");
} }
}, },
clickCancel: () => { onNegativeClick: () => {
recoverRef.value.value = null; recoverRef.value.value = null;
}, },
}); });
@ -286,7 +341,7 @@ const recoverSite = async () => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 10px; border-radius: 8px;
background-color: var(--main-background-light-color); background-color: var(--main-background-light-color);
transition: background-color 0.3s, box-shadow 0.3s; transition: background-color 0.3s, box-shadow 0.3s;
&.check { &.check {
@ -294,7 +349,7 @@ const recoverSite = async () => {
&::before { &::before {
content: ""; content: "";
position: absolute; position: absolute;
border-radius: 14px; border-radius: 12px;
top: -4px; top: -4px;
left: -4px; left: -4px;
right: -4px; right: -4px;

View File

@ -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>

View File

@ -168,7 +168,6 @@ const pressKeyboard = (event) => {
const changeEngine = () => { const changeEngine = () => {
status.setSiteStatus("focus", false); status.setSiteStatus("focus", false);
status.setEngineChangeStatus(!status.engineChangeStatus); status.setEngineChangeStatus(!status.engineChangeStatus);
console.log(status.engineChangeStatus);
}; };
</script> </script>

View File

@ -65,7 +65,7 @@ const weatherData = ref({});
// //
const updateTimeData = () => { const updateTimeData = () => {
timeData.value = getCurrentTime(); timeData.value = getCurrentTime(set.showZeroTime);
}; };
// //

View File

@ -4,8 +4,6 @@ import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
// IconFont // IconFont
import SvgIcon from "@/components/SvgIcon.vue"; import SvgIcon from "@/components/SvgIcon.vue";
// Notification
import Notification from "@/components/Notification.vue";
// 主组件 // 主组件
import App from "@/App.vue"; import App from "@/App.vue";
// 全局样式 // 全局样式
@ -20,6 +18,5 @@ pinia.use(piniaPluginPersistedstate);
// 挂载 // 挂载
app.use(pinia); app.use(pinia);
app.component("Notification", Notification);
app.component("SvgIcon", SvgIcon); app.component("SvgIcon", SvgIcon);
app.mount("#app"); app.mount("#app");

View File

@ -23,6 +23,8 @@ const useSetDataStore = defineStore("setData", {
timeStyle: "one", timeStyle: "one",
// 是否显秒 // 是否显秒
showSeconds: false, showSeconds: false,
// 是否显零
showZeroTime: true,
// 是否显示搜索建议 // 是否显示搜索建议
showSuggestions: true, showSuggestions: true,
// 跳转方式 // 跳转方式

View File

@ -23,7 +23,7 @@ const useStatusDataStore = defineStore("statusData", {
}, },
setSiteStatus(value, alsoChange = true) { setSiteStatus(value, alsoChange = true) {
this.siteStatus = value; this.siteStatus = value;
this.searchInputValue = ""; if (value !== "focus") this.searchInputValue = "";
if (alsoChange) this.engineChangeStatus = false; if (alsoChange) this.engineChangeStatus = false;
}, },
setEngineChangeStatus(value) { setEngineChangeStatus(value) {

View File

@ -32,6 +32,13 @@ body {
height: 100vh; height: 100vh;
} }
// NButton
.n-button {
background-color: var(--main-background-light-color);
border-radius: 8px;
transition: background-color 0.3s;
}
// NMessage // NMessage
.n-message-container { .n-message-container {
top: 20px !important; 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 动画 // Transition 动画
.fade-enter-active, .fade-enter-active,
.fade-leave-active { .fade-leave-active {

View File

@ -2,7 +2,7 @@
* 获取当前时间 * 获取当前时间
* @returns {Object} 时间对象 * @returns {Object} 时间对象
*/ */
export const getCurrentTime = () => { export const getCurrentTime = (ShowZero = true) => {
const time = new Date(); const time = new Date();
// 格式化 // 格式化
const formatTime = (value) => (value < 10 ? "0" + value : value); const formatTime = (value) => (value < 10 ? "0" + value : value);
@ -10,7 +10,7 @@ export const getCurrentTime = () => {
const year = time.getFullYear(); const year = time.getFullYear();
const month = time.getMonth() + 1; const month = time.getMonth() + 1;
const day = formatTime(time.getDate()); const day = formatTime(time.getDate());
const hour = formatTime(time.getHours()); const hour = ShowZero ? formatTime(time.getHours()) : time.getHours();
const minute = formatTime(time.getMinutes()); const minute = formatTime(time.getMinutes());
const second = formatTime(time.getSeconds()); const second = formatTime(time.getSeconds());
const weekdayArr = ["日", "一", "二", "三", "四", "五", "六"]; const weekdayArr = ["日", "一", "二", "三", "四", "五", "六"];