调整导航链接数据的结构,提高初次载入的速度

This commit is contained in:
2022-03-18 16:04:03 +08:00
parent 463aa3ae4b
commit 4fb4f13da3
3 changed files with 3796 additions and 3941 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,168 +1,48 @@
import { Loading, Notification } from 'element-ui';
let datas = {
// 链接数据(初始化后)
list: [],
// 版本信息
version: ''
};
// 链接数据(初始化前)
let navLinks = [];
let utils = {
/**
* 初始化导航链接数据
* 设置唯一 ID & 改变结构
*/
init: function () {
// 初始化提示
var loading = Loading.service({
customClass: 'loading-link',
lock: true,
spinner: 'el-icon-loading',
text: ''
});
var currentIndex = 0;
var currentIndexCpy = 0;
var fn = (obj) => {
currentIndex += 1;
obj.id = currentIndex;
// 有链接
if (obj.links != undefined) {
// 无子分类
if (obj.sub === undefined) {
obj.sub = [];
}
obj.links.forEach((item, index, arr) => {
// 添加到子分类(适配 Element UI - Tree
try {
obj.sub.push(item);
} catch (err) {
console.warn('[添加链接到 sub]', err);
console.warn('[出错的 obj]', obj);
}
// 到达最后一项,删除 links 自身
if (index === (arr.length - 1)) {
delete obj.links;
}
});
}
// 递归
if (obj.sub != undefined) {
obj.sub.forEach(item => {
setTimeout(() => {
fn(item);
}, 2 * currentIndex);
});
}
// 提示文本
loading.text = `初始化导航链接,请稍候 [${currentIndex}]`;
};
// 检测 currentIndex 是否已停止变化
var timer = setInterval(() => {
if (currentIndexCpy === currentIndex) {
// 停止检测
clearInterval(timer);
// 日志
console.log('[导航链接] 初始化完毕');
// 关闭提示
loading.close();
// 更新
datas.list = JSON.parse(JSON.stringify(navLinks));
// 写入缓存
setTimeout(() => {
this.cache('W', navLinks);
}, 1000);
}
// 同步
currentIndexCpy = currentIndex;
}, 5000);
return fn;
},
/**
* 导航链接数据缓存
*
* @param {string} mode 模式(读 - R写 - W
* @param {array} list 写入的导航链接数据模式为“W”时
*
* @returns {object} 缓存为最新时 status 为 1否则为 0list 为缓存中的导航链接数据。
*/
cache: function (mode, list) {
var datasCacheStr;
var datasCache = {};
var datasCurrent = {};
if (mode === 'R') {
// 读取缓存
datasCacheStr = localStorage.getItem('navLinksCache');
// 是否存在缓存
if (datasCacheStr === null) {
return {
status: 0
};
} else {
datasCache = JSON.parse(datasCacheStr)
}
// 链接数据为空
if (datasCache.list === undefined || datasCache.list.length === 0) {
return {
status: 0
};
}
// 版本号
if (datasCache.version != datas.version) {
return {
status: 0
};
} else {
return {
status: 1,
list: datasCache.list
};
}
} else if (mode === 'W') {
datasCurrent.version = datas.version;
datasCurrent.list = list;
// 写入缓存
localStorage.setItem('navLinksCache', JSON.stringify(datasCurrent));
import { Notification } from 'element-ui';
/** 初始化导航链接数据,设置唯一 ID */
const fnInit = function () {
let index = 0;
function fn(obj) {
// 更新
index += 1;
// 设置 ID
obj.id = index;
// 递归
if (obj.items) {
obj.items.forEach((item) => {
fn(item);
});
}
}
return fn;
};
const datas = {
list: [],
version: '',
};
// 读取链接数据
(function () {
let scriptElem = document.createElement('script');
const el = document.createElement('script');
// 加载失败
el.onerror = function () {
Notification.error({
title: '错误',
message: '导航链接载入失败',
duration: 0
});
};
// 加载成功
el.onload = function () {
const { frostNavLinks } = window;
scriptElem.onload = function () {
// 属性不存在
if (window.frostNavLinks === undefined) {
if (typeof frostNavLinks === 'undefined') {
Notification.error({
title: '错误',
message: '导航链接载入失败',
@@ -171,31 +51,27 @@ let utils = {
return;
}
// 同步
datas.version = window.frostNavLinks.version;
navLinks = window.frostNavLinks.list;
const {
list: navList,
version: navVersion,
} = frostNavLinks;
// 缓存
let cache = utils.cache('R');
// 缓存可以使用
if (cache.status === 1) {
datas.list = cache.list;
return;
}
let init = utils.init();
const init = fnInit();
// 初始化
navLinks.forEach(item => {
navList.forEach((item) => {
init(item);
});
datas.list = navList;
datas.version = navVersion;
};
scriptElem.setAttribute('type', 'text/javascript');
scriptElem.setAttribute('src', 'static/js/frostNavLinks.js');
el.setAttribute('type', 'text/javascript');
el.setAttribute('src', 'static/js/frostNavLinks.js');
document.body.appendChild(scriptElem);
document.body.appendChild(el);
})();

View File

@@ -150,7 +150,7 @@
:data="currentLinks"
node-key="id"
empty-text="没有查找到内容"
:props="{ label: 'title', children: 'sub' }"
:props="{ label: 'title', children: 'items' }"
:filter-node-method="searchLinkSubmit"
:default-expand-all="false"
:expand-on-click-node="true"
@@ -223,6 +223,13 @@
</template>
<script>
/**
* @typedef {object} NavLinkItem
* @property {string} title
* @property {string} desc
* @property {string} link
*/
import IconElement from '@/components/IconElement.vue';
export default {
@@ -326,33 +333,32 @@ export default {
},
methods: {
/**
* 更改当前显示的分类
*/
/** 更改当前显示的分类 */
changeCategory(index) {
const { navLinks, searchLink, show } = this;
if (index === 'search') {
this.currentLinks = [];
this.show.searchEngine = true;
this.show.searchLink = false;
this.show.linkTree = false;
show.searchEngine = true;
show.searchLink = false;
show.linkTree = false;
} else if (index === 'all') {
this.currentLinks = this.navLinks.list;
this.show.searchEngine = false;
this.show.searchLink = true;
this.show.linkTree = true;
this.currentLinks = navLinks.list;
show.searchEngine = false;
show.searchLink = true;
show.linkTree = true;
} else {
this.currentLinks = this.navLinks.list[Number(index)].sub;
this.show.searchEngine = false;
this.show.searchLink = true;
this.show.linkTree = true;
this.currentLinks = navLinks.list[Number(index)].items;
show.searchEngine = false;
show.searchLink = true;
show.linkTree = true;
}
this.searchLink.keyword = '';
searchLink.keyword = '';
},
/**
* 查看详情
*
* @description 查看详情
* @param {object} datas 当前链接的数据
*/
openDetail(datas) {
@@ -373,8 +379,7 @@ export default {
},
/**
* 打开链接
*
* @description 打开链接
* @param {string} link 需要打开的链接
* @param {boolean} showOnly 是否仅显示链接
*/
@@ -426,8 +431,7 @@ export default {
},
/**
* 搜索引擎(获取关键词建议)
*
* @description 搜索引擎(获取关键词建议)
* @param {string} keyword 当前输入的关键词
*/
searchEngineGS(keyword) {
@@ -467,9 +471,9 @@ export default {
// 处理数据
var cbFunc = (data) => {
var id = 0; // 结果 ID
var id = 0; // 结果 ID
var reqName = suggest.name; // 来源名称
if (reqName === '百度') {
// [百度]
let result = (data.g || []);
@@ -498,7 +502,7 @@ export default {
id += 1;
suggest.list.push({
id,
label: item.value,
label: item['value'],
highlight: keyword
});
});
@@ -514,9 +518,7 @@ export default {
});
},
/**
* 搜索引擎(搜索)
*/
/** 搜索引擎(搜索) */
searchEngineSubmit() {
var vm = this;
var se = this.searchEngine;
@@ -524,10 +526,10 @@ export default {
var keyword = se.keyword;
var url = '';
if (keyword === '') {
return false;
} else {
if (keyword) {
keyword = window.encodeURIComponent(keyword);
} else {
return false;
}
for (let category in se.list) {
@@ -545,46 +547,47 @@ export default {
},
/**
* 搜索链接(搜索)
*
* @param {string} value 关键词
* @param {object} data 每一项链接的信息
* @description 搜索链接(搜索)
* @param {string} keyword 关键词
* @param {NavLinkItem} data 每一项链接的信息
*/
searchLinkSubmit(value, data) {
searchLinkSubmit(keyword, data) {
// 关键词为空,显示全部
if (value === '') {
if (keyword === '') {
return true;
}
// 小写
value = value.toLowerCase();
// 转为小写
keyword = keyword.toLowerCase();
var searchType = this.searchLink.type;
var title = data.title.toLowerCase();
var link = (data.link || '');
var desc = (data.desc || '');
var result = false;
const type = this.searchLink.type;
const title = (data.title || '').toLowerCase();
const link = (data.link || '').toLowerCase();
const desc = (data.desc || '').toLowerCase();
if (searchType === 'all') {
switch (type) {
// 全部
let checks = [
(title.indexOf(value) !== -1),
(link.indexOf(value) !== -1),
(desc.indexOf(value) !== -1),
];
result = (checks[0] || checks[1] || checks[2]);
} else if (searchType === 'title') {
case 'all':
return (
title.includes(keyword) ||
link.includes(keyword) ||
desc.includes(keyword)
);
// 标题
result = (title.indexOf(value) !== -1);
} else if (searchType === 'link') {
case 'title':
return title.includes(keyword);
// 链接
result = (link.indexOf(value) !== -1);
} else if (searchType === 'desc') {
case 'link':
return link.includes(keyword);
// 简介
result = (desc.indexOf(value) !== -1);
case 'desc':
return desc.includes(keyword);
// 未知
default:
return false;
}
return result;
},
},