优化全局状态读写逻辑,使用 Vuex

This commit is contained in:
2022-03-20 21:49:43 +08:00
parent fdb9d31101
commit 83ea700eac
12 changed files with 556 additions and 402 deletions

View File

@@ -2,7 +2,7 @@
<div id="app">
<!-- 加载动画 -->
<div v-show="config.loading.subPage" class="loading-bar">
<div v-show="showLoading" class="loading-bar">
<div class="bar-content"></div>
</div>
@@ -20,7 +20,7 @@
<!-- 标题 -->
<el-menu-item
v-show="config.storage.showSiteTitle"
v-show="appConfig.showSiteTitle"
index="title"
class="title"
disabled
@@ -79,6 +79,8 @@
</template>
<script>
import { mapState } from 'vuex';
import FloatingBtn from '@/components/FloatingBtn.vue';
export default {
@@ -88,12 +90,10 @@ export default {
},
data() {
return {
config: this.$root.config,
debounce: {
saveConfig: null,
updateConfig: null
},
// Header 菜单项
debounceFontSize: null,
/** Header 菜单项 */
headerMenuItems: [
{
id: 'home',
@@ -116,12 +116,20 @@ export default {
routeName: 'About'
}
],
// 显示下拉菜单
showHeaderDropdown: false
/** 显示下拉菜单 */
showHeaderDropdown: false,
}
},
computed: {
// Header 默认激活的菜单项
...mapState({
appConfig: 'config',
showLoading: 'showLoading',
}),
/** Header 默认激活的菜单项 */
headerDefaultActive() {
var routeName = this.$route.name;
var item = '';
@@ -131,10 +139,23 @@ export default {
}
return item;
}
},
},
watch: {
// 更新字体大小
'appConfig.fontSize': {
handler(value) {
clearTimeout(this.debounceFontSize);
this.debounceFontSize = setTimeout(() => {
document.documentElement.style.fontSize = `${value}px`;
}, 500);
}
},
// 路由名称
'$route.name': {
handler() {
@@ -143,40 +164,18 @@ export default {
}
},
// 更新储存的设置
'config.storage': {
handler(obj) {
clearTimeout(this.debounce.saveConfig);
this.debounce.saveConfig = setTimeout(() => {
localStorage.setItem('navConfig', JSON.stringify(obj));
}, 2000);
},
deep: true
},
created() {
this.init();
},
methods: {
/** 初始化 */
init() {
this.$store.commit('readConfig');
},
// 改变字体大小
'config.storage.fontSize': {
handler(value) {
clearTimeout(this.debounce.updateConfig);
this.debounce.updateConfig = setTimeout(() => {
// 改变字体大小
document.documentElement.style.fontSize = value + 'px';
}, 1000);
}
}
},
mounted() {
var configStr = localStorage.getItem('navConfig');
var configObj = {};
if (configStr != null) {
configObj = JSON.parse(configStr);
Object.assign(this.config.storage, configObj);
}
}
}
</script>

View File

@@ -2,160 +2,6 @@ let config = {
loading: {
subPage: false
},
searchEngines: {
search: {
title: '搜索',
list: [
{
name: '百度',
desc: 'www.baidu.com',
url: 'https://www.baidu.com/s?wd=%keyword%',
icon: 'website/baidu.svg',
show: true
},
{
name: '必应',
desc: 'cn.bing.com',
url: 'https://cn.bing.com/search?q=%keyword%',
icon: 'website/bing.svg',
show: true
},
{
name: '秘迹',
desc: 'mijisou.com',
url: 'https://mijisou.com/?q=%keyword%',
icon: 'website/mijisou.svg',
show: true
},
{
name: '搜狗',
desc: 'www.sogou.com',
url: 'https://www.sogou.com/web?query=%keyword%',
icon: 'website/sogou.svg',
show: true
},
{
name: '360',
desc: 'www.so.com',
url: 'https://www.so.com/s?q=%keyword%',
icon: 'website/360.svg',
show: true
},
{
name: 'Google',
desc: 'www.google.com',
url: 'https://www.google.com/search?q=%keyword%',
icon: 'website/google.svg',
show: true
},
{
name: 'Yandex',
desc: 'yandex.com',
url: 'https://yandex.com/search/?text=%keyword%',
icon: 'website/yandex.svg',
show: true
}
]
},
media: {
title: '多媒体',
list: [
{
name: '网易云音乐',
desc: 'music.163.com',
url: 'https://music.163.com/#/search/m/?s=%keyword%',
icon: 'website/netease_music.svg',
show: true
},
{
name: 'AcFun',
desc: 'www.acfun.cn',
url: 'https://www.acfun.cn/search/?keyword=%keyword%',
icon: 'website/acfun.svg',
show: true
},
{
name: 'bilibili',
desc: 'search.bilibili.com',
url: 'https://search.bilibili.com/all?keyword=%keyword%',
icon: 'website/bilibili.svg',
show: true
},
{
name: 'QQ音乐',
desc: 'y.qq.com',
url: 'https://y.qq.com/n/ryqq/search?w=%keyword%',
icon: 'website/qq_music.svg',
show: true
}
]
},
technology: {
title: '技术',
list: [
{
name: 'CSDN',
desc: 'so.csdn.net',
url: 'https://so.csdn.net/so/search/all?q=%keyword%',
icon: 'website/csdn.svg',
show: true
},
{
name: 'GitHub',
desc: 'github.com',
url: 'https://github.com/search?q=%keyword%',
icon: 'website/github.svg',
show: true
},
{
name: 'MDN',
desc: 'developer.mozilla.org',
url: 'https://developer.mozilla.org/zh-CN/search?q=%keyword%',
icon: 'website/mdn.svg',
show: true
}
]
},
design: {
title: '设计',
list: [
{
name: '站酷',
desc: 'www.zcool.com.cn',
url: 'https://www.zcool.com.cn/search/content?word=%keyword%',
icon: 'website/zcool.svg',
show: true
},
{
name: 'Iconfont',
desc: 'www.iconfont.cn',
url: 'https://www.iconfont.cn/search/index?searchType=icon&q=%keyword%',
icon: 'website/iconfont.svg',
show: true
}
]
},
community: {
title: '社区',
list: [
{
name: '天涯',
desc: 'search.tianya.cn',
url: 'https://search.tianya.cn/bbs?q=%keyword%',
icon: 'website/tianya.svg',
show: true
},
{
name: '知乎',
desc: 'www.zhihu.com',
url: 'https://www.zhihu.com/search?type=content&q=%keyword%',
icon: 'website/zhihu.svg',
show: true
}
]
}
},
siteName: 'Frost 网址导航',
storage: {
fontSize: 16,
showSiteTitle: true,

View File

@@ -1,52 +1,3 @@
/**
* @description 解析推荐的关键词
* @param {string} type 来源类型
* @param {*} datas 关键词数据
* @param {number} [max] 最大返回数量
* @returns {string[]} 关键词列表
*/
function parseSearchWords(type = '', datas = null, max = 10) {
if (!datas) {
return [];
}
/** @type {string[]} */
let words = [];
try {
switch (type) {
case '360':
words = parseSearch360(datas);
case 'baidu':
words = parseSearchBaidu(datas);
case 'bing':
words = parseSearchBing(datas);
default:
break;
}
} catch (error) {
console.error('解析失败');
return [];
}
const arrLength = words.length;
const cutLength = Math.max(arrLength - max, 0);
const cutStart = arrLength - cutLength;
words.splice(cutStart, cutLength);
let value = '';
for (value of words) {
if (typeof value !== 'string') {
console.error('关键词的数据类型错误');
return [];
}
}
return words;
}
/**
* @desc 解析 360 推荐关键词2021-12-29
* @param {{ result: { word: string }[] }} datas
@@ -91,10 +42,41 @@ function parseSearchBing(datas) {
return words;
}
/**
* @typedef MDNSearchIndexDatas
* @type {{ title: string, url: string }[]}
*/
/**
* @description 解析 MDN 搜索关键词
* @param {MDNSearchIndexDatas} datas 关键词数据
* @param {string} keyword 输入的关键词
* @param {number} [max] 最多返回的结果数量,默认为 10
* @returns {MDNSearchIndexDatas} 匹配到的关键词
*/
function parseSearchMDN(datas = [], keyword = '', max = 10) {
/** @type {MDNSearchIndexDatas} */
const result = [];
const word = String(keyword).toLowerCase();
let count = 0;
for (const item of datas) {
if (item.title.toLowerCase().indexOf(word) > -1) {
result.push(item);
if ((count += 1) >= max) {
break;
}
}
}
return result;
}
/**
* @description 获取搜索 URL
* @param {string} type 搜索引擎类型
* @param {string} word 搜索关键词
* @param {string} type 搜索引擎类型
* @param {string} word 搜索关键词
* @param {string} [cbName] 回调函数名称,用于获取推荐关键词
* @returns {(string|null)} 根据参数返回不同的结果
* - 无 `cbName` 时返回搜索结果页面 URL
@@ -128,6 +110,207 @@ function getSearchURL(type, word, cbName) {
}
}
/**
* @description 解析推荐的关键词
* @param {string} type 来源类型
* @param {*} datas 关键词数据
* @param {number} [max] 最大返回数量
* @returns {string[]} 关键词列表
*/
function parseSearchWords(type = '', datas = null, max = 10) {
if (!datas) {
return [];
}
/** @type {string[]} */
let words = [];
try {
switch (type) {
case '360':
words = parseSearch360(datas);
break;
case 'baidu':
words = parseSearchBaidu(datas);
break;
case 'bing':
words = parseSearchBing(datas);
break;
default:
console.error('来源类型错误');
return [];
}
} catch (error) {
console.error('解析失败');
return [];
}
const arrLength = words.length;
const cutLength = Math.max(arrLength - max, 0);
const cutStart = arrLength - cutLength;
words.splice(cutStart, cutLength);
let value = '';
for (value of words) {
if (typeof value !== 'string') {
console.error('关键词的数据类型错误');
return [];
}
}
return words;
}
/** 搜索引擎列表 */
const searchEngines = {
search: {
title: '搜索',
list: [
{
name: '百度',
desc: 'www.baidu.com',
url: 'https://www.baidu.com/s?wd=%keyword%',
icon: 'website/baidu.svg',
show: true
},
{
name: '必应',
desc: 'cn.bing.com',
url: 'https://cn.bing.com/search?q=%keyword%',
icon: 'website/bing.svg',
show: true
},
{
name: '搜狗',
desc: 'www.sogou.com',
url: 'https://www.sogou.com/web?query=%keyword%',
icon: 'website/sogou.svg',
show: true
},
{
name: '360',
desc: 'www.so.com',
url: 'https://www.so.com/s?q=%keyword%',
icon: 'website/360.svg',
show: true
},
{
name: 'Google',
desc: 'www.google.com',
url: 'https://www.google.com/search?q=%keyword%',
icon: 'website/google.svg',
show: true
},
{
name: 'Yandex',
desc: 'yandex.com',
url: 'https://yandex.com/search/?text=%keyword%',
icon: 'website/yandex.svg',
show: true
}
]
},
media: {
title: '多媒体',
list: [
{
name: '网易云音乐',
desc: 'music.163.com',
url: 'https://music.163.com/#/search/m/?s=%keyword%',
icon: 'website/netease_music.svg',
show: true
},
{
name: 'AcFun',
desc: 'www.acfun.cn',
url: 'https://www.acfun.cn/search/?keyword=%keyword%',
icon: 'website/acfun.svg',
show: true
},
{
name: 'bilibili',
desc: 'search.bilibili.com',
url: 'https://search.bilibili.com/all?keyword=%keyword%',
icon: 'website/bilibili.svg',
show: true
},
{
name: 'QQ音乐',
desc: 'y.qq.com',
url: 'https://y.qq.com/n/ryqq/search?w=%keyword%',
icon: 'website/qq_music.svg',
show: true
}
]
},
technology: {
title: '技术',
list: [
{
name: 'CSDN',
desc: 'so.csdn.net',
url: 'https://so.csdn.net/so/search/all?q=%keyword%',
icon: 'website/csdn.svg',
show: true
},
{
name: 'GitHub',
desc: 'github.com',
url: 'https://github.com/search?q=%keyword%',
icon: 'website/github.svg',
show: true
},
{
name: 'MDN',
desc: 'developer.mozilla.org',
url: 'https://developer.mozilla.org/zh-CN/search?q=%keyword%',
icon: 'website/mdn.svg',
show: true
}
]
},
design: {
title: '设计',
list: [
{
name: '站酷',
desc: 'www.zcool.com.cn',
url: 'https://www.zcool.com.cn/search/content?word=%keyword%',
icon: 'website/zcool.svg',
show: true
},
{
name: 'Iconfont',
desc: 'www.iconfont.cn',
url: 'https://www.iconfont.cn/search/index?searchType=icon&q=%keyword%',
icon: 'website/iconfont.svg',
show: true
}
]
},
community: {
title: '社区',
list: [
{
name: '天涯',
desc: 'search.tianya.cn',
url: 'https://search.tianya.cn/bbs?q=%keyword%',
icon: 'website/tianya.svg',
show: true
},
{
name: '知乎',
desc: 'www.zhihu.com',
url: 'https://www.zhihu.com/search?type=content&q=%keyword%',
icon: 'website/zhihu.svg',
show: true
}
]
}
};
/**
* @typedef {object} SearchItem
* @property {string} name 名称
@@ -154,3 +337,10 @@ const searchItems = [
// wordURL: 'https://sg1.api.bing.com/qsonhs.aspx?type=cb&cb={cb}&q={w}',
},
];
export default {
getSearchURL,
parseSearchMDN,
parseSearchWords,
searchEngines,
};

View File

@@ -1,5 +1,3 @@
import config from './config.js';
class Utils {
constructor() { }
@@ -9,7 +7,7 @@ class Utils {
* @param {string} [value] 新的标题
*/
changeTitle(value) {
document.title = (value ? (value + ' - ') : '') + config.siteName;
document.title = ((value ? `${value} - ` : '') + 'Frost 网址导航');
}
/**

View File

@@ -24,8 +24,7 @@ export default {
name: 'FloatingBtn',
data() {
return {
config: this.$root.config.storage,
showInner: false
showInner: false,
}
},
mounted () {
@@ -33,9 +32,7 @@ export default {
},
methods: {
/**
* 设置动画
*/
/** 设置动画 */
initAnimation() {
var vm = this;
var el = vm.$refs['floatingBtn'];
@@ -53,16 +50,12 @@ export default {
});
},
/**
* 切换按钮显示
*/
/** 切换按钮显示 */
toggleInnerBtns() {
this.showInner = !this.showInner;
},
/**
* 返回主页
*/
/** 返回主页 */
backToHome() {
const routeName = 'Home';
@@ -77,19 +70,14 @@ export default {
}
},
/**
* 刷新
*/
/** 刷新 */
refreshPage() {
window.location.reload();
},
/**
* 切换侧边菜单折叠状态
*/
/** 切换侧边菜单折叠状态 */
toggleSideCollapse() {
var cfg = this.config;
cfg.sideMenuCollapse = !cfg.sideMenuCollapse;
this.$store.dispatch('toggleSideCollapse');
},
},

View File

@@ -4,10 +4,6 @@ import App from './App.vue';
import router from './router';
import store from './store';
import config from './assets/js/config';
import navLinks from './assets/js/navLinks';
import utils from './assets/js/utils';
import 'ress/ress.css';
import 'font-awesome/css/font-awesome.min.css';
import './assets/css/element.scss';
@@ -20,12 +16,5 @@ Vue.config.productionTip = false;
new Vue({
router,
store,
data: function () {
return {
config,
navLinks,
utils
}
},
render: h => h(App)
}).$mount('#app');

View File

@@ -2,8 +2,8 @@ import Vue from 'vue';
import VueRouter from 'vue-router';
import routes from './routes';
import config from '@/assets/js/config';
import utils from '@/assets/js/utils';
import store from '@/store/index';
Vue.use(VueRouter);
@@ -11,18 +11,16 @@ const router = new VueRouter({
routes
});
// to, from, next
router.beforeEach((to, from, next) => {
if (to.meta.loadingBar) {
config.loading.subPage = true;
store.commit('toggleLoading', true);
}
next();
});
// to, from
router.afterEach((to) => {
if (to.meta.loadingBar) {
config.loading.subPage = false;
store.commit('toggleLoading', false);
}
utils.changeTitle(to.meta.title);
});

View File

@@ -4,9 +4,111 @@ import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {},
state: {
/** 设置 */
config: {
fontSize: 16,
showSiteTitle: true,
sideMenuCollapse: true,
searchEngine: '百度',
searchSuggestion: false,
},
/** 显示加载动画 */
showLoading: false,
},
getters: {},
mutations: {},
actions: {},
mutations: {
/** 从本地储存中读取设置 */
readConfig(state) {
let keyName = 'fn_config';
let storage = localStorage.getItem(keyName);
let parsed = null;
let config = state.config;
try {
parsed = JSON.parse(storage);
} catch (error) {
console.error('解析保存的设置失败。');
}
if (parsed && parsed.constructor === Object) {
// [本地储存中有数据,读取]
for (let key in config) {
let value = parsed[key];
if (typeof value !== 'undefined') {
config[key] = value;
}
}
} else {
// [本地储存中无数据,写入]
localStorage.setItem(keyName, JSON.stringify(config));
}
},
/** 重置保存的设置 */
resetConfig() {
localStorage.removeItem('fn_config');
},
/**
* @description 更新设置
* @param {object} payload
* @param {string} payload.key
* @param {any} payload.value
*/
setConfig(state, payload) {
const {
key: cKey = null,
value: cValue = null,
} = payload;
const { config } = state;
if (cKey === null) {
console.error('更新设置失败key 为空。');
return;
}
if (typeof config[cKey] === 'undefined') {
console.error('更新设置失败key 不存在。');
return;
}
// 更新设置
config[cKey] = cValue;
// 保存设置
localStorage.setItem('fn_config', JSON.stringify(config));
},
/** 切换加载动画显示隐藏 */
toggleLoading(state, payload = false) {
state.showLoading = payload;
},
},
actions: {
/** 切换导航链接侧边菜单显示隐藏 */
toggleSideCollapse(store) {
const { sideMenuCollapse } = store.state.config;
store.commit('setConfig', {
key: 'sideMenuCollapse',
value: !sideMenuCollapse,
});
},
},
modules: {},
});

View File

@@ -41,11 +41,13 @@
</template>
<script>
import navLinks from '@/assets/js/navLinks';
export default {
name: 'AboutView',
data() {
return {
navLinks: this.$root.navLinks,
navLinks,
info: {
github: 'https://github.com/Frost-ZX/frost-navigation'
}

View File

@@ -6,7 +6,7 @@
<el-menu
class="side-nav"
default-active="search"
:collapse="config.sideMenuCollapse"
:collapse="appConfig.sideMenuCollapse"
:collapse-transition="false"
@select="changeCategory"
>
@@ -41,32 +41,32 @@
<div class="wrapper">
<!-- 搜索引擎 -->
<div v-show="show.searchEngine" class="search-engine">
<div v-show="show.searchNet" class="search-engine">
<!-- 搜索栏 -->
<div :class="['search-bar', 'shadow-3', { suggest: showSES }]">
<!-- 输入 -->
<input
v-model="searchEngine.keyword"
v-model="searchNet.keyword"
class="input"
type="text"
@blur="searchEngine.isFocus = false"
@focus="searchEngine.isFocus = true"
@keydown.enter.exact="searchEngineSubmit()"
@blur="searchNet.isFocus = false"
@focus="searchNet.isFocus = true"
@keydown.enter.exact="searchNetSubmit()"
/>
<!-- 清除 -->
<div
v-show="searchEngine.keyword.length > 0"
v-show="searchNet.keyword.length > 0"
class="btn btn-clear"
@click="searchEngine.keyword = ''"
@click="searchNet.keyword = ''"
>
<i class="el-icon-close"></i>
</div>
<!-- 搜索 -->
<div class="btn btn-search" @click="searchEngineSubmit()">
<div class="btn btn-search" @click="searchNetSubmit()">
<i class="el-icon-search"></i>
</div>
@@ -74,9 +74,9 @@
<div class="suggestion shadow-3">
<ul>
<li
v-for="item in searchEngine.suggest.list"
v-for="item in searchNet.suggest.list"
:key="item.id"
@click="searchEngine.keyword = item.label"
@click="searchNet.keyword = item.label"
>
<!-- 文本 -->
<span class="label">{{ item.label }}</span>
@@ -86,7 +86,7 @@
effect="plain"
size="mini"
type="success"
>{{ searchEngine.suggest.name }}</el-tag>
>{{ searchNet.suggest.name }}</el-tag>
</li>
</ul>
</div>
@@ -95,13 +95,13 @@
<!-- 选择搜索引擎 -->
<el-radio-group
v-model="config.searchEngine"
v-model="configSearchEngine"
size="small"
:class="['search-type', { fade: searchEngine.isFocus }]"
:class="['search-type', { fade: searchNet.isFocus }]"
>
<!-- 分类 -->
<div
v-for="(category, cIndex) in searchEngine.list"
v-for="(category, cIndex) in searchNet.list"
:key="cIndex"
class="category"
>
@@ -230,6 +230,11 @@
* @property {string} link
*/
import { mapState } from 'vuex';
import navLinks from '@/assets/js/navLinks';
import searchUtils from '@/assets/js/search-utils';
import utils from '@/assets/js/utils';
import IconElement from '@/components/IconElement.vue';
export default {
@@ -239,19 +244,19 @@ export default {
},
data() {
return {
config: this.$root.config.storage,
utils: this.$root.utils,
// 显示的内容
/** 显示的内容 */
show: {
searchEngine: true,
searchNet: true,
searchLink: false,
linkTree: false,
},
// 搜索引擎
searchEngine: {
/** 网络搜索 */
searchNet: {
isFocus: false,
keyword: '',
list: this.$root.config.searchEngines,
list: searchUtils.searchEngines,
url: '',
debounce: null,
suggest: {
@@ -259,17 +264,21 @@ export default {
name: '',
},
},
// 导航链接
navLinks: this.$root.navLinks,
// 当前显示的链接
/** 导航链接数据 */
navLinks,
/** 当前显示的链接 */
currentLinks: [],
// 搜索链接
/** 链接搜索 */
searchLink: {
debounce: null,
keyword: '',
type: 'all'
},
// 链接详情
/** 链接详情 */
linkDetail: {
show: false,
id: '',
@@ -279,19 +288,39 @@ export default {
desc: '',
update: '',
},
};
},
computed: {
...mapState({
appConfig: 'config',
}),
/** 设置 - 搜索引擎名称 */
configSearchEngine: {
/** @this */
get() {
return this.appConfig.searchEngine;
},
set(value) {
this.$store.commit('setConfig', {
key: 'searchEngine',
value,
});
},
},
/**
* 显示搜索引擎关键词建议
* @description 显示搜索引擎关键词建议
* @this
*/
showSES() {
var se = this.searchEngine;
var sn = this.searchNet;
var isShow = (
(se.isFocus) &&
(se.keyword !== '') &&
(se.suggest.list.length > 0)
(sn.isFocus) &&
(sn.keyword !== '') &&
(sn.suggest.list.length > 0)
);
return isShow;
@@ -299,18 +328,20 @@ export default {
},
watch: {
'searchEngine.keyword': {
'searchNet.keyword': {
handler(value) {
if (!this.config.searchSuggestion) {
if (!this.appConfig.searchSuggestion) {
return;
}
clearInterval(this.searchEngine.debounce);
this.searchEngine.debounce = setTimeout(() => {
clearInterval(this.searchNet.debounce);
this.searchNet.debounce = setTimeout(() => {
value = window.encodeURIComponent(value);
this.searchEngineGS(value);
this.searchNetGS(value);
}, 500);
}
},
'searchLink.keyword': {
handler(value) {
clearTimeout(this.searchLink.debounce);
@@ -319,12 +350,14 @@ export default {
}, 500);
}
},
'searchLink.type': {
handler() {
// 更改搜索类型时自动重新搜索
this.$refs.linkTree.filter(this.searchLink.keyword);
}
},
},
methods: {
@@ -334,17 +367,17 @@ export default {
if (index === 'search') {
this.currentLinks = [];
show.searchEngine = true;
show.searchNet = true;
show.searchLink = false;
show.linkTree = false;
} else if (index === 'all') {
this.currentLinks = navLinks.list;
show.searchEngine = false;
show.searchNet = false;
show.searchLink = true;
show.linkTree = true;
} else {
this.currentLinks = navLinks.list[Number(index)].items;
show.searchEngine = false;
show.searchNet = false;
show.searchLink = true;
show.linkTree = true;
}
@@ -394,45 +427,14 @@ export default {
}
},
/**
* @typedef MDNSearchIndexDatas
* @type {{ title: string, url: string }[]}
*/
/**
* @description 解析 MDN 搜索关键词
* @param {MDNSearchIndexDatas} datas 关键词数据
* @param {string} keyword 输入的关键词
* @param {number} [max] 最多返回的结果数量,默认为 10
* @returns {MDNSearchIndexDatas} 匹配到的关键词
*/
parseMDNSearchWords(datas = [], keyword = '', max = 10) {
/** @type {MDNSearchIndexDatas} */
const result = [];
const word = String(keyword).toLowerCase();
let count = 0;
for (const item of datas) {
if (item.title.toLowerCase().indexOf(word) > -1) {
result.push(item);
if ((count += 1) >= max) {
break;
}
}
}
return result;
},
/**
* @description 搜索引擎(获取关键词建议)
* @param {string} keyword 当前输入的关键词
*/
searchEngineGS(keyword) {
var suggest = this.searchEngine.suggest;
searchNetGS(keyword) {
var suggest = this.searchNet.suggest;
// 设置的搜索引擎名称
var configSE = this.config.searchEngine;
var configSE = this.configSearchEngine;
// 关键词建议来源信息(默认使用百度)
var reqURLs = [
{
@@ -506,7 +508,7 @@ export default {
};
// 使用 JSONP 获取
this.utils.jsonp({
utils.jsonp({
url: reqURL,
cbName: 'cbSES',
cbFunc
@@ -514,11 +516,11 @@ export default {
},
/** 搜索引擎(搜索) */
searchEngineSubmit() {
searchNetSubmit() {
var vm = this;
var se = this.searchEngine;
var selectedSE = this.config.searchEngine;
var keyword = se.keyword;
var sn = this.searchNet;
var selectedSE = this.configSearchEngine;
var keyword = sn.keyword;
var url = '';
if (keyword) {
@@ -527,8 +529,8 @@ export default {
return false;
}
for (let category in se.list) {
let list = se.list[category].list;
for (let category in sn.list) {
let list = sn.list[category].list;
for (let index in list) {
if (list[index].name === selectedSE) {

View File

@@ -6,7 +6,7 @@
<el-form-item label="字体大小" class="set-font">
<el-input-number
v-model="config.fontSize"
v-model="configFontSize"
:min="12"
:max="32"
controls-position="right"
@@ -16,28 +16,23 @@
</el-form-item>
<el-form-item label="显示网站标题">
<el-switch v-model="config.showSiteTitle"></el-switch>
<el-switch v-model="configShowSiteTitle"></el-switch>
</el-form-item>
<el-form-item label="折叠主页侧边菜单">
<el-switch v-model="config.sideMenuCollapse"></el-switch>
<el-switch v-model="configSideMenuCollapse"></el-switch>
</el-form-item>
<el-form-item label="获取搜索引擎关键词建议">
<el-switch v-model="config.searchSuggestion"></el-switch>
<el-switch v-model="configSearchSuggestion"></el-switch>
</el-form-item>
<el-form-item label="清除数据">
<el-button
type="danger"
size="medium"
@click="resetDatas('settings')"
@click="resetDatas()"
>清除设置</el-button>
<el-button
type="danger"
size="medium"
@click="resetDatas('cache')"
>清除缓存</el-button>
</el-form-item>
</el-form>
@@ -47,34 +42,83 @@
</template>
<script>
import { mapState } from 'vuex';
export default {
name: 'SettingsView',
data() {
return {
config: this.$root.config.storage,
}
return { }
},
computed: {
...mapState({
appConfig: 'config',
}),
configFontSize: {
/** @this */
get() {
return this.appConfig.fontSize;
},
set(value) {
this.$store.commit('setConfig', {
key: 'fontSize',
value,
});
},
},
configShowSiteTitle: {
/** @this */
get() {
return this.appConfig.showSiteTitle;
},
set(value) {
this.$store.commit('setConfig', {
key: 'showSiteTitle',
value,
});
},
},
configSideMenuCollapse: {
/** @this */
get() {
return this.appConfig.sideMenuCollapse;
},
set(value) {
this.$store.commit('setConfig', {
key: 'sideMenuCollapse',
value,
});
},
},
configSearchSuggestion: {
/** @this */
get() {
return this.appConfig.searchSuggestion;
},
set(value) {
this.$store.commit('setConfig', {
key: 'searchSuggestion',
value,
});
},
},
},
methods: {
/**
* 清除数据
*
* @param {string} type 清除类型cache、settings
*/
resetDatas(type) {
/** 清除数据 */
resetDatas() {
this.$confirm('确定要清除吗?', '', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (type === 'cache') {
localStorage.removeItem('navLinksCache');
} else if (type === 'settings') {
localStorage.removeItem('navConfig');
} else {
return
}
this.$store.commit('resetConfig');
this.$message({
message: '已清除2s 后自动刷新',

View File

@@ -43,11 +43,7 @@
export default {
name: 'ToolsDetail',
data() {
return {
}
return { }
},
computed: {