no message

This commit is contained in:
CN32479-詹红柱 2021-08-18 15:45:41 +08:00
parent e0a2d6e0dd
commit a6902abac2
3 changed files with 174 additions and 13 deletions

View File

@ -24,7 +24,10 @@
</noscript> </noscript>
<!-- 内容区域 --> <!-- 内容区域 -->
<div id="app" style="height: 100%;"> <div id="app" style="height: 100%;">
</div>
<!-- 导出内容的节点 -->
<div id="mybookmark" style="height: 100%;display: none;opacity: 0;">
</div> </div>
<!-- 渐变背景 --> <!-- 渐变背景 -->
<canvas id="canvas-complex" <canvas id="canvas-complex"

View File

@ -4,7 +4,7 @@
<div class="bookmark" id="bookmark"> <div class="bookmark" id="bookmark">
<div class="tool-bar"> <div class="tool-bar">
<div class="tool-logo"> <div class="tool-logo">
<a href="" target="_blank"><img src="./assets/svg/logo.svg" title="更多数据" class="tool-icon" />红隼书签</a> <a href="" target="_blank"><img src="./assets/svg/logo.svg" title="感谢作者 是半夏鸭 设计的图标" class="tool-icon" />红隼书签</a>
</div> </div>
<div> <div>
<div class="search-box"> <div class="search-box">
@ -21,9 +21,19 @@
<!-- 侧边导航栏 --> <!-- 侧边导航栏 -->
<div class="box-m"> <div class="box-m">
<div class="left-box"> <div class="left-box">
<div class="label" :class="activeIndex===index?'active':'inactive'" v-for="(item,index) in data" :key="index" @click="selectType(item,index)"> <div class="left-box-item">
<img src="./assets/svg/file.svg" /> <div class="label" :class="activeIndex===index?'active':'inactive'" v-for="(item,index) in data" :key="index" @click="selectType(item,index)">
<div class="text-elipss"> {{item.type}} </div> <img src="./assets/svg/file.svg" />
<div class="text-elipss"> {{item.type}} </div>
</div>
</div>
<!-- 导入导出 -->
<div class="import-tool">
<span class="import-text">导入/导出&nbsp;</span>
<i class="el-icon-upload2" title="导入浏览器书签" @click="importBookmark">
<input type="file" ref="filElem" id="file">
</i>
<i class="el-icon-download" title="导出浏览器书签" @click="exportBookmark"></i>
</div> </div>
</div> </div>
<div class="right-box"> <div class="right-box">
@ -69,6 +79,7 @@ import { watch } from '@vue/runtime-core'
import Dialog from './components/Dialog.vue' import Dialog from './components/Dialog.vue'
import gsap from 'gsap' import gsap from 'gsap'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { importBookmark, exportBookmark } from './components/utils.js'
var rowData = [] var rowData = []
function getData(fn = () => {}) { function getData(fn = () => {}) {
// //
@ -126,11 +137,17 @@ export default {
// //
function add(row = {}, flag = 'add') { function add(row = {}, flag = 'add') {
const temp = {...row} const temp = { ...row }
if (flag === 'modify') { if (flag === 'modify') {
data.detail = Object.assign(temp, { type: rowData[data.activeIndex].type, flag: 'modify' }) data.detail = Object.assign(temp, {
type: rowData[data.activeIndex].type,
flag: 'modify'
})
} else { } else {
data.detail = Object.assign({}, { type: rowData[data.activeIndex].type, flag: 'add' }) data.detail = Object.assign(
{},
{ type: rowData[data.activeIndex].type, flag: 'add' }
)
} }
data.isDetailVisible = true data.isDetailVisible = true
} }
@ -147,10 +164,14 @@ export default {
// //
const deleteClick = (row) => { const deleteClick = (row) => {
const myData = JSON.parse(localStorage.getItem('BOOKMARK')) const myData = JSON.parse(localStorage.getItem('BOOKMARK'))
const delDetail = Object.assign(row, { type: rowData[data.activeIndex].type }) const delDetail = Object.assign(row, {
type: rowData[data.activeIndex].type
})
for (let i = 0; i < myData.length; i++) { for (let i = 0; i < myData.length; i++) {
if (delDetail.type === myData[i].type) { if (delDetail.type === myData[i].type) {
const cindex = myData[i].children.findIndex(s => s.title === delDetail.title) const cindex = myData[i].children.findIndex(
(s) => s.title === delDetail.title
)
if (cindex > -1) { if (cindex > -1) {
myData[i].children.splice(cindex, 1) myData[i].children.splice(cindex, 1)
localStorage.setItem('BOOKMARK', JSON.stringify(myData)) localStorage.setItem('BOOKMARK', JSON.stringify(myData))
@ -167,7 +188,9 @@ export default {
navigate, navigate,
add, add,
closeViews, closeViews,
search search,
importBookmark,
exportBookmark
} }
}, },
methods: { methods: {
@ -218,7 +241,7 @@ export default {
border: 1px solid rgba(255, 255, 255, 0.18); border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2); box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
position: relative; position: relative;
overflow-y: auto; // overflow-y: auto;
padding: 8px 0; padding: 8px 0;
img { img {
width: 20px; width: 20px;
@ -283,7 +306,7 @@ export default {
animation: 0.3ms; animation: 0.3ms;
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, 0.3); box-shadow: 0 8px 18px 0 rgba(31, 38, 135, 0.3);
} }
&:hover .logo-box-tools{ &:hover .logo-box-tools {
opacity: 0.85; opacity: 0.85;
} }
} }
@ -444,7 +467,7 @@ export default {
right: 0; right: 0;
top: 0; top: 0;
opacity: 0; opacity: 0;
transition:0.4s opacity; transition: 0.4s opacity;
i { i {
padding: 4px; padding: 4px;
display: inline-block; display: inline-block;
@ -455,4 +478,52 @@ export default {
} }
} }
} }
.import-tool {
position: absolute;
width: 100%;
background: #fbf5f5;
height: 36px;
padding: 3px 15px;
display: flex;
align-items: center;
bottom: 0;
z-index: 99;
i {
font-size: 18px;
margin: 1px 4px;
padding: 4px;
cursor: pointer;
color: #e03b5d;
background: #ff00001f;
border-radius: 5px;
opacity: 0.7;
&:hover {
color: #e03b5d;
background: #c804041f;
opacity: 1;
}
}
}
.left-box-item {
height: 100%;
overflow-y: auto;
padding-bottom: 40px;
}
.import-text {
font-size: 12px;
color: #999;
margin-right: 3px;
}
.el-icon-upload2 {
position: relative;
input {
width: 1.46rem;
height: 100%;
z-index: 1;
opacity: 0;
position: absolute;
cursor: pointer;
}
}
</style> </style>

87
src/components/utils.js Normal file
View File

@ -0,0 +1,87 @@
function walkBookmarksTree(root) {
const result = []
// 深度优先遍历
const walk = (node, list) => {
const els = node.children
if (els && els.length > 0) {
for (let i = 0; i < els.length; i++) {
const item = els[i]
// p标签或h3标签直接跳过
if (item.tagName === 'P' || item.tagName === 'H3') {
continue
}
// 文件夹不用创建元素
if (item.tagName === 'DL') {
walk(els[i], list)
} else { // DT节点
let child = null
// 判断是否是文件夹
const children = item.children
let isDir = false
for (let j = 0; j < children.length; j++) {
if (children[j].tagName === 'H3' || children[j].tagName === 'DL') {
isDir = true
}
}
// 文件夹
if (isDir) {
child = {
name: item.tagName === 'DT' ? item.querySelector('h3') ? item.querySelector('h3').innerText : '' : '',
folder: true,
children: []
}
walk(els[i], child.children)
} else { // 书签
const _item = item.querySelector('a')
if (_item) {
child = {
name: _item?.innerText,
url: _item?.href
}
}
}
child && list.push(child)
}
}
}
}
walk(root, result)
return result
}
// 导入
export function importBookmark() {
const file = document.getElementById('file')
file.dispatchEvent(new MouseEvent('click'))
const mybookmark = document.getElementById('mybookmark')
document.getElementById('file').addEventListener('change', function () {
var file = document.getElementById('file').files[0]
var reader = new FileReader()
reader.readAsText(file, 'utf-8')
reader.onload = function () {
mybookmark.innerHTML = reader.result
console.log(walkBookmarksTree(mybookmark))
// const myData = walkBookmarksTree(mybookmark)
// myData && localStorage.setItem('BOOKMARK', myData)
}
})
}
// 导出数据为JSON下载
export function exportBookmark() {
if (localStorage.getItem('BOOKMARK')) {
var content = localStorage.getItem('BOOKMARK')
var eleLink = document.createElement('a')
eleLink.download = 'kestrel-bookmark.json'
eleLink.style.display = 'none'
// 字符内容转变成blob地址
var blob = new Blob([content])
eleLink.href = URL.createObjectURL(blob)
// 触发点击
document.body.appendChild(eleLink)
eleLink.click()
// 然后移除
document.body.removeChild(eleLink)
} else {
this.$message.warning('暂无可导出数据')
}
}