更新为构建的静态文件

更改为静态文件,以便于在Cloudflare的Pages直接部署。
This commit is contained in:
caojiezi2003 2023-10-25 14:31:21 +08:00
parent 78747b86c2
commit 883a42fa3b
81 changed files with 511 additions and 19914 deletions

View File

@ -1,3 +0,0 @@
> 1%
last 2 versions
not dead

View File

@ -1,5 +0,0 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true

View File

@ -1,17 +0,0 @@
module.exports = {
root: true,
env: { node: true },
extends: [
'plugin:vue/vue3-essential',
'@vue/standard'
],
parserOptions: {
parser: 'babel-eslint'
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'space-before-function-paren': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'object-curly-spacing': process.env.NODE_ENV === 'production' ? 'warn' : 'off'
}
}

1
.gitattributes vendored
View File

@ -1 +0,0 @@
*.js linguist-language=vue

21
.gitignore vendored
View File

@ -1,21 +0,0 @@
.DS_Store
node_modules
sitespeed-result
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

BIN
1.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

BIN
2.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1017 KiB

BIN
3.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 MiB

BIN
4.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

BIN
5.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 959 KiB

601
README.md
View File

@ -1,36 +1,8 @@
# Part1用Vue3.0 开发一款导入浏览器书签的在线书签 # 一款基于导入浏览器书签的在线书签
## 🤵介绍(取名)
👉👉👉【红隼书签】是一款简洁的在线书签导航网站。 名字的由来其实是,本着保护动物,爱护动物的初心,想到起一个鸟类的名称,其实最开始想了很多名字,小詹书签,麻雀书签等。
![红隼-kestrel](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ace153ff51d04a4da78f3616c08c58c0~tplv-k3u1fbpfcp-zoom-1.image)
但是听起来都不够响亮。后来想了一个食肉的有点凶猛的又有点呆萌的鸟类的名字红隼【英文翻译kestrel】点个赞。于是就有了这个名字啦但是听起来也是不错的。于是开发计划开始啦。
## 😀数据来源([印象中文](https://docschina.org/)
他的默认数据为我选的是[印象中文](https://docschina.org/)的web导航数据其实我自己哪里收藏了更多的导航数据但是很多设计到公司的一些访问网站。想想还是算了于是就用了印象中文的数据。它可以修改数据全局搜索筛选功能单页面完成逻辑非常简单新手小白也能完成二次修改开发采用granim插件完成背景动画可选择更多动画效果炫酷光晕背景动画效果。
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9b029e2bd28d4875b6f6bc472d1909f8~tplv-k3u1fbpfcp-zoom-1.image)
## 介绍
👉👉👉基于 [kestrel-bookmark](https://github.com/zhanhongzhu/kestrel-bookmark) 项目构建的静态文件,是一款简洁的在线书签导航网站。 本人想部署在Cloudflare的pages上但是Cloudflare部署一直报Vue依赖被弃用于是索性直接放上已构建好的静态文件。
## 💹 功能/特色 ## 💹 功能/特色
@ -61,31 +33,21 @@
## 📝 正在开发的功能 ## 📝 正在开发的功能
-   👉自定义工具栏 - 请移步原作者Github项目页[kestrel-bookmark](https://github.com/kestrela/kestrel-bookmark)查看。
-   👉书签支持多种布局样式(卡片,列表,树形书签结构等)
-   👉支持修改整个书签的图标;目前使用的是红点图标,也挺好看的;
-   👉自定义配色方案
-   👉增加中国风和热门游戏配色效果
-   👉其他功能
## 😀自定义导入数据 ## 😀自定义导入数据
可以将浏览器的书签导出,然后导入到书签系统中。也可以将书签系统的数据导入到浏览器中。 - 可以将浏览器的书签导出,然后导入到书签系统中。也可以将书签系统的数据导入到浏览器中。
## 😀leancloud存储 ## 😀leancloud存储
数据到云端。只需注册登录即可,后续无需担心数据丢失问题。 - 数据到云端。只需注册登录即可,后续无需担心数据丢失问题。
@ -93,56 +55,17 @@
## ⚡主题 ## ⚡主题
目前提供 清晰/暗黑两种主题。后续还会增加更多的主题效果。 - 目前提供 清晰/暗黑两种主题。
##### 👉暗黑
![2.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3e6abc93bd354debbe1170d0a7e3589f~tplv-k3u1fbpfcp-watermark.image?)
![3.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1fc634e98080478eb0e06046a672b8ff~tplv-k3u1fbpfcp-watermark.image?)
##### 👉清新明亮
![1.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/e39468cc70a94af082c3041d08304548~tplv-k3u1fbpfcp-watermark.image?)
![4.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/961152c473c443488e28c5e4d8827492~tplv-k3u1fbpfcp-watermark.image?)
![5.png](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ec9ac63684f643c7b8b2a3a8c9a7d62b~tplv-k3u1fbpfcp-watermark.image?)
## 💌 网址书签
========⚡⚡⚡ [红隼书签](http://bookmark.zhanhongzhu.top/) **注意:👉本项目会持续新增功能,但持续维护。如使用中发现问题,请留言或者提交 issue 。谢谢!!!**
## 📚安装步骤 ## 📚安装步骤
- 这是已打包的静态文件直接下载丢到服务器上就OK了。
- 如果需要自行修改可以直接改静态文件也可以clone原项目源码自行修改再打包。
-   1.克隆项目 https://gitee.com/zhanhongzhu/kestrel-bookmark.git
-   2.进入项目目录 `npm install`
-   3.启动项目`npm run serve`
-   4.打开浏览器即可 localhost:8080 就可以看到界面啦;
-   5.打包命令 `npm run build`
## 🚀 效果 ## 🚀 效果
@ -154,506 +77,16 @@
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52b83ea3177f420bb289a94e66bdb3dd~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3e0df0adde3f4848a4fe3060ea03efc6~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db6a1a9ab3134001a81beea4b885f59e~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/663750e8531d4b77a186519f0bfa5bba~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a7ee5b5dd4b045dbab8cfeb787aa3834~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eee207a04c234bbb838946eedfd00d6e~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b0b67d480b5c4e43b5646cdc8dbc040a~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eeef8b79fa28404c9021052945fae4f3~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef3c0e9215614a9389e1e6d4e1350dbe~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/52b83ea3177f420bb289a94e66bdb3dd~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3e0df0adde3f4848a4fe3060ea03efc6~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/db6a1a9ab3134001a81beea4b885f59e~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/663750e8531d4b77a186519f0bfa5bba~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/a7ee5b5dd4b045dbab8cfeb787aa3834~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eee207a04c234bbb838946eedfd00d6e~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b0b67d480b5c4e43b5646cdc8dbc040a~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/eeef8b79fa28404c9021052945fae4f3~tplv-k3u1fbpfcp-zoom-1.image) ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ef3c0e9215614a9389e1e6d4e1350dbe~tplv-k3u1fbpfcp-zoom-1.image)
## 致谢
- 原作者[zhanhongzhu](https://gitee.com/zhanhongzhu/)
- 原项目完全开源大家可以随意研究二次开发。觉得不错可以去原作者项目点个Star⭐⭐⭐
## 链接
#### 😄 源码地址 - [原作者博客](https:/zhanhongzhu.top)
- [原项目demo](http://bookmark.zhanhongzhu.top)
- [源码链接(gitee)](https://gitee.com/zhanhongzhu/kestrel-bookmark)
- [源码链接(github)](https://github.com/zhanhongzhu/kestrel-bookmark)
完全开源大家可以随意研究二次开发。当然还是十分欢迎大家点个Star⭐⭐⭐\
👉👉[源码链接(gitee)](https://gitee.com/zhanhongzhu/kestrel-bookmark)       👉👉[源码链接(github)](https://github.com/zhanhongzhu/kestrel-bookmark)
## 项目结构
```
├── src
     ├── Api      // 存放接口
     │    └──common.js  // leancloud-storage公共接口函数封装
     │    └──user.js   // leancloud-storage 登录、登出接口
     ├── assets      // 存放静态资源
     │    └──Json    // 静态数据源json数据
     │    └──svg    // 工具栏图标
     ├── components  //存放组件
     │    └──Dialog.vue  // 新增、修改书签
     │    └──Login.vue    // 登录弹窗
     ├── APP.vue
     └── main.js
```
## 💡 项目图标(后续支持修改图标)
红隼书签使用了的是[iconfont图标](https://www.iconfont.cn/),设计的小姐姐是[是半夏鸭](https://www.zcool.com.cn/u/21341407),设计的图标太棒了,在此表示感谢。ღ( ´・ᴗ・` )
很喜欢这个图标的;![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/af70cd5d5ca44552a4bcc71d0b5c0899~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/767b6c377ef3495d97b64ccd128aaaec~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6986c99ea31f414ebee6c55005437fa3~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/22c0311e20f142dda970f9ffc4912bf6~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b8060e82f4864cd79854df3ef1ce7508~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/652e0e3cdba843a99d0c22ec21896fa7~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/243477afb4b54b59bb70757502d44fcd~tplv-k3u1fbpfcp-zoom-1.image)
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/03711e54d5394d86a87b1ff59735ea5d~tplv-k3u1fbpfcp-zoom-1.image)
👨‍小姐姐的图标作品集地址[图标作品集地址](https://www.zcool.com.cn/work/ZNTI5NTIxMjg=.html)
## 😀主要功能函数--1、解析浏览器书签为JSON数据
```
export 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 = {
              type: 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 = {
                title: _item?.innerText,
                url: _item?.href
              }
            }
          }
          child && list.push(child)
        }
      }
    }
  }
  walk(root, result)
  //过滤不为 folder的书签保证书签能够识别
  const myBookmark = result.filter(v => v.folder)
  return flagBrowerList(myBookmark)
}
```
## 😀2、原生Input文件上传-隐藏input标签实现点击上传
```
 <i class="el-icon-upload2" title="导入浏览器书签" @click="importBookmark">
    <input type="file" ref="filElem" id="file">
</i>
```
```
// 导入书签
const 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
       const formDatas = JSON.stringify(walkBookmarksTree(mybookmark))
          //此处已经获取了我们上传的bookmark.html文件的内容了并且已经格式化
      })
  } else {
    ElMessage.warning('请先登录')
  }
}
```
## 😄3、接入leanCloud 实现serveless数据存储
其实这部分我已经进行了简单的函数封装,用起来是很方便的,还有很多用法可以参考[leancloud文档](https://leancloud.cn/docs/leanstorage_guide-dotnet.html),具体用法是非常详细的。
其实使用下面几个封装的函数基本就可以实现一个系统的增删改查了还是非常快速方便的。数据以JSON数据格式进行存储。
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6b0dc9ebbb4a461f9c7a0617819517a5~tplv-k3u1fbpfcp-zoom-1.image)
### 😄4.1 对象存储公共函数(传入表名和存储的数据)
```
import AV from 'leancloud-storage'
// 对象存储公共函数
export const saveObject = (className, params) => {
  return new Promise((resolve, reject) => {
    const Todo = AV.Object.extend(className)
    const user = AV.User.current()
    var todo = new Todo()
    todo.set('formDatas', params.formDatas)
    todo.set('user', user)
    todo.save().then((res) => {
      resolve(res)
    }, (error) => {
      reject(error)
    })
  })
}
```
### 😄4.2 获取对象存储的列表数据(传入表名和条件)
```
// 获取对象列表
export const getObject = (className, params) => {
  return new Promise((resolve, reject) => {
    const query = new AV.Query(className)
    // 查询多个条件
    const user = AV.User.current()
    for (const v in params) {
      if (params[v]) {
        query.equalTo(v, params[v])
      }
    }
    query.equalTo('user', user)
    query.find().then((res) => {
      resolve(res)
    }, (error) => {
      reject(error)
    })
  })
}
```
### 😄4.3 删除对象数据传入表名和数据ID
```
// 删除对象
export const deleteObject = (className, id) => {
  return new Promise((resolve, reject) => {
    const todo = AV.Object.createWithoutData(className, id)
    todo.destroy().then((res) => {
      resolve(res)
    }, (error) => {
      reject(error)
    })
  })
}
```
### 😄4.4 更新对象数据(传入表名和存的数据+ID
```
// 更新对象
export const updateObject = (className, params) => {
  return new Promise((resolve, reject) => {
    const todo = AV.Object.createWithoutData(className, params.id)
    for (var i in params) {
      todo.set(i, params[i])
    }
    todo.save().then((res) => {
      resolve(res)
    }, (error) => {
      reject(error)
    })
  })
}
```
## 😀 issue
需要什么新的需求或者设计,可以给我提[issue](https://gitee.com/zhanhongzhu/kestrel-bookmark/issues),感谢,喜欢的也可以点个赞。
## 💯 致谢
感谢 【空白i】 的打赏 【66.6】继续加油,希望可以做出更多更精致开源的作品处理。继续加油。😀 😀 😀
## 捐赠
请作者喝杯咖啡😀😀😀😀😀😀😀😀😀😀😀😀😀
<img src="https://zhanhongzhu.top/111.jpg" style="height:280px;width:180px;border-radius:12px;object-fit:contain;"/>
<img src="https://zhanhongzhu.top/222.jpg" style="height:280px;width:180px;border-radius:12px;object-fit:contain;"/>
## 😀 其他链接
-   [我的博客(收集各类大神的学习笔记及官方文档,强烈推荐)](https:/zhanhongzhu.top)
-   [红隼书签](http://bookmark.zhanhongzhu.top)
-   [掘金](https://juejin.im/user/5cc6757ce51d456e5238ca23)
-   [思否](https://segmentfault.com/u/huixiaodeyanjingzhenmei)
-   [CSDN](https://blog.csdn.net/weixin_43779957)
-   [简书](https://www.jianshu.com/u/b8d251f62b08)
-   [语雀(超过1800多篇开发文档)](https://www.yuque.com/zhanhongzhu)

View File

@ -1 +0,0 @@
module.exports = { presets: ['@vue/cli-plugin-babel/preset']}

448
css/app.css Normal file
View File

@ -0,0 +1,448 @@
.my-dialog[data-v-1232f72c] {
background: red
}
.my-dialog[data-v-1232f72c] .el-dialog__header {
border-bottom: 1px solid #eee !important
}
.my-dialog[data-v-1232f72c] .el-dialog__title {
font-size: 16px;
color: #e03b5d
}
.bg[data-v-08a9f3f2] {
z-index: -999;
position: fixed;
height: 100%;
width: 100%;
background: url(../img/bg.jpg)
}
.my-dialog[data-v-32ee5f5a] {
background: red
}
.my-dialog[data-v-32ee5f5a] .el-dialog__header {
border-bottom: 1px solid #eee !important
}
.my-dialog[data-v-32ee5f5a] .el-dialog__title {
font-size: 16px;
color: #e03b5d
}
.my-dialog[data-v-6f880459] {
background: red
}
.my-dialog[data-v-6f880459] .el-dialog__header {
border-bottom: 1px solid #eee !important
}
.my-dialog[data-v-6f880459] .el-dialog__title {
font-size: 16px;
color: #e03b5d
}
.granim-box[data-v-6f880459] {
height: 240px;
width: 100%;
border-radius: 12px;
overflow: hidden
}
.granim-box canvas[data-v-6f880459] {
height: 100%;
width: 100%;
-o-object-fit: cover;
object-fit: cover
}
.slelec[data-v-6f880459] {
height: 40px;
line-height: 40px
}
.opacity[data-v-6f880459] .el-form-item__content {
display: flex;
align-items: center
}
.opacity[data-v-6f880459] .el-form-item__content .el-input:first-child {
margin-right: 8px
}
#file[data-v-6f880459] {
height: 32px;
line-height: 16px
}
input[type=text][data-v-6f880459] {
color: red
}
#app[data-v-58ce68a6] {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
overflow: hidden
}
.bookmark[data-v-58ce68a6] {
position: relative;
margin-top: 8vh;
width: 1200px;
height: 75vh;
border: 1px solid hsla(0, 0%, 100%, .18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, .2);
border-radius: 6px;
background: var(--35139428);
opacity: var(--1e5ee377)
}
.bookmark .left-box[data-v-58ce68a6] {
width: 200px;
height: 100%;
border: 1px solid hsla(0, 0%, 100%, .18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, .2);
position: relative;
padding: 8px 0
}
.bookmark .left-box img[data-v-58ce68a6] {
width: 20px;
height: auto;
margin-right: 5px;
cursor: pointer
}
.bookmark .left-box .active[data-v-58ce68a6] {
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, .2);
background: var(--88b6866a)
}
.bookmark .left-box .inactive[data-v-58ce68a6] {
box-shadow: none;
background: var(--35139428)
}
.bookmark .left-box .label[data-v-58ce68a6] {
font-size: 14px;
display: flex;
cursor: pointer;
border: none;
position: relative;
padding: 10px 15px
}
.bookmark .left-box .label[data-v-58ce68a6]:hover {
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, .2);
background: var(--88b6866a)
}
.bookmark .left-box .label .text-elipss[data-v-58ce68a6] {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap
}
.bookmark .right-box[data-v-58ce68a6] {
width: calc(100% - 200px)
}
.bookmark .right-box .card-s[data-v-58ce68a6] {
width: 100%;
padding-top: 10px;
max-height: calc(80vh - 49px);
display: flex;
flex-wrap: wrap;
overflow-x: hidden;
overflow-y: auto
}
.bookmark .right-box .card-s .card-item[data-v-58ce68a6] {
cursor: pointer;
width: calc(33% - 40px);
display: flex;
justify-content: flex-start;
align-items: center;
border: 1px solid hsla(0, 0%, 100%, .18);
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, .2);
padding: 10px;
margin: 7px 20px 7px 20px;
position: relative;
border-radius: 8px;
max-height: 200px;
height: 72px !important
}
.bookmark .right-box .card-s .card-item[data-v-58ce68a6]:hover {
transform: scale(1.04);
animation-delay: .3ms;
animation: .3ms;
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, .3);
background: var(--88b6866a)
}
.bookmark .right-box .card-s .card-item:hover .logo-box-tools[data-v-58ce68a6] {
opacity: .85
}
.tool-icon[data-v-58ce68a6] {
width: 20px;
height: 20px;
-o-object-fit: contain;
object-fit: contain;
display: inline-block;
margin-right: 12px;
cursor: pointer
}
.tool-icon[data-v-58ce68a6]:hover {
fill: "#3eaf7c"
}
.tool-bar[data-v-58ce68a6] {
height: 48px;
border-bottom: 1px solid var(--26f10f65);
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background: var(--35139428)
}
.tool-bar .tool-logo[data-v-58ce68a6] {
margin: 0 15px
}
.tool-bar .tool-logo a[data-v-58ce68a6] {
color: #e03b5d;
display: flex;
align-items: center
}
.tool-bar .search-box[data-v-58ce68a6] {
display: inline-block;
position: relative;
margin-right: 1rem;
white-space: nowrap
}
.tool-bar .search-box img[data-v-58ce68a6] {
position: absolute;
top: 0;
bottom: 0;
z-index: 0;
left: .6rem;
margin: auto;
width: 20px;
height: auto
}
.tool-bar .search-box input[data-v-58ce68a6] {
text-align: initial;
text-indent: 0;
text-shadow: none;
text-transform: none;
word-spacing: normal;
letter-spacing: normal;
cursor: text;
width: 14rem;
height: 2rem;
color: #4e6e8e;
display: inline-block;
border: 1px solid var(--26f10f65);
border-radius: .25rem;
font-size: .9rem;
line-height: 2rem;
padding: 0 .5rem 0 2rem;
outline: none;
transition: all .2s ease;
background: transparent;
background-size: auto;
background-size: 1rem
}
[data-v-58ce68a6]::-webkit-scrollbar-thumb {
background-color: var(--5c838562);
background-clip: padding-box;
min-height: 28px;
border-radius: 10px
}
.box-m[data-v-58ce68a6] {
display: flex;
height: calc(100% - 50px)
}
.logo-img[data-v-58ce68a6] {
width: 62px;
height: 100%;
margin-right: 10px;
filter: drop-shadow(0 0 1px #888)
}
.logo-img img[data-v-58ce68a6] {
height: 100%;
width: 100%;
-o-object-fit: contain;
object-fit: contain;
display: block;
max-width: 70px;
width: 62px
}
.logo-box[data-v-58ce68a6] {
position: relative;
flex: 1
}
.logo-box .title[data-v-58ce68a6] {
max-width: 145px;
padding-top: 3px;
font-size: 16px;
font-weight: 700
}
.logo-box .subtitle[data-v-58ce68a6],
.logo-box .title[data-v-58ce68a6] {
width: 100%;
color: var(--1082daf8);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block
}
.logo-box .subtitle[data-v-58ce68a6] {
position: relative;
max-width: 185px;
margin-top: 5px;
font-size: 13px;
opacity: .8
}
.list-complete-item[data-v-58ce68a6] {
transition: all .8s ease;
display: inline-block;
margin-right: 10px
}
.list-complete-enter-from[data-v-58ce68a6],
.list-complete-leave-to[data-v-58ce68a6] {
opacity: 0;
transform: translateY(30px)
}
.list-complete-leave-active[data-v-58ce68a6] {
position: absolute
}
.card-item-nodata[data-v-58ce68a6] {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center
}
.card-item-nodata span[data-v-58ce68a6] {
display: block;
margin-top: 20px;
color: #999
}
.logo-box-tools[data-v-58ce68a6] {
position: absolute;
right: 0;
top: 0;
opacity: 0;
transition: opacity .4s
}
.logo-box-tools i[data-v-58ce68a6] {
padding: 4px;
display: inline-block
}
.logo-box-tools i[data-v-58ce68a6]:hover {
color: #e03b5d;
background: rgba(255, 0, 0, .12156862745098039);
border-radius: 5px
}
.import-tool[data-v-58ce68a6] {
position: absolute;
width: 100%;
background: var(--35139428);
height: 36px;
padding: 3px 10px;
display: flex;
align-items: center;
bottom: 0;
z-index: 99;
border-top: 1px solid var(--26f10f65)
}
.import-tool i[data-v-58ce68a6] {
font-size: 15px;
margin: 1px 2px;
padding: 3px;
cursor: pointer;
color: #e03b5d;
background: rgba(255, 0, 0, .12156862745098039);
border-radius: 5px;
opacity: .7
}
.import-tool i[data-v-58ce68a6]:hover {
color: #e03b5d;
background: rgba(200, 4, 4, .12156862745098039);
opacity: 1
}
.left-box-item[data-v-58ce68a6] {
height: 100%;
overflow-y: auto;
padding-bottom: 40px
}
.import-text[data-v-58ce68a6] {
font-size: 12px;
color: #999;
margin-right: 3px
}
.el-icon-upload2[data-v-58ce68a6] {
position: relative
}
.el-icon-upload2 input[data-v-58ce68a6] {
width: 1.46rem;
height: 100%;
z-index: 1;
opacity: 0;
position: absolute;
cursor: pointer
}
.login-status[data-v-58ce68a6] {
display: inline-block;
font-size: 12px;
padding-right: 8px;
color: #999;
cursor: pointer
}
.login-s .tool-icon[data-v-58ce68a6] {
margin-right: 5px
}
.login-s:hover .login-status[data-v-58ce68a6] {
color: #e03b5d
}

1
css/chunk-vendors.css Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

BIN
dist/favicon.ico vendored

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1626099491673" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2195" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M560.54 553.96m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2196"></path><path d="M515.4 954A448 448 0 0 1 198.56 189.1a448 448 0 1 1 633.68 633.68A445.14 445.14 0 0 1 515.4 954z m0-844.14c-218.4 0-396 177.66-396 396s177.68 396 396 396 396-177.68 396-396-177.6-395.98-396-395.98z" fill="#231815" p-id="2197"></path><path d="M487.06 212.12m24 0l8.7 0q24 0 24 24l0 539.62q0 24-24 24l-8.7 0q-24 0-24-24l0-539.62q0-24 24-24Z" fill="#231815" p-id="2198"></path><path d="M519.74 800.76h-8.68a25.02 25.02 0 0 1-25-25V236.12a25.02 25.02 0 0 1 25-25h8.68a25.02 25.02 0 0 1 25 25v539.64a25.02 25.02 0 0 1-25 25z m-8.68-587.64a23.02 23.02 0 0 0-23 23v539.64a23.02 23.02 0 0 0 23 23h8.68a23.02 23.02 0 0 0 23-23V236.12a23.02 23.02 0 0 0-23-23z" fill="#231815" p-id="2199"></path><path d="M809.22 476.22m0 24l0 8.7q0 24-24 24l-539.62 0q-24 0-24-24l0-8.7q0-24 24-24l539.62 0q24 0 24 24Z" fill="#231815" p-id="2200"></path><path d="M785.22 534H245.58a25.02 25.02 0 0 1-25-25v-8.68a25.02 25.02 0 0 1 25-25h539.64a25.02 25.02 0 0 1 25 25v8.68a25.02 25.02 0 0 1-25 25z m-539.64-56.78a23.02 23.02 0 0 0-23 23v8.68a23.02 23.02 0 0 0 23 23h539.64a23.02 23.02 0 0 0 23-23v-8.68a23.02 23.02 0 0 0-23-23z" fill="#231815" p-id="2201"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141545685" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2501" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M615.98 656.9m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2502"></path><path d="M771.7 931H245.82c-76.58 0-138.9-60.44-138.9-134.72V479.36a133.16 133.16 0 0 1 46.14-100.28L416 150.28a142 142 0 0 1 185.52 0l262.94 228.8a133.16 133.16 0 0 1 46.14 100.28v316.92c0 74.28-62.32 134.72-138.9 134.72zM508.76 166.74a90 90 0 0 0-59.26 22L186.56 417.58A82.12 82.12 0 0 0 158 479.36v316.92C158 842.42 197.38 880 245.82 880h525.88c48.44 0 87.86-37.54 87.86-83.68V479.36a82.12 82.12 0 0 0-28.6-61.78L568 188.78a90.12 90.12 0 0 0-59.24-22.04z" fill="#231815" p-id="2503"></path><path d="M362.78 734.16m28.34 0l241.76 0q28.34 0 28.34 28.34l0 3.1q0 28.34-28.34 28.34l-241.76 0q-28.34 0-28.34-28.34l0-3.1q0-28.34 28.34-28.34Z" fill="#231815" p-id="2504"></path><path d="M632.88 794.92H391.12a29.38 29.38 0 0 1-29.34-29.34v-3.08a29.38 29.38 0 0 1 29.34-29.34h241.76a29.38 29.38 0 0 1 29.34 29.34v3.08a29.38 29.38 0 0 1-29.34 29.34z m-241.76-59.76a27.36 27.36 0 0 0-27.34 27.34v3.08a27.36 27.36 0 0 0 27.34 27.34h241.76a27.36 27.36 0 0 0 27.34-27.34v-3.08a27.36 27.36 0 0 0-27.34-27.34z" fill="#231815" p-id="2505"></path></svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624769226567" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1298" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M698.0096 632.064m-212.7872 0a212.7872 212.7872 0 1 0 425.5744 0 212.7872 212.7872 0 1 0-425.5744 0Z" fill="#FF8080" p-id="1299"></path><path d="M771.9936 870.4H255.3856c-82.6368 0-149.8624-67.2256-149.8624-149.8624V317.7472c0-82.6368 67.2256-149.9136 149.8624-149.9136h92.3136c29.2864 0 57.8048 10.3424 80.2816 29.184l88.5248 74.1888c4.1472 3.4816 9.472 5.4272 14.8992 5.4272h240.5376c82.6368 0 149.8624 67.2256 149.8624 149.9136v294.0416c0.0512 82.5856-67.1744 149.8112-149.8112 149.8112zM255.3856 219.0336c-54.4256 0-98.6624 44.288-98.6624 98.7136v402.7904c0 54.4256 44.288 98.6624 98.6624 98.6624h516.608c54.4256 0 98.6624-44.288 98.6624-98.6624V426.496c0-54.4256-44.288-98.7136-98.6624-98.7136H531.456c-17.4592 0-34.4064-6.1952-47.7696-17.3568L395.0592 236.288a73.94816 73.94816 0 0 0-47.36-17.2544H255.3856z" fill="#512C56" p-id="1300"></path><path d="M629.6064 550.7072h-90.368V460.3392c0-14.1312-11.4688-25.6-25.6-25.6s-25.6 11.4688-25.6 25.6v90.368H397.7216c-14.1312 0-25.6 11.4688-25.6 25.6s11.4688 25.6 25.6 25.6h90.368v90.368c0 14.1312 11.4688 25.6 25.6 25.6s25.6-11.4688 25.6-25.6v-90.368h90.368c14.1312 0 25.6-11.4688 25.6-25.6s-11.4688-25.6-25.6512-25.6z" fill="#512C56" p-id="1301"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624778788435" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10366" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M604.22 630.62m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="10367"></path><path d="M323.1 430.26a48.72 48.72 0 0 1-48.7-48.68V119.04a26 26 0 0 1 52 0v254.82l53.28-50.4a48.74 48.74 0 0 1 68.8 1.88l1.06 1.2L486 370.1V119.04a26 26 0 1 1 52 0v260.28a48.68 48.68 0 0 1-84 33.46l-1.06-1.18-40.1-48-56.28 53.24a48.58 48.58 0 0 1-33.46 13.42z" fill="#231815" p-id="10368"></path><path d="M788.64 962H265.28a140.84 140.84 0 0 1-140.68-140.74V232.44a140.84 140.84 0 0 1 140.68-140.7h523.36a140.86 140.86 0 0 1 140.7 140.7v588.82A140.86 140.86 0 0 1 788.64 962zM265.28 146.36a86.16 86.16 0 0 0-86 86v588.9a86.16 86.16 0 0 0 86 86h523.36a86.18 86.18 0 0 0 86-86V232.44a86.18 86.18 0 0 0-86-86z" fill="#231815" p-id="10369"></path></svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624771399713" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2852" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M446.112 177.545c137.568 0.22 252.613 104.598 266.163 241.493 13.563 136.896-78.778 261.819-213.618 289.009-134.853 27.203-268.386-52.157-308.945-183.609s25.018-272.252 151.738-325.78a267.236 267.236 0 0 1 104.662-21.113m0-62.06c-182.794 0-330.99 148.195-330.99 330.99s148.196 330.99 330.99 330.99 330.99-148.196 330.99-330.99-148.195-330.99-330.99-330.99z m431.322 793.34a30.85 30.85 0 0 1-21.941-9.101l-157.22-157.22c-11.753-12.18-11.585-31.535 0.374-43.508 11.973-11.972 31.328-12.14 43.494-0.375l157.22 157.22a31.037 31.037 0 0 1 6.724 33.81 31.004 31.004 0 0 1-28.651 19.175z m0 0" p-id="2853"></path></svg>

Before

Width:  |  Height:  |  Size: 989 B

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141560343" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2813" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M424.42 531.9m-303.48 0a303.48 303.48 0 1 0 606.96 0 303.48 303.48 0 1 0-606.96 0Z" fill="#E03B5D" p-id="2814"></path><path d="M468.1 886c-225.52 0-408.98-183.5-408.98-409.02S242.58 68 468.1 68s408.98 183.46 408.98 408.98S693.62 886 468.1 886z m0-766c-196.84 0-356.98 160.14-356.98 356.98S271.26 834 468.1 834s356.98-160.14 356.98-356.98S664.94 120 468.1 120z" fill="#231815" p-id="2815"></path><path d="M217.36 636.7A26 26 0 0 1 194 622.14a311.58 311.58 0 0 1 142.44-416.98 26 26 0 1 1 22.9 46.68c-128.48 63.06-181.72 218.9-118.66 347.4a26 26 0 0 1-23.32 37.46z" fill="#231815" p-id="2816"></path><path d="M703.718732 766.595201m20.039406-20.039406l0.014142-0.014142q20.039406-20.039406 40.078812 0l150.104628 150.104627q20.039406 20.039406 0 40.078813l-0.014142 0.014142q-20.039406 20.039406-40.078813 0l-150.104627-150.104628q-20.039406-20.039406 0-40.078812Z" fill="#231815" p-id="2817"></path><path d="M894 946a29.22 29.22 0 0 1-20.74-8.58l-150.1-150.1a29.34 29.34 0 0 1 41.5-41.5l150 150.18a29.38 29.38 0 0 1 0 41.5A29.26 29.26 0 0 1 894 946z m-150.2-206.72a27.36 27.36 0 0 0-19.32 46.72l150 150a27.34 27.34 0 1 0 38.68-38.66l-150.1-150.1a27.14 27.14 0 0 0-19.26-7.96z" fill="#231815" p-id="2818"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141521003" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2190" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M626.44 662.52m-244.78 0a244.78 244.78 0 1 0 489.56 0 244.78 244.78 0 1 0-489.56 0Z" fill="#E03B5D" p-id="2191"></path><path d="M791.86 919.74H239.1a139.54 139.54 0 0 1-139.38-139.4v-64.52a139.54 139.54 0 0 1 139.38-139.38h552.76a139.54 139.54 0 0 1 139.38 139.38v64.52a139.54 139.54 0 0 1-139.38 139.4zM239.1 628.44a87.48 87.48 0 0 0-87.38 87.38v64.52a87.48 87.48 0 0 0 87.38 87.4h552.76a87.48 87.48 0 0 0 87.38-87.4v-64.52a87.48 87.48 0 0 0-87.38-87.38z" fill="#231815" p-id="2192"></path><path d="M515.48 628.88c-153.48 0-278.44-124.88-278.44-278.44S362 72 515.48 72 794 196.92 794 350.44s-125 278.44-278.52 278.44z m0-504.86A226.44 226.44 0 1 0 742 350.44 226.68 226.68 0 0 0 515.48 124z" fill="#231815" p-id="2193"></path><path d="M339.06 376.44a26 26 0 0 1-26-26A199.18 199.18 0 0 1 512 151.5a26 26 0 0 1 0 52 147.12 147.12 0 0 0-146.94 146.94 26 26 0 0 1-26 26z" fill="#231815" p-id="2194"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

1
dist/index.html vendored
View File

@ -1 +0,0 @@
<!DOCTYPE html><html lang="en" style="height: 100%;"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><link href="./static/css/bootstrap.css" rel="stylesheet"><link href="./static/css/style.css" rel="stylesheet"><link href="./static/css/index.css" rel="stylesheet"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0"><meta name="keywords" content="红隼书签, docschina, JavaScript, webpack, Node.js, Vue, React, Babel, Parcel, Rollup, RxJS, ECMAScript, Koa, Preact, PostCSS, 开源翻译, 开源技术文档, 中文文档, Web 前端中文文档, webpack 中文文档, doc.webpack-china.org, Node.js 中文文档, nodejs.cn, Vue.js 中文文档, vuefe.cn, React 中文文档, doc.react-china.org, Babel 中文文档, babeljs.cn, Parcel 中文文档, parceljs.io, Rollup 中文文档, rollupjs.cn, RxJS 中文文档, ECMAScript 中文文档, Koa 中文文档, koajs.cn, Preact 中文文档, Polymer, TypeScript, Element UI, iView UI, Vuetify, San, Lavas, Mint UI, Ant Design, ThinkJS, egg, Express, ESLint, 前端周刊, JavaScript Weekly, Node Weekly, Vue News, CSS Weekly, react status, Frontend Focus, Mobile Dev Weekly, Bitcoin Weekly, Golang Weekly"><meta name="description" content="红隼书签,深入挖掘国外前端新领域,为中国 Web 前端开发人员提供优质文档!!"><meta name="author" content="leehey, lizhihua, liqichang"><title>红隼书签-为中国 Web 前端开发人员提供优质网站导航</title><link href="css/app.82d112bb.css" rel="preload" as="style"><link href="css/chunk-vendors.4cb5fce1.css" rel="preload" as="style"><link href="js/app.bdf5fee8.js" rel="preload" as="script"><link href="js/chunk-vendors.486d881b.js" rel="preload" as="script"><link href="css/chunk-vendors.4cb5fce1.css" rel="stylesheet"><link href="css/app.82d112bb.css" rel="stylesheet"></head><body style="height:100%;margin: 0;"><noscript><strong>We're sorry but luotian-dev doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app" style="height: 100%;"></div><div id="mybookmark" style="height: 100%;display: none;opacity: 0;"></div><canvas id="canvas-complex" style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.95;"></canvas><div class="demo-2"><div class="content"><div id="large-header" class="large-header"><canvas id="demo-canvas"></canvas></div></div></div><script src="./static/js/granim.min.js"></script><script src="./static/js/bg.js"></script><script src="js/chunk-vendors.486d881b.js"></script><script src="js/app.bdf5fee8.js"></script></body></html>

File diff suppressed because one or more lines are too long

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 295 KiB

After

Width:  |  Height:  |  Size: 295 KiB

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 989 B

After

Width:  |  Height:  |  Size: 989 B

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

42
index.html Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en" style="height: 100%;">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="icon" href="./favicon.ico">
<link href="./static/css/bootstrap.css" rel="stylesheet">
<link href="./static/css/style.css" rel="stylesheet">
<link href="./static/css/index.css" rel="stylesheet">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=0">
<meta name="keywords" content="web书签, 浏览器书签,">
<meta name="description" content="web书签随时随地使用浏览器书签">
<meta name="author" content="zhanhongzhuJonylee">
<title>Web书签-Jonylee的设计导航</title>
<link href="css/app.css" rel="preload" as="style">
<link href="css/chunk-vendors.css" rel="preload" as="style">
<link href="js/app.js" rel="preload" as="script">
<link href="js/chunk-vendors.js" rel="preload" as="script">
<link href="css/chunk-vendors.css" rel="stylesheet">
<link href="css/app.css" rel="stylesheet">
</head>
<body style="height:100%;margin: 0;"><noscript><strong>We're sorry but luotian-dev doesn't work properly without
JavaScript enabled. Please enable it to continue.</strong></noscript>
<div id="app" style="height: 100%;"></div>
<div id="mybookmark" style="height: 100%;display: none;opacity: 0;"></div><canvas id="canvas-complex"
style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.95;"></canvas>
<div class="demo-2">
<div class="content">
<div id="large-header" class="large-header"><canvas id="demo-canvas"></canvas></div>
</div>
</div>
<script src="./static/js/granim.min.js"></script>
<script src="./static/js/bg.js"></script>
<script src="js/chunk-vendors.js"></script>
<script src="js/app.js"></script>
</body>
</html>

2
js/app.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

View File

@ -1,37 +0,0 @@
{
"name": "luotian-dev",
"version": "0.1.10",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^0.21.0",
"core-js": "^3.6.5",
"element-plus": "^1.0.2-beta.70",
"granim": "^2.0.0",
"gsap": "^3.7.0",
"js-cookie": "^3.0.0",
"leancloud-storage": "^4.11.1",
"vue": "^3.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^7.0.0-0",
"node-sass": "^4.12.0",
"sass-loader": "^8.0.2",
"vue-loader-v16": "^16.0.0-beta.5.4",
"vue-style-loader": "^4.1.2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

View File

@ -1,47 +0,0 @@
<!DOCTYPE html>
<html lang="en" style="height: 100%;">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link href="./static/css/bootstrap.css" rel="stylesheet">
<link href="./static/css/style.css" rel="stylesheet">
<link href="./static/css/index.css" rel="stylesheet">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="keywords"
content="红隼书签, docschina, JavaScript, webpack, Node.js, Vue, React, Babel, Parcel, Rollup, RxJS, ECMAScript, Koa, Preact, PostCSS, 开源翻译, 开源技术文档, 中文文档, Web 前端中文文档, webpack 中文文档, doc.webpack-china.org, Node.js 中文文档, nodejs.cn, Vue.js 中文文档, vuefe.cn, React 中文文档, doc.react-china.org, Babel 中文文档, babeljs.cn, Parcel 中文文档, parceljs.io, Rollup 中文文档, rollupjs.cn, RxJS 中文文档, ECMAScript 中文文档, Koa 中文文档, koajs.cn, Preact 中文文档, Polymer, TypeScript, Element UI, iView UI, Vuetify, San, Lavas, Mint UI, Ant Design, ThinkJS, egg, Express, ESLint, 前端周刊, JavaScript Weekly, Node Weekly, Vue News, CSS Weekly, react status, Frontend Focus, Mobile Dev Weekly, Bitcoin Weekly, Golang Weekly">
<meta name="description" content="红隼书签,深入挖掘国外前端新领域,为中国 Web 前端开发人员提供优质文档!!">
<meta name="author" content="leehey, lizhihua, liqichang">
<title>红隼书签-为中国 Web 前端开发人员提供优质网站导航</title>
</head>
<body style="height:100%;margin: 0;">
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<!-- 内容区域 -->
<div id="app" style="height: 100%;">
</div>
<!-- 导出内容的节点 -->
<div id="mybookmark" style="height: 100%;display: none;opacity: 0;">
</div>
<!-- 渐变背景 -->
<canvas id="canvas-complex"
style="width:100vw;height:100vh;position: absolute;z-index:-99;top:0;opacity: 0.95;"></canvas>
<!-- 气泡背景 -->
<div class="demo-2">
<div class="content">
<div id="large-header" class="large-header">
<canvas id="demo-canvas"></canvas>
</div>
</div>
</div>
<!-- built files will be auto injected -->
<!-- 引入の依赖 -->
<script src="./static/js/granim.min.js"></script>
<script src="./static/js/bg.js"></script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -1,187 +0,0 @@
* {
margin: 0px;
padding: 0px;
border: none;
outline: none;
font-size: 100%;
line-height: inherit;
}
body {
font-size: 16px;
color: #585f5f;
line-height: 1.5em;
font-weight: 400;
background: #ffffff;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
font-family: 'Inter', sans-serif;
}
a {
text-decoration: none;
cursor: pointer;
color: #24a77e;
}
.theme_color {
color: #24a77e;
}
a:hover,
a:focus,
a:visited,
a:active,
button:active {
text-decoration: none;
outline: none;
}
h1,
h2,
h3,
h4,
h5,
h6 {
position: relative;
font-weight: normal;
margin: 0px 0px 15px;
background: none;
line-height: 1.25em;
font-family: 'Libre Baskerville', serif;
}
h1 {
font-size: 60px;
}
h2 {
font-size: 48px;
}
h3 {
font-size: 40px;
}
h4 {
font-size: 26px;
}
h5 {
font-size: 20px;
}
h6 {
font-size: 16px;
}
input,
select,
button {
font-family: 'Inter', sans-serif;
}
textarea {
overflow: hidden;
resize: none;
}
button {
outline: none !important;
cursor: pointer;
}
p {
font-size: 15px;
line-height: 1.7em;
font-weight: 400;
margin: 0 0 15px;
}
.text {
font-size: 15px;
line-height: 1.7em;
font-weight: 400;
margin: 0 0;
}
.clearfix::after {
display: block;
clear: both;
content: ""
}
::-webkit-input-placeholder {
color: inherit;
}
::-moz-input-placeholder {
color: inherit;
}
::-ms-input-placeholder {
color: inherit;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
}
::-webkit-scrollbar-track-piece {
border-radius: 2px;
}
::-webkit-scrollbar-thumb {
background-clip: padding-box;
min-height: 28px;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
}
.my-dialog {
border-radius: 12px !important;
}
.el-dialog__header .el-dialog__title {
color: #e03b5d;
font-size: 14px;
}
.el-dialog__header {
padding: 12px 20px !important;
border-bottom: 1px solid #eee;
}
.bookmark {
border-radius: 12px !important;
overflow: hidden;
}
.el-dialog__body {
padding: 15px 30px!important;
}
.el-dialog__headerbtn {
top: 12px !important;
}
.el-select {
width: 100%;
}
.el-form-item{
display: flex;
align-items: center;
margin-bottom: 7px!important;
min-height: 26px;
}
.el-form-item__label{
display: inline-block!important;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,84 +0,0 @@
(function () {
var width; var height; var largeHeader; var canvas; var ctx; var circles; var target; var animateHeader = true
// Main
initHeader()
addListeners()
function initHeader() {
width = window.innerWidth
height = window.innerHeight
target = { x: 0, y: height }
largeHeader = document.getElementById('large-header')
largeHeader.style.height = height + 'px'
canvas = document.getElementById('demo-canvas')
canvas.width = width
canvas.height = height
ctx = canvas.getContext('2d')
// create particles
circles = []
for (var x = 0; x < width * 0.5; x++) {
var c = new Circle()
circles.push(c)
}
animate()
}
// Event handling
function addListeners() {
window.addEventListener('scroll', scrollCheck)
window.addEventListener('resize', resize)
}
function scrollCheck() {
if (document.body.scrollTop > height) animateHeader = false
else animateHeader = true
}
function resize() {
width = window.innerWidth
height = window.innerHeight
largeHeader.style.height = height + 'px'
canvas.width = width
canvas.height = height
}
function animate() {
if (animateHeader) {
ctx.clearRect(0, 0, width, height)
for (var i in circles) {
circles[i].draw()
}
}
requestAnimationFrame(animate)
}
// Canvas manipulation
function Circle() {
var _this = this;
// constructor
(function () {
_this.pos = {}
init()
})()
function init() {
_this.pos.x = Math.random() * width
_this.pos.y = height + Math.random() * 100
_this.alpha = 0.1 + Math.random() * 0.3
_this.scale = 0.1 + Math.random() * 0.3
_this.velocity = Math.random()
}
this.draw = function () {
if (_this.alpha <= 0) {
init()
}
_this.pos.y -= _this.velocity
_this.alpha -= 0.0005
ctx.beginPath()
ctx.arc(_this.pos.x, _this.pos.y, _this.scale * 20, 0, 2.5 * Math.PI, false)
ctx.fillStyle = 'rgba(255,255,255,' + _this.alpha + ')'
ctx.fill()
}
}
})()

File diff suppressed because one or more lines are too long

View File

@ -1,60 +0,0 @@
import AV from 'leancloud-storage'
// 对象存储公共函数
export const saveObject = (className, params) => {
return new Promise((resolve, reject) => {
const Todo = AV.Object.extend(className)
const user = AV.User.current()
var todo = new Todo()
todo.set('formDatas', params.formDatas)
todo.set('user', user)
todo.save().then((res) => {
resolve(res)
}, (error) => {
reject(error)
})
})
}
// 获取对象列表
export const getObject = (className, params) => {
return new Promise((resolve, reject) => {
const query = new AV.Query(className)
// 查询多个条件
const user = AV.User.current()
for (const v in params) {
if (params[v]) {
query.equalTo(v, params[v])
}
}
query.equalTo('user', user)
query.find().then((res) => {
resolve(res)
}, (error) => {
reject(error)
})
})
}
// 删除对象
export const deleteObject = (className, id) => {
return new Promise((resolve, reject) => {
const todo = AV.Object.createWithoutData(className, id)
todo.destroy().then((res) => {
resolve(res)
}, (error) => {
reject(error)
})
})
}
// 更新对象
export const updateObject = (className, params) => {
return new Promise((resolve, reject) => {
const todo = AV.Object.createWithoutData(className, params.id)
for (var i in params) {
todo.set(i, params[i])
}
todo.save().then((res) => {
resolve(res)
}, (error) => {
reject(error)
})
})
}

View File

@ -1,64 +0,0 @@
import AV from 'leancloud-storage'
// 用户登录
const login = (username, password) => {
return new Promise((resolve, reject) => {
AV.User.logIn(username, password).then(user => {
resolve(user)
}).catch(error => {
reject(error)
})
})
}
// 用户登录
const loginEmail = (email, password) => {
return new Promise((resolve, reject) => {
AV.User.loginWithEmail(password, email).then(user => {
resolve(user)
}).catch(error => {
reject(error)
})
})
}
// 用户登出
const logout = (username, password) => {
return new Promise((resolve, reject) => {
AV.User.logOut(username, password).then(user => {
resolve(user)
})
})
}
// 用户注册
const register = (username, password) => {
return new Promise((resolve, reject) => {
const user = new AV.User()
user.setUsername(username)
user.setPassword(password)
user.signUp().then((user) => {
resolve(user)
}, (error) => {
reject(error)
})
})
}
const getInfo = (params) => {
return new Promise((resolve, reject) => {
const user = new AV.User()
user.loginWithAuthData({
openid: params.openid,
access_token: params.access_token,
expires_in: params.expires_in
}, 'weixin').then(function (user) {
resolve(user)
}).catch(function (error) {
reject(error)
})
})
}
export default {
login,
logout,
register,
loginEmail,
getInfo
}

View File

@ -1,750 +0,0 @@
<template>
<div id="app">
<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>
</div>
<div>
<div class="search-box">
<img src="./assets/svg/search.svg">
<input type="text" placeholder="请输入书签名称" v-model="searchVal" />
</div>
<img src="./assets/svg/add.svg" class="tool-icon" @click="add({},'add')" />
<a title="我的博客" href="https://zhanhongzhu.top" target="_blank"><img src="./assets/svg/blog.svg" class="tool-icon" /></a>
<a title="github" href="https://github.com" target="_blank"><img src="./assets/svg/translate.svg" class="tool-icon" /></a>
<span class="login-s" @click="loginClick"><img src="./assets/svg/user.svg" class="tool-icon" title="已登录" /><span class="login-status" :title="userInfo.username">{{userInfo.username.slice(0, 5)}}</span></span>
</div>
<!-- userInfo.objectId?LoginOut:handleUserLogin -->
</div>
<!-- 侧边导航栏 -->
<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>
<i class="el-icon-setting" title="配置项" @click="configClick"></i>
<i class="el-icon-refresh" title="重置" @click="resetClick"></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)">
<div class="logo-img"><img :src="card.logo?card.logo:'/img/logo.f38dc2e8.svg'" /></div>
<div class="logo-box">
<span class="logo-box-tools">
<i class="el-icon-edit" @click.stop="add(card,'modify')"></i>
<i class="el-icon-delete" @click.stop="deleteClick(card)"></i>
</span>
<span class="title">{{card.title || 'Kestrel-bookmark'}}</span>
<span class="subtitle">{{card.desc || "红隼书签-为中国 Web 前端开发人员提供优质网站导航"}}</span>
</div>
</div>
</transition-group>
<!-- 无数据显示 -->
<div v-if="!bookMark.length" class="card-item-nodata">
<div>
<svg width="66" height="68" viewBox="0 0 66 68" class="icon empty-icon" data-v-8739e5ce="">
<g fill="none" fill-rule="evenodd" transform="translate(4 3)" data-v-8739e5ce="">
<g fill="#F7F7F7" data-v-8739e5ce="">
<path d="M9 10h23.751v3.221H9zM9 16.494h41.083v4.026H9zM9 26.104h23.751v3.221H9zM9 42.208h23.751v3.221H9zM9 33.351h41.083v4.026H9zM9 49.455h41.083v4.026H9z" data-v-8739e5ce="">
</path>
</g>
<rect width="56" height="60" x="1.139" y="1.338" stroke="#EBEBEB" stroke-width="2" rx="6" data-v-8739e5ce=""></rect>
</g>
</svg><span class="empty-text" data-v-8739e5ce="">暂无数据</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 新增/修改弹窗 -->
<Dialog class="my-dialog" v-model="isDetailVisible" @closeViews="closeViews" :detail="detail" :selectType="activeIndex" @fresh="search" />
<!-- 登录弹窗 -->
<Login v-model="isLoginVisible" @closeViews="closeLoginViews" @setUser="setUsername" />
<!-- 配置项-背景 动画效果 -->
<Configd v-model="isConfigVisible" @closeViews="closeConfigViews" @fresh="fresh" />
<!-- 配置项-背景 -->
<Bg ref="bgRef" />
</template>
<script>
import { reactive, toRefs, watch, ref, onMounted, computed } from 'vue'
import { myData } from './assets/Json/印象笔记.js'
import Dialog from './components/Dialog.vue'
import Bg from './components/Bg.vue'
import Login from './components/Login.vue'
import Configd from './components/Configd.vue'
import gsap from 'gsap'
import { ElMessage, ElMessageBox } from 'element-plus'
import { saveObject, getObject } from './Api/common.js'
import { exportBookmark, walkBookmarksTree } from './components/utils.js'
import Cookie from 'js-cookie'
import { themeConfig } from './components/theme'
import Api from './Api/user.js'
var rowData = []
export default {
components: { Dialog, Login, Configd, Bg },
name: 'kestrel-bookmark',
setup() {
//
const flatten = (arr, result = []) => {
for (const item of arr) {
Array.isArray(item.children)
? flatten(item.children, result)
: result.push(item)
}
return result
}
const data = reactive({
activeIndex: 0,
data: [],
bookMark: [],
searchVal: '',
allData: [],
isDetailVisible: false,
isLoginVisible: false,
isConfigVisible: false,
detail: {},
userInfo: {
username: '未登录'
},
themeStyle: {},
theme: 'light'
})
/*
**数据来源
1.未登录 缓存无数据 取默认
2.未登录 缓存有数据 取缓存
3.已登录 系统无数据 取默认
4.已登录 系统有数据 取系统数据
*/
const getBookmarkList = (fn = () => {}) => {
if (Cookie.get('userInfo')) {
data.userInfo = JSON.parse(Cookie.get('userInfo'))
}
if (!data.userInfo.objectId) {
if (localStorage.getItem('BOOKMARK')) {
rowData = JSON.parse(localStorage.getItem('BOOKMARK'))
} else {
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
rowData = JSON.parse(JSON.stringify(myData))
}
data.data = rowData
data.bookMark = rowData[0].children
data.allData = flatten(rowData)
fn()
} else {
//
getObject('BOOKMARK')
.then((res) => {
if (res.length > 0) {
rowData = JSON.parse(res[0].attributes.formDatas)
} else {
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
rowData = JSON.parse(JSON.stringify(myData))
}
})
.catch(() => {
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
rowData = JSON.parse(JSON.stringify(myData))
})
.finally(() => {
fn()
data.data = rowData
data.bookMark = rowData[0].children
data.allData = flatten(rowData)
})
}
}
//
const setUsername = () => {
if (Cookie.get('userInfo')) {
data.userInfo = JSON.parse(Cookie.get('userInfo'))
} else {
data.userInfo = { username: '未登录' }
}
getBookmarkList()
}
setUsername()
//
watch(
() => data.searchVal,
() => {
data.bookMark = data.allData.filter(
(v) =>
v.title.toLowerCase().indexOf(data.searchVal.toLowerCase()) > -1
)
}
)
//
const selectType = (item, index) => {
data.bookMark = item.children
data.activeIndex = index
}
//
const navigate = (v) => window.open(v.url, '_target')
//
function add(row = {}, flag = 'add') {
const temp = { ...row }
if (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.isDetailVisible = true
}
//
const handleUserLogin = () => {
data.isLoginVisible = true
}
//
const configClick = () => {
data.isConfigVisible = true
}
const closeConfigViews = (v) => (data.isConfigVisible = v)
//
const closeViews = (v) => (data.isDetailVisible = v)
const closeLoginViews = (v) => (data.isLoginVisible = v)
//
const search = async () => {
await getBookmarkList(() => {
data.data = rowData
data.bookMark = rowData[data.activeIndex].children
})
}
//
const deleteClick = (row) => {
const myData = JSON.parse(localStorage.getItem('BOOKMARK'))
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
)
if (cindex > -1) {
myData[i].children.splice(cindex, 1)
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
ElMessage.success('删除成功')
search()
}
}
}
}
// 退
const LoginOut = () => {
ElMessageBox.confirm('确认要退出登录?', '温馨提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = { username: '', password: '' }
Api.logout(params.username, params.password).then((res) => {
Cookie.remove('userInfo')
setUsername()
})
ElMessage({
type: 'success',
message: '已退出登录'
})
})
}
// 退
const loginClick = () => {
data.userInfo.objectId ? LoginOut() : handleUserLogin()
}
//
const importBookmark = () => {
if (data.userInfo.objectId) {
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
const formDatas = JSON.stringify(walkBookmarksTree(mybookmark))
if (formDatas) {
const params = { formDatas: formDatas }
saveBookmarkList(params)
}
}
})
} else {
ElMessage.warning('请先登录')
}
}
//
const saveBookmarkList = (params) => {
saveObject('BOOKMARK', params).then((res) => {
ElMessage.success('导入成功')
getBookmarkList()
})
}
const bgRef = ref(null)
const fresh = () => {
setTheme()
bgRef.value.init()
}
//
const setTheme = () => {
const obj1 = localStorage.getItem('granimConfig')
if (obj1) {
const obj = JSON.parse(obj1)
data.theme = obj.theme
data.themeStyle = themeConfig[`${data.theme}`]
data.themeStyle.opacity0 =
obj.opacity0 && obj.opacity0 > 0.5 ? obj.opacity0 : 0.5
} else {
data.themeStyle = themeConfig.light
data.themeStyle.opacity0 = 0.8
}
}
//
const bgColor = computed(() => {
return themeConfig[`${data.theme}`].bgColor
})
//
const activeColor = computed(() => {
return themeConfig[`${data.theme}`].activeColor
})
//
const opacity0 = computed(() => {
return data.themeStyle.opacity0
})
//
const textColor = computed(() => {
return themeConfig[`${data.theme}`].textColor
})
//
const borderColor = computed(() => {
return themeConfig[`${data.theme}`].borderColor
})
//
const scrollbarColor = computed(() => {
return themeConfig[`${data.theme}`].scrollbarColor
})
onMounted(() => {
setTheme()
})
//
const resetClick = () => {
localStorage.removeItem('granimConfig')
bgRef.value.init()
}
return {
scrollbarColor,
textColor,
opacity0,
activeColor,
borderColor,
bgColor,
resetClick,
bgRef,
fresh,
deleteClick,
...toRefs(data),
selectType,
navigate,
add,
closeViews,
closeLoginViews,
search,
importBookmark,
exportBookmark,
loginClick,
setUsername,
configClick,
closeConfigViews
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0
el.style.height = 0
},
enter(el, done) {
gsap.to(el, {
opacity: 1,
height: '1.6em',
delay: el.dataset.index * 0.15,
onComplete: done
})
},
leave(el, done) {
gsap.to(el, {
opacity: 0,
height: 0,
delay: el.dataset.index * 0.15,
onComplete: done
})
}
}
}
</script>
<style scoped lang="scss">
#app {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.bookmark {
position: relative;
margin-top: 8vh;
width: 1200px;
height: calc(75vh);
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
border-radius: 6px;
background: v-bind(bgColor);
opacity: v-bind(opacity0);
.left-box {
width: 200px;
height: 100%;
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;
padding: 8px 0;
img {
width: 20px;
height: auto;
margin-right: 5px;
cursor: pointer;
}
.active {
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
background: v-bind(activeColor);
}
.inactive {
box-shadow: none;
background: v-bind(bgColor);
}
.label {
font-size: 14px;
display: flex;
cursor: pointer;
border: none;
position: relative;
padding: 10px 15px;
&:hover {
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
background: v-bind(activeColor);
}
.text-elipss {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.right-box {
width: calc(100% - 200px);
.card-s {
width: 100%;
padding-top: 10px;
max-height: calc(80vh - 49px);
// height:calc(100% - 48px);
display: flex;
flex-wrap: wrap;
overflow-x: hidden;
overflow-y: auto;
.card-item {
cursor: pointer;
width: calc(33% - 40px);
display: flex;
justify-content: flex-start;
align-items: center;
border: 1px solid rgba(255, 255, 255, 0.18);
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, 0.2);
padding: 10px;
margin: 7px 20px 7px 20px;
position: relative;
border-radius: 8px;
max-height: 200px;
height: 72px !important;
&:hover {
transform: scale(1.04);
animation-delay: 0.3ms;
animation: 0.3ms;
box-shadow: 0 8px 18px 0 rgba(31, 38, 135, 0.3);
background: v-bind(activeColor);
}
&:hover .logo-box-tools {
opacity: 0.85;
}
}
}
}
}
.tool-icon {
width: 20px;
height: 20px;
object-fit: contain;
display: inline-block;
margin-right: 12px;
cursor: pointer;
&:hover {
fill: '#3eaf7c';
}
}
.tool-bar {
height: 48px;
border-bottom: 1px solid v-bind(borderColor);
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background: v-bind(bgColor);
.tool-logo {
margin: 0 15px;
a {
color: #e03b5d;
display: flex;
align-items: center;
}
}
.search-box {
display: inline-block;
position: relative;
margin-right: 1rem;
white-space: nowrap;
img {
position: absolute;
top: 0;
bottom: 0;
z-index: 0;
left: 0.6rem;
margin: auto;
width: 20px;
height: auto;
}
input {
text-align: initial;
text-indent: initial;
text-shadow: initial;
text-transform: initial;
word-spacing: initial;
letter-spacing: initial;
cursor: text;
width: 14rem;
height: 2rem;
color: #4e6e8e;
display: inline-block;
border: 1px solid v-bind(borderColor);
border-radius: 0.25rem;
font-size: 0.9rem;
line-height: 2rem;
padding: 0 0.5rem 0 2rem;
outline: none;
transition: all 0.2s ease;
background: transparent;
background-size: auto;
background-size: 1rem;
}
}
}
::-webkit-scrollbar-thumb {
background-color: v-bind(scrollbarColor);
background-clip: padding-box;
min-height: 28px;
border-radius: 10px;
}
.box-m {
display: flex;
height: calc(100% - 50px);
}
.logo-img {
width: 62px;
height: 100%;
margin-right: 10px;
filter: drop-shadow(0px 0px 1px #888);
img {
height: 100%;
width: 100%;
object-fit: contain;
display: block;
max-width: 70px;
width: 62px;
}
}
.logo-box {
position: relative;
flex: 1;
.title {
width: 100%;
max-width: 145px;
display: block;
padding-top: 3px;
font-size: 16px;
font-weight: bold;
color: v-bind(textColor);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
}
.subtitle {
width: 100%;
position: relative;
max-width: 185px;
margin-top: 5px;
font-size: 13px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: v-bind(textColor);
opacity: 0.8;
display: block;
}
}
.list-complete-item {
transition: all 0.8s ease;
display: inline-block;
margin-right: 10px;
}
.list-complete-enter-from,
.list-complete-leave-to {
opacity: 0;
transform: translateY(30px);
}
.list-complete-leave-active {
position: absolute;
}
.card-item-nodata {
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
span {
display: block;
margin-top: 20px;
color: #999;
}
}
.logo-box-tools {
position: absolute;
right: 0;
top: 0;
opacity: 0;
transition: 0.4s opacity;
i {
padding: 4px;
display: inline-block;
&:hover {
color: #e03b5d;
background: #ff00001f;
border-radius: 5px;
}
}
}
.import-tool {
position: absolute;
width: 100%;
background: v-bind(bgColor);
height: 36px;
padding: 3px 10px;
display: flex;
align-items: center;
bottom: 0;
z-index: 99;
border-top: 1px solid v-bind(borderColor);
i {
font-size: 15px;
margin: 1px 2px;
padding: 3px;
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;
}
}
.login-status {
display: inline-block;
font-size: 12px;
padding-right: 8px;
color: #999;
cursor: pointer;
}
.login-s .tool-icon {
margin-right: 5px;
}
.login-s:hover .login-status {
color: #e03b5d;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624771417607" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3507" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M857.47 206.73c-93.05-95.92-236.62-139.6-330.63-139.6-165.6 0-289.96 57.22-380.2 174.92-26.98 35.19-45.97 78.36-54.92 124.83-30.99 161.17-7.93 295.44 68.51 399.05 120.45 163.23 328.8 189.41 341.78 190.88 1.67 0.2 3.44 0.32 5.3 0.32 10.27 0 23.09-3.46 33.45-13.3 13.15-12.49 18.71-31.01 16.52-55.02l-0.49-3.36c-15.97-78.67-13.06-134.57 8.39-161.68 19.91-25.12 58-26.32 91.6-27.35 4.58-0.16 9.02-0.28 13.28-0.49 85.65 7.26 152.5-9.68 198.82-50.41 70.85-62.33 74.71-162.69 76.8-216.84 2.51-83.13-27.99-159.88-88.21-221.95z m-29.6 392.18c-33.42 29.43-85.32 41.21-154.42 35.01l-2.15-0.18-2.16 0.1c-4.54 0.22-9.32 0.36-14.28 0.53-40.04 1.25-100.54 3.13-138.34 50.87-33.56 42.38-40.63 110.34-21.55 207.66-46.6-8.39-196.58-43.94-285.07-164.26-65.49-89.03-84.73-206.81-57.19-350.03 7.12-37.05 22.07-71.21 43.21-98.78 49.56-64.66 137.8-150.6 330.92-150.6 83.94 0 209.17 41.48 286.07 120.75 48.93 50.45 72.72 109.95 70.7 176.59-2.37 61.74-8.83 131.08-55.74 172.34z" fill="#666666" p-id="3508"></path><path d="M299.58 398.72c-31.31 0-56.69 25.38-56.69 56.69s25.38 56.7 56.69 56.7 56.7-25.38 56.7-56.7-25.39-56.69-56.7-56.69zM511.74 250.99c-31.31 0-56.7 25.38-56.7 56.69s25.38 56.7 56.7 56.7 56.69-25.38 56.69-56.7-25.38-56.69-56.69-56.69zM696.96 398.72c-31.31 0-56.7 25.38-56.7 56.69s25.38 56.7 56.7 56.7c31.31 0 56.7-25.38 56.7-56.7s-25.39-56.69-56.7-56.69z" fill="#666666" p-id="3509"></path></svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1626099545795" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2353" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M615.98 575.08m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2354"></path><path d="M285.68 779.24a48.82 48.82 0 0 1-48.56-53.44l10.18-107.4a83.08 83.08 0 0 1 23.88-50.78L668.86 170A82.94 82.94 0 0 1 786 170l60.16 60.16a82.8 82.8 0 0 1 0 117.16L448.5 744.94a83.04 83.04 0 0 1-50.76 23.9l-107.4 10.18c-1.56 0.14-3.12 0.22-4.66 0.22z m109.6-36.44zM727.44 198a30.44 30.44 0 0 0-21.6 8.92L308.16 604.6a30.64 30.64 0 0 0-8.8 18.72l-9.78 103.24 103.22-9.78a30.62 30.62 0 0 0 18.72-8.82L809.2 310.28a30.52 30.52 0 0 0 0-43.2l-60.16-60.16a30.36 30.36 0 0 0-21.6-8.92z" fill="#231815" p-id="2355"></path><path d="M207.88 824.22m28.34 0l657.66 0q28.34 0 28.34 28.34l0 0.02q0 28.34-28.34 28.34l-657.66 0q-28.34 0-28.34-28.34l0-0.02q0-28.34 28.34-28.34Z" fill="#231815" p-id="2356"></path><path d="M893.86 882H236.22a29.36 29.36 0 0 1 0-58.7h657.64a29.36 29.36 0 0 1 0 58.7z m-657.64-56.78a27.36 27.36 0 0 0 0 54.7h657.64a27.36 27.36 0 0 0 0-54.7z" fill="#231815" p-id="2357"></path></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625888775605" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="522" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M512 1024C230.4 1024 0 793.6 0 512S230.4 0 512 0s512 230.4 512 512-230.4 512-512 512z m259.2-569.6H480c-12.8 0-25.6 12.8-25.6 25.6v64c0 12.8 12.8 25.6 25.6 25.6h176c12.8 0 25.6 12.8 25.6 25.6v12.8c0 41.6-35.2 76.8-76.8 76.8h-240c-12.8 0-25.6-12.8-25.6-25.6V416c0-41.6 35.2-76.8 76.8-76.8h355.2c12.8 0 25.6-12.8 25.6-25.6v-64c0-12.8-12.8-25.6-25.6-25.6H416c-105.6 0-188.8 86.4-188.8 188.8V768c0 12.8 12.8 25.6 25.6 25.6h374.4c92.8 0 169.6-76.8 169.6-169.6v-144c0-12.8-12.8-25.6-25.6-25.6z" fill="#d81e06" p-id="523"></path></svg>

Before

Width:  |  Height:  |  Size: 904 B

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141737574" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3277" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M635.1 629.62m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="3278"></path><path d="M786 945.8H262.64a139.54 139.54 0 0 1-139.4-139.38V217.58a139.54 139.54 0 0 1 139.4-139.38H786a139.54 139.54 0 0 1 139.38 139.38v588.84A139.54 139.54 0 0 1 786 945.8zM262.64 130.2a87.48 87.48 0 0 0-87.4 87.38v588.84a87.48 87.48 0 0 0 87.4 87.38H786a87.48 87.48 0 0 0 87.38-87.38V217.58A87.48 87.48 0 0 0 786 130.2z" fill="#231815" p-id="3279"></path><path d="M279.2 278.2m28.34 0l209.96 0q28.34 0 28.34 28.34l0 0.02q0 28.34-28.34 28.34l-209.96 0q-28.34 0-28.34-28.34l0-0.02q0-28.34 28.34-28.34Z" fill="#231815" p-id="3280"></path><path d="M517.5 336h-210a29.36 29.36 0 0 1 0-58.7h210a29.36 29.36 0 0 1 0 58.7z m-210-56.7a27.36 27.36 0 0 0 0 54.7h210a27.36 27.36 0 0 0 0-54.7z" fill="#231815" p-id="3281"></path><path d="M279.2 504.3m28.34 0l410.32 0q28.34 0 28.34 28.34l0 0.02q0 28.34-28.34 28.34l-410.32 0q-28.34 0-28.34-28.34l0-0.02q0-28.34 28.34-28.34Z" fill="#231815" p-id="3282"></path><path d="M717.84 562H307.54a29.34 29.34 0 0 1 0-58.68h410.3a29.34 29.34 0 0 1 0 58.68z m-410.3-56.7a27.34 27.34 0 0 0 0 54.68h410.3a27.34 27.34 0 0 0 0-54.68z" fill="#231815" p-id="3283"></path><path d="M279.2 695.72m28.34 0l410.32 0q28.34 0 28.34 28.34l0 0.02q0 28.34-28.34 28.34l-410.32 0q-28.34 0-28.34-28.34l0-0.02q0-28.34 28.34-28.34Z" fill="#231815" p-id="3284"></path><path d="M717.84 753.4H307.54a29.36 29.36 0 0 1 0-58.7h410.3a29.36 29.36 0 0 1 0 58.7z m-410.3-56.7a27.36 27.36 0 0 0 0 54.7h410.3a27.36 27.36 0 0 0 0-54.7z" fill="#231815" p-id="3285"></path></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1624772214418" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4431" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M874.336 786.304c-56.96 78.016-130.496 131.84-220.64 161.856-10.304 1.824-18.368 0.448-22.848-4.032a22.4 22.4 0 0 1-7.2-17.504v-122.88c0-37.632-10.304-65.44-30.464-82.912a409.856 409.856 0 0 0 59.616-10.368 222.752 222.752 0 0 0 54.72-22.816c18.848-10.784 34.528-23.36 47.104-38.592 12.544-15.232 22.848-35.904 30.912-61.44 8.096-25.568 12.128-54.688 12.128-87.904 0-47.072-15.232-86.976-46.208-120.16 14.368-35.456 13.024-74.912-4.48-118.848-10.752-3.616-26.432-1.344-47.072 6.272a301.44 301.44 0 0 0-53.824 25.568l-21.984 13.888A407.776 407.776 0 0 0 512 291.2c-38.56 0-75.776 4.928-112.096 15.232a444.48 444.48 0 0 0-24.672-15.68c-10.336-6.272-26.464-13.888-48.896-22.432-21.952-8.96-39.008-11.232-50.24-8.064-17.024 43.936-18.368 83.424-4.032 118.848-30.496 33.632-46.176 73.536-46.176 120.608 0 33.216 4.032 62.336 12.128 87.456 8.032 25.12 18.368 45.76 30.496 61.44 12.544 15.68 28.224 28.704 47.072 39.04 18.848 10.304 37.216 17.92 54.72 22.816a409.6 409.6 0 0 0 59.648 10.368c-15.712 13.856-25.12 34.048-28.704 60.064a99.744 99.744 0 0 1-26.464 8.512 178.208 178.208 0 0 1-33.184 2.688c-13.024 0-25.568-4.032-38.144-12.544-12.544-8.512-23.296-20.64-32.256-36.32a97.472 97.472 0 0 0-28.256-30.496c-11.232-8.064-21.088-12.576-28.704-13.92l-11.648-1.792c-8.096 0-13.92 0.928-17.056 2.688-3.136 1.792-4.032 4.032-2.688 6.72 1.344 2.688 3.136 5.408 5.376 8.096 2.24 2.688 4.928 4.928 7.616 7.168l4.032 2.688c8.544 4.032 17.056 11.232 25.568 21.984 8.544 10.752 14.368 20.64 18.4 29.6l5.824 13.44c4.928 14.816 13.44 26.912 25.568 35.872 12.096 8.992 25.088 14.816 39.008 17.504 13.888 2.688 27.36 4.032 40.352 4.032 12.992 0 23.776-0.448 32.288-2.24l13.472-2.24c0 14.784 0 32.288 0.416 52.032 0 19.744 0.48 30.496 0.48 31.392a22.624 22.624 0 0 1-7.648 17.472c-4.928 4.48-12.992 5.824-23.296 4.032-90.144-30.048-163.68-83.84-220.64-161.888C92.256 708.256 64 620.352 64 523.04c0-81.152 20.192-156.064 60.096-224.672a445.184 445.184 0 0 1 163.232-163.232C355.936 95.232 430.816 75.04 512 75.04s156.064 20.192 224.672 60.096a445.184 445.184 0 0 1 163.232 163.232C939.808 366.528 960 441.888 960 523.04c0 97.76-28.704 185.216-85.664 263.264z" p-id="4432"></path></svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141570340" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3123" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M572.34 543.18m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="3124"></path><path d="M350.92 481.78h-65.42a139.54 139.54 0 0 1-139.4-139.38v-65.44a139.54 139.54 0 0 1 139.4-139.38h65.42a139.54 139.54 0 0 1 139.38 139.38v65.44a139.54 139.54 0 0 1-139.38 139.38z m-65.42-292.2a87.48 87.48 0 0 0-87.4 87.38v65.44a87.48 87.48 0 0 0 87.4 87.38h65.42a87.48 87.48 0 0 0 87.38-87.38v-65.44a87.48 87.48 0 0 0-87.38-87.38zM725.16 478.64h-65.44a139.54 139.54 0 0 1-139.38-139.38v-65.42a139.54 139.54 0 0 1 139.38-139.4h65.44a139.54 139.54 0 0 1 139.38 139.4v65.42a139.54 139.54 0 0 1-139.38 139.38z m-65.44-292.2a87.48 87.48 0 0 0-87.38 87.4v65.42a87.48 87.48 0 0 0 87.38 87.38h65.44a87.48 87.48 0 0 0 87.38-87.38v-65.42a87.48 87.48 0 0 0-87.38-87.4zM350.92 849.38h-65.42A139.56 139.56 0 0 1 146.1 710v-65.44a139.54 139.54 0 0 1 139.4-139.38h65.42a139.54 139.54 0 0 1 139.38 139.38V710a139.54 139.54 0 0 1-139.38 139.38z m-65.42-292.2a87.48 87.48 0 0 0-87.4 87.38V710a87.48 87.48 0 0 0 87.4 87.38h65.42A87.48 87.48 0 0 0 438.3 710v-65.44a87.48 87.48 0 0 0-87.38-87.38zM725.16 846.24h-65.44a139.54 139.54 0 0 1-139.38-139.38v-65.44A139.54 139.54 0 0 1 659.72 502h65.44a139.54 139.54 0 0 1 139.38 139.38v65.44a139.54 139.54 0 0 1-139.38 139.42zM659.72 554a87.48 87.48 0 0 0-87.38 87.38v65.44a87.48 87.48 0 0 0 87.38 87.38h65.44a87.48 87.48 0 0 0 87.38-87.38v-65.4A87.48 87.48 0 0 0 725.16 554z" fill="#231815" p-id="3125"></path></svg>

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141565378" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2968" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M624.68 588.62m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2969"></path><path d="M772.46 960.64a54.12 54.12 0 0 1-25.68-6.5l-225.84-121.2a2.3 2.3 0 0 0-2 0L291 950.24a54.22 54.22 0 0 1-78.2-57.84l45.48-252.22a2.22 2.22 0 0 0-0.62-2l-182-180.46a54.26 54.26 0 0 1 30.84-92.26l254-34.68a2.22 2.22 0 0 0 1.7-1.2l115.32-228.84A54 54 0 0 1 526 70.92h0.48a54 54 0 0 1 48.32 30.66l111.44 230.78a2.32 2.32 0 0 0 1.68 1.24l253.3 39.02a54.22 54.22 0 0 1 29.28 92.76l-185.06 177.32a2.3 2.3 0 0 0-0.66 2L826 897.64a54.32 54.32 0 0 1-53.48 63z m-252.58-180a54.38 54.38 0 0 1 25.66 6.44l225.82 121.2a2 2 0 0 0 2.36-0.14 2 2 0 0 0 0.9-2.18l-41.16-252.94a54.2 54.2 0 0 1 16-47.86l185.04-177.32a2.24 2.24 0 0 0-1.2-3.82L680 385a54.22 54.22 0 0 1-40.58-30L528 124.18a2 2 0 0 0-2-1.26 2 2 0 0 0-2 1.24L408.56 353a54.18 54.18 0 0 1-41.08 29.32l-254 34.68a2 2 0 0 0-1.82 1.52 2 2 0 0 0 0.56 2.3l182 180.44a54.28 54.28 0 0 1 15.2 48.14L264 901.62a2.24 2.24 0 0 0 3.22 2.4l227.86-117.32a54.16 54.16 0 0 1 24.8-6.02z" fill="#231815" p-id="2970"></path><path d="M310.36 493.3a26 26 0 0 1-3.48-51.78l117.82-16 44.64-88.54a26 26 0 1 1 46.42 23.4l-44.82 88.82a51.2 51.2 0 0 1-38.8 27.7L314 493.04a26.88 26.88 0 0 1-3.64 0.26z" fill="#231815" p-id="2971"></path></svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141511849" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2037" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M604.22 591.06m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2038"></path><path d="M796.9 344.84a26 26 0 0 1-26-25.64c0-1.86-0.62-45.4-0.5-60.5a13.42 13.42 0 0 0-3.86-9.68 12 12 0 0 0-8.72-3.64H546a26 26 0 0 1 0-52h211.82a63.82 63.82 0 0 1 45.64 19.02 65.04 65.04 0 0 1 18.94 46.72c-0.12 14.52 0.5 58.9 0.5 59.36a26 26 0 0 1-25.64 26.36z" fill="#231815" p-id="2039"></path><path d="M790.9 878.74H225.28c-77.46 0-140.48-67.38-140.48-150.2V312c0-82.82 63.02-150.2 140.48-150.2h225.18c45.14 0 87.78 23.38 114 62.54l34.2 50.9c16.22 24.14 42 38.56 69.1 38.56h123.04c77.46 0 140.48 67.38 140.48 150.2v264.6c0.1 82.76-62.92 150.14-140.38 150.14zM225.28 216c-47.58 0-86.28 43-86.28 96v416.6c0 52.94 38.7 96 86.28 96h565.62c47.58 0 86.3-43.08 86.3-96V464c0-52.94-38.72-96-86.3-96h-123.04c-45.12 0-87.78-23.38-114-62.52l-34.2-50.9c-16.22-24.16-42-38.58-69.12-38.58z" fill="#231815" p-id="2040"></path></svg>

Before

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141551574" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2655" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M624.12 491.04m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2656"></path><path d="M838.96 858.72a80.86 80.86 0 0 1-52.18-19.36l-73.28-61.74a26.74 26.74 0 0 0-17.34-6.58H256c-77.44 0-140.44-67.28-140.44-150V328.14c0-82.7 63-150 140.44-150h526.4c77.46 0 140.46 67.28 140.46 150v442c0 35.64-19.18 66.7-50 81.06a80 80 0 0 1-33.9 7.52zM256 232.3c-47.58 0-86.3 43-86.3 95.84v292.92c0 52.86 38.72 95.84 86.3 95.84h440.16a81.3 81.3 0 0 1 52.24 19.32L821.68 798a25.3 25.3 0 0 0 28.2 4.14c9.08-4.22 18.76-14.82 18.76-32v-442c0-52.84-38.72-95.84-86.32-95.84z" fill="#231815" p-id="2657"></path><path d="M356.02 470.06m-53.32 0a53.32 53.32 0 1 0 106.64 0 53.32 53.32 0 1 0-106.64 0Z" fill="#231815" p-id="2658"></path><path d="M356 524.38A54.32 54.32 0 1 1 410.34 470 54.38 54.38 0 0 1 356 524.38z m0-106.64A52.32 52.32 0 1 0 408.34 470 52.38 52.38 0 0 0 356 417.74z" fill="#231815" p-id="2659"></path><path d="M512 470.06m-53.32 0a53.32 53.32 0 1 0 106.64 0 53.32 53.32 0 1 0-106.64 0Z" fill="#231815" p-id="2660"></path><path d="M512 524.38A54.32 54.32 0 1 1 566.32 470 54.38 54.38 0 0 1 512 524.38z m0-106.64A52.32 52.32 0 1 0 564.32 470 52.4 52.4 0 0 0 512 417.74z" fill="#231815" p-id="2661"></path><path d="M672.46 470.06m-53.32 0a53.32 53.32 0 1 0 106.64 0 53.32 53.32 0 1 0-106.64 0Z" fill="#231815" p-id="2662"></path><path d="M672.46 524.38A54.32 54.32 0 1 1 726.78 470a54.36 54.36 0 0 1-54.32 54.38z m0-106.64A52.32 52.32 0 1 0 724.78 470a52.38 52.38 0 0 0-52.32-52.26z" fill="#231815" p-id="2663"></path></svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1 +0,0 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1625141535771" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2346" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M614.8 618.7m-300.58 0a300.58 300.58 0 1 0 601.16 0 300.58 300.58 0 1 0-601.16 0Z" fill="#E03B5D" p-id="2347"></path><path d="M679.68 943.04H367.14a143.42 143.42 0 0 1-123.86-71.5L87.02 600.86a143.32 143.32 0 0 1 0-143l156.26-270.68a143.42 143.42 0 0 1 123.86-71.5h312.54a143.42 143.42 0 0 1 123.86 71.5l156.26 270.68a143.32 143.32 0 0 1 0 143l-156.26 270.68a143.42 143.42 0 0 1-123.86 71.5z m-312.54-768a84 84 0 0 0-72.54 41.88L138.34 487.48a84 84 0 0 0 0 83.76L294.6 842a84 84 0 0 0 72.54 41.88h312.54A84 84 0 0 0 752.22 842l156.26-270.66a84 84 0 0 0 0-83.76l-156.26-270.76a84 84 0 0 0-72.54-41.88z" fill="#231815" p-id="2348"></path><path d="M539.36 703.56a174.2 174.2 0 1 1 174.18-174.2 174.38 174.38 0 0 1-174.18 174.2z m0-289.12a114.94 114.94 0 1 0 114.92 114.92 115.06 115.06 0 0 0-114.92-114.92z" fill="#231815" p-id="2349"></path></svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -1,69 +0,0 @@
<template>
<div class="bg"></div>
</template>
<script setup>
import { onMounted, defineExpose } from 'vue'
//
const defaultConfig = {
direction: 'left-right',
isPausedWhenNotInView: true,
opacity: [1, 1],
states: {
'default-state': {
gradients: [
[
{ color: '#833ab4', pos: 0.2 },
{ color: '#fd1d1d', pos: 0.8 },
{ color: '#38ef7d', pos: 1 }
],
[
{ color: '#40e0d0', pos: 0 },
{ color: '#ff8c00', pos: 0.2 },
{ color: '#ff0080', pos: 0.75 }
]
]
}
},
image: {
source: 'https://zhanhongzhu.top/bg.jpg',
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
}
}
let granimInstance = null
const init = () => {
let granimConfig = localStorage.getItem('granimConfig')
granimConfig = granimConfig ? JSON.parse(granimConfig) : defaultConfig
delete granimConfig.opacity
//
// eslint-disable-next-line no-undef, no-new
granimInstance = new Granim({
element: '#canvas-complex',
...granimConfig,
opacity: 1
})
}
defineExpose({ init })
onMounted(() => {
if (granimInstance) {
granimInstance.destroy()
}
init()
})
</script>
<style scoped lang="scss">
.bg {
position: fixed;
z-index: -999;
position: fixed;
height: 100%;
width: 100%;
background: url(../assets/bg.jpg);
}
</style>

View File

@ -1,312 +0,0 @@
<!-- /* eslint-disable */ -->
<template>
<el-dialog custom-class="my-dialog" title="配置项" :visible="isConfigVisible" width="700px">
<el-form status-icon ref="refruleForm" :rules="rules" :model="ruleForm" label-width="60px" size="small">
<el-row>
<el-col :span="24">
<el-form-item label="背景">
<input id="file" @change="handleFileChange" accept="image/*" type="file" :multiple="false">
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="主题" class="slelec">
<el-select v-model="theme" placeholder="光影" @change="setGranim">
<el-option label="清新" value="light" />
<el-option label="暗黑" value="dark" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="光影" class="slelec">
<el-select v-model="selectVal" placeholder="光影" @change="setGranim">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="亮度" class="slelec">
<el-input v-model="opacity0" placeholder="亮度" onkeyup="value=value.replace(/[^\d.]/g,0)" @change="setGranim"/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="位置">
<el-select v-model="direction" placeholder="位置" @change="setGranim">
<el-option v-for="item in directions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="效果">
<div class="granim-box">
<canvas id="granim-box"></canvas>
</div>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="透明度" class="opacity">
<el-input v-model="opacity1" placeholder="透明度参数1" onkeyup="value=value.replace(/[^\d]/g,0)" />
<el-input v-model="opacity2" placeholder="透明度参数2" onkeyup="value=value.replace(/[^\d]/g,0)" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeViews" size="small"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import Cookie from 'js-cookie'
import {
watch,
reactive,
ref,
toRefs,
onMounted,
useAttrs,
nextTick
} from 'vue'
import { ElMessage } from 'element-plus'
import Api from '../Api/user.js' // register
import { config } from './config.js'
export default {
model: {
value: 'isConfigVisible',
events: 'closeViews'
},
props: {
isConfigVisible: {
type: Boolean,
default: false
}
},
setup(props, context) {
const state = reactive({
ruleForm: {
username: '',
password: ''
},
options: [
{ label: '渐变-01', value: 'gradient1' },
{ label: '渐变-02', value: 'gradient2' },
{ label: '渐变-03', value: 'gradient3' },
{ label: '迷雾森林', value: 'gradient4' }
],
directions: [
{ label: '从上到下', value: 'top-bottom' },
{ label: '从左到右', value: 'left-right' },
{ label: '环形', value: 'diagonal' },
{ label: '对角线', value: 'radial' },
{ label: '自定义', value: 'custom' }
],
selectVal: 'gradient4',
direction: 'left-right',
opacity1: 0.15,
opacity2: 0.15,
imageUrl: '',
granimRef: null,
theme: 'light',
opacity0: 0.8
})
// :rules
const rules = {
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
email: [
{
type: 'email',
required: true,
message: '请输入正确的邮箱',
trigger: 'blur'
}
]
}
const refruleForm = ref(null)
//
const submitForm = () => {
refruleForm.value.validate((valid) => {
if (valid) {
const formData = { ...state.ruleForm }
Api.login(formData.email, formData.password)
.then((res) => {
Cookie.set('userInfo', JSON.stringify(res))
context.emit('setUser')
ElMessage.success('登录成功')
closeViews()
})
.catch((err) => {
if (err.code === 210) {
ElMessage.error('账号或密码不正确')
} else if (err.code === 211) {
Api.register(formData.email, formData.password).then((res) => {
Cookie.set('userInfo', JSON.stringify(res))
context.emit('setUser')
ElMessage.success('注册成功')
closeViews()
})
}
})
}
})
}
//
function closeViews() {
refruleForm.value.resetFields()
context.emit('closeViews', false)
}
const setGranim = () => {
state.opacity1 = state.opacity1 || 1
state.opacity2 = state.opacity2 || 1
const obj = config[`${state.selectVal}`]
//
const granimConfig = {
...obj,
opacity1: state.opacity1,
opacity2: state.opacity2,
opacity0: state.opacity0,
selectVal: state.selectVal,
theme: state.theme,
opacity: [state.opacity1, state.opacity2],
direction: state.direction,
image: {
source: state.imageUrl,
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
}
}
//
localStorage.setItem('granimConfig', JSON.stringify(granimConfig))
// eslint-disable-next-line no-undef, no-new
state.granimRef = new Granim({
element: '#granim-box',
...granimConfig
})
context.emit('fresh')
}
// base64
function changeFileIntoBase64(file) {
return new Promise((resolve) => {
const fr = new FileReader()
/* eslint-disable */
fr.readAsDataURL(file)
fr.onload = (result) => {
const base64Str = result.currentTarget.result
resolve(base64Str)
}
})
}
const handleFileChange = (e) => {
const file = e.target.files[0]
changeFileIntoBase64(file)
.then((res) => {
state.imageUrl = res
})
.finally(() => {
setGranim()
})
}
const attrs = useAttrs()
onMounted(() => {
let granimConfig = localStorage.getItem('granimConfig')
if (granimConfig) {
let obj = JSON.parse(granimConfig)
state.selectVal = obj.selectVal
state.direction = obj.direction
state.opacity1 =
obj.opacity && obj.opacity.length > 0 ? obj.opacity[0] : 0.15 //
state.opacity2 =
obj.opacity && obj.opacity.length > 0 ? obj.opacity[1] : 0.15
state.imageUrl = obj.image && obj.image.source ? obj.image.source : ''
state.theme = obj.theme
state.opacity0 = obj.opacity0
}
state.granimRef = null
})
watch(
() => attrs.modelValue,
(v) => {
if (v) {
nextTick(() => {
if (state.granimRef) {
state.granimRef.destroy()
}
setGranim()
})
}
},
{
deep: true,
}
)
return {
...toRefs(state),
closeViews,
submitForm,
refruleForm,
rules,
setGranim,
handleFileChange,
}
},
}
</script>
<style scoped lang="scss">
.my-dialog {
background: red;
}
.my-dialog /deep/.el-dialog__header {
border-bottom: 1px solid #eee !important;
}
.my-dialog /deep/.el-dialog__title {
font-size: 16px;
color: #e03b5d;
}
.granim-box {
height: 240px;
width: 100%;
border-radius: 12px;
overflow: hidden;
canvas {
height: 100%;
width: 100%;
object-fit: cover;
}
}
.slelec {
height: 40px;
line-height: 40px;
// :deep(.el-form-item__label) {
// }
}
.opacity {
:deep(.el-form-item__content) {
display: flex;
align-items: center;
.el-input {
&:first-child {
margin-right: 8px;
}
}
}
}
#file {
height: 32px;
line-height: 16px;
}
input[type='text'] {
color: red;
}
</style>

View File

@ -1,168 +0,0 @@
<template>
<el-dialog custom-class="my-dialog" title="新增书签" :visible="isDetailVisible" width="758px">
<el-form status-icon ref="refruleForm" :rules="rules" :model="ruleForm" label-width="100px" size="small">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="书签名称" prop="title">
<el-input v-model="ruleForm.title" placeholder="请输入书签名称"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="书签类别" prop="type">
<el-select v-model="ruleForm.type" placeholder="请选择书签类别" style="width:100%">
<el-option v-for="(item,index) in BOOKMARK" :value="item" :key="index"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="LOGO地址" prop="logo">
<el-input v-model="ruleForm.logo" placeholder="请输入LOGO地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="访问地址" prop="url">
<el-input v-model="ruleForm.url" placeholder="请输入访问绝对地址"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="书签描述" prop="desc">
<el-input type="textarea" clearable placeholder="请输入书签描述" v-model="ruleForm.desc" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeViews" size="small"> </el-button>
<el-button type="primary" @click="submitForm" size="small"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import { reactive, ref, toRefs, nextTick, watch } from 'vue'
import { ElMessage } from 'element-plus'
export default {
model: {
value: 'isDetailVisible',
events: 'closeViews'
},
props: {
isDetailVisible: {
type: Boolean,
default: false
},
selectType: {
type: Number,
default: 0
},
detail: {
type: Object,
default: () => {}
}
},
setup(props, context) {
const isBOOKMARK = JSON.parse(localStorage.getItem('BOOKMARK'))
const BOOKMARK = isBOOKMARK ? isBOOKMARK.map((v) => v.type) : []
const form = reactive({
ruleForm: {
title: '',
type: '',
desc: '',
url: '',
logo: ''
}
})
// :rules
const rules = {
title: [{ required: true, message: '请输入书签名称', trigger: 'blur' }],
type: [{ required: true, message: '请选择书签类别', trigger: 'change' }]
}
const refruleForm = ref(null)
//
const submitForm = () => {
refruleForm.value.validate((valid) => {
if (valid) {
const myData = isBOOKMARK.map((v) => {
const myDetail = { ...props.detail }
const formData = { ...form.ruleForm }
if (props.detail.flag === 'modify') {
//
if (myDetail.type === formData.type && v.type === formData.type) {
const sIndex = v.children.findIndex(
(d) => d.title === myDetail.title
)
if (sIndex > -1) {
v.children[sIndex] = formData
ElMessage.success('编辑成功')
}
} else if (myDetail.type !== formData.type) {
//
//
if (myDetail.type === v.type) {
const pindex = v.children.findIndex(
(p) => p.title === myDetail.title
)
v.children.splice(pindex, 1)
}
//
if (formData.type === v.type) {
v.children.push(formData)
ElMessage.success('编辑成功')
}
}
} else {
//
if (v.type === formData.type) {
v.children.push(formData)
ElMessage.success('新增成功')
}
}
return v
})
localStorage.setItem('BOOKMARK', JSON.stringify(myData))
context.emit('fresh')
closeViews()
}
})
}
//
function closeViews() {
refruleForm.value.resetFields()
context.emit('closeViews', false)
}
//
watch(
() => props.detail,
(v) => {
if (v) {
nextTick(() => {
form.ruleForm = { ...props.detail }
})
}
},
{ deep: true }
)
return {
...toRefs(form),
closeViews,
submitForm,
refruleForm,
rules,
BOOKMARK
}
}
}
</script>
<style scoped lang="scss">
.my-dialog {
background: red;
}
.my-dialog /deep/.el-dialog__header {
border-bottom: 1px solid #eee !important;
}
.my-dialog /deep/.el-dialog__title {
font-size: 16px;
color: #e03b5d;
}
</style>

View File

@ -1,115 +0,0 @@
<template>
<el-dialog custom-class="my-dialog" title="用户登录" :visible="isLoginVisible" width="400px">
<el-form status-icon ref="refruleForm" :rules="rules" :model="ruleForm" label-width="60px" size="small">
<el-row>
<el-col :span="24">
<el-form-item label="邮箱" prop="email">
<el-input v-model="ruleForm.email" placeholder="请输入邮箱"></el-input>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="密码" prop="password">
<el-input v-model="ruleForm.password" show-password placeholder="请输入密码"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="closeViews" size="small"> </el-button>
<el-button type="primary" @click="submitForm" size="small"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import Cookie from 'js-cookie'
import { reactive, ref, toRefs } from 'vue'
import { ElMessage } from 'element-plus'
import Api from '../Api/user.js' // register
export default {
model: {
value: 'isLoginVisible',
events: 'closeViews'
},
props: {
isLoginVisible: {
type: Boolean,
default: false
}
},
setup(props, context) {
const form = reactive({
ruleForm: {
username: '',
password: ''
}
})
// :rules
const rules = {
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
email: [
{
type: 'email',
required: true,
message: '请输入正确的邮箱',
trigger: 'blur'
}
]
}
const refruleForm = ref(null)
//
const submitForm = () => {
refruleForm.value.validate((valid) => {
if (valid) {
const formData = { ...form.ruleForm }
Api.login(formData.email, formData.password)
.then((res) => {
Cookie.set('userInfo', JSON.stringify(res))
context.emit('setUser')
ElMessage.success('登录成功')
closeViews()
})
.catch((err) => {
if (err.code === 210) {
ElMessage.error('账号或密码不正确')
} else if (err.code === 211) {
Api.register(formData.email, formData.password).then((res) => {
Cookie.set('userInfo', JSON.stringify(res))
context.emit('setUser')
ElMessage.success('注册成功')
closeViews()
})
}
})
}
})
}
//
function closeViews() {
refruleForm.value.resetFields()
context.emit('closeViews', false)
}
return {
...toRefs(form),
closeViews,
submitForm,
refruleForm,
rules
}
}
}
</script>
<style scoped lang="scss">
.my-dialog {
background: red;
}
.my-dialog /deep/.el-dialog__header {
border-bottom: 1px solid #eee !important;
}
.my-dialog /deep/.el-dialog__title {
font-size: 16px;
color: #e03b5d;
}
</style>

View File

@ -1,88 +0,0 @@
export const config = {
gradient1: {
direction: 'left-right',
// isPausedWhenNotInView: true,
image: {
source: 'https://zhanhongzhu.top/bg.jpg',
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
},
states: {
'default-state': {
gradients: [
[
{ color: '#833ab4', pos: 0.2 },
{ color: '#fd1d1d', pos: 0.8 },
{ color: '#38ef7d', pos: 1 }
],
[
{ color: '#40e0d0', pos: 0 },
{ color: '#ff8c00', pos: 0.2 },
{ color: '#ff0080', pos: 0.75 }
]
]
}
}
},
gradient2: {
direction: 'left-right',
opacity: [1, 1],
// isPausedWhenNotInView: true,
image: {
source: 'https://zhanhongzhu.top/bg.jpg',
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
},
states: {
'default-state': {
gradients: [
['#AA076B', '#61045F'],
['#02AAB0', '#00CDAC'],
['#DA22FF', '#9733EE']
]
}
}
},
gradient3: {
direction: 'left-right',
// isPausedWhenNotInView: true,
image: {
source: 'https://zhanhongzhu.top/bg.jpg',
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
},
states: {
'default-state': {
gradients: [
['#ff9966', '#ff5e62'],
['#00F260', '#0575E6'],
['#e1eec3', '#f05053']
]
}
}
},
gradient4: {
direction: 'top-bottom',
// isPausedWhenNotInView: true,
image: {
source: 'https://zhanhongzhu.top/bg.jpg',
position: ['center', 'bottom'],
stretchMode: ['stretch', 'stretch-if-bigger'],
blendingMode: 'multiply'
},
states: {
'default-state': {
gradients: [
['#29323c', '#485563'],
['#FF6B6B', '#556270'],
['#80d3fe', '#7ea0c4'],
['#f0ab51', '#eceba3']
],
transitionSpeed: 7000
}
}
}
}

View File

@ -1,20 +0,0 @@
export const themeConfig = {
light: {
bgColor: '#fff',
activeColor: '#a0cae6',
textColor: '#111',
hoverColor: '#fff',
borderColor: '#eee',
scrollbarColor: '#dddddd',
svgColor: ''
},
dark: {
bgColor: '#111',
activeColor: '#000',
textColor: '#fff',
hoverColor: '#000',
borderColor: '#2c2c2c',
scrollbarColor: '#222',
svgColor: '#888'
}
}

View File

@ -1,89 +0,0 @@
// 格式化浏览器书签
export 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 = {
type: 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 = {
title: _item?.innerText,
url: _item?.href
}
}
}
child && list.push(child)
}
}
}
}
walk(root, result)
const myBookmark = result.filter(v => v.folder)
return flagBrowerList(myBookmark)
}
// 降维书签数据
const flagBrowerList = v => {
const res = []
const flatten = (v) => {
for (let i = 0; i < v.length; i++) {
if (v[i].folder) {
flatten(v[i].children)
const result = v[i]
result.children = result.children.filter(v => !v.folder)
res.push(result)
}
}
}
flatten(v)
return res
}
// 导出数据为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('暂无可导出数据')
}
}

View File

@ -1,16 +0,0 @@
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
// 接入了Leancloud
import AV from 'leancloud-storage'
// 请注册leancloud,新建应用,然后替换这个
AV.init({
appId: '\x42\x77\x4c\x72\x43\x67\x64\x56\x79\x4c\x73\x35\x32\x6d\x4a\x4f\x31\x48\x63\x72\x58\x61\x6b\x49\x2d\x67\x7a\x47\x7a\x6f\x48\x73\x7a', appKey: '\x32\x35\x67\x4e\x77\x7a\x77\x34\x64\x56\x37\x49\x41\x68\x37\x69\x30\x49\x7a\x44\x6e\x59\x76\x56', serverURL: '\x68\x74\x74\x70\x73\x3a\x2f\x2f\x62\x77\x6c\x72\x63\x67\x64\x76\x2e\x6c\x63\x2d\x63\x6e\x2d\x6e\x31\x2d\x73\x68\x61\x72\x65\x64\x2e\x63\x6f\x6d'
})
const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

View File

@ -1,15 +0,0 @@
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/', // 打包配置,解决页面空白の配置方案。
devServer: {
port: 8080,
proxy: {
'/api': {
target: 'https://api.zhanhongzhu.top',
changeOrigin: true,
pathRewrite: {
'^/api': '/api'
}
}
}
}
}