no message
This commit is contained in:
parent
e0a2d6e0dd
commit
a6902abac2
@ -24,7 +24,10 @@
|
||||
</noscript>
|
||||
<!-- 内容区域 -->
|
||||
<div id="app" style="height: 100%;">
|
||||
</div>
|
||||
|
||||
<!-- 导出内容的节点 -->
|
||||
<div id="mybookmark" style="height: 100%;display: none;opacity: 0;">
|
||||
</div>
|
||||
<!-- 渐变背景 -->
|
||||
<canvas id="canvas-complex"
|
||||
|
85
src/App.vue
85
src/App.vue
@ -4,7 +4,7 @@
|
||||
<div class="bookmark" id="bookmark">
|
||||
<div class="tool-bar">
|
||||
<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 class="search-box">
|
||||
@ -21,11 +21,21 @@
|
||||
<!-- 侧边导航栏 -->
|
||||
<div class="box-m">
|
||||
<div class="left-box">
|
||||
<div class="left-box-item">
|
||||
<div class="label" :class="activeIndex===index?'active':'inactive'" v-for="(item,index) in data" :key="index" @click="selectType(item,index)">
|
||||
<img src="./assets/svg/file.svg" />
|
||||
<div class="text-elipss"> {{item.type}} </div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 导入导出 -->
|
||||
<div class="import-tool">
|
||||
<span class="import-text">导入/导出: </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 class="right-box">
|
||||
<transition-group v-if="bookMark.length" name="staggered-fade" class="card-s" tag="ul" :css="false" @before-enter="beforeEnter" @enter="enter" @leave="leave">
|
||||
<div class="card-item list-complete-item" v-for="(card,idx) in bookMark" :key="idx" @click="navigate(card)">
|
||||
@ -69,6 +79,7 @@ import { watch } from '@vue/runtime-core'
|
||||
import Dialog from './components/Dialog.vue'
|
||||
import gsap from 'gsap'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { importBookmark, exportBookmark } from './components/utils.js'
|
||||
var rowData = []
|
||||
function getData(fn = () => {}) {
|
||||
// 数据持久化
|
||||
@ -128,9 +139,15 @@ export default {
|
||||
function add(row = {}, flag = 'add') {
|
||||
const temp = { ...row }
|
||||
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 {
|
||||
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
|
||||
}
|
||||
@ -147,10 +164,14 @@ export default {
|
||||
// 删除
|
||||
const deleteClick = (row) => {
|
||||
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++) {
|
||||
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) {
|
||||
myData[i].children.splice(cindex, 1)
|
||||
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
|
||||
@ -167,7 +188,9 @@ export default {
|
||||
navigate,
|
||||
add,
|
||||
closeViews,
|
||||
search
|
||||
search,
|
||||
importBookmark,
|
||||
exportBookmark
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -218,7 +241,7 @@ export default {
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
|
||||
position: relative;
|
||||
overflow-y: auto;
|
||||
// overflow-y: auto;
|
||||
padding: 8px 0;
|
||||
img {
|
||||
width: 20px;
|
||||
@ -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>
|
||||
|
87
src/components/utils.js
Normal file
87
src/components/utils.js
Normal 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('暂无可导出数据')
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user