no message
This commit is contained in:
		
							parent
							
								
									e0a2d6e0dd
								
							
						
					
					
						commit
						a6902abac2
					
				| @ -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" | ||||||
|  | |||||||
							
								
								
									
										97
									
								
								src/App.vue
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								src/App.vue
									
									
									
									
									
								
							| @ -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">导入/导出: </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
									
								
							
							
						
						
									
										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
	 CN32479-詹红柱
						CN32479-詹红柱