├── tsconfig.json ├── module └── vue3-context-menu.d.ts ├── .vscode └── extensions.json ├── public ├── icon │ ├── 128.png │ ├── 16.png │ ├── 32.png │ ├── 48.png │ └── 96.png └── wxt.svg ├── entrypoints ├── background.ts ├── content.ts ├── popup │ ├── main.ts │ ├── index.html │ └── App.vue └── view │ └── catalogue.vue ├── types └── tree.ts ├── styles ├── index.css ├── reset.css └── style.css ├── components ├── svgIcon │ └── svg.vue ├── tree │ └── treeItem.vue └── dialog │ └── dialog.vue ├── .gitignore ├── README.md ├── assets └── svgs │ ├── vue.svg │ ├── uniapp.svg │ ├── gitee.svg │ ├── pluginmanagement.svg │ ├── miniprogram.svg │ ├── gitlab.svg │ ├── mdnwebdocs.svg │ ├── github.svg │ ├── nuxt.svg │ ├── reactrouter.svg │ ├── es6.svg │ ├── nextjs.svg │ ├── nodejs.svg │ ├── redux.svg │ ├── typescript.svg │ ├── createreactapp.svg │ ├── pinia.svg │ ├── express.svg │ ├── react.svg │ ├── umijs.svg │ ├── koa.svg │ └── nestjs.svg ├── CHANGELOG.md ├── components.d.ts ├── utils ├── index.ts └── storage.ts ├── package.json ├── wxt.config.ts ├── uno.config.ts ├── auto-imports.d.ts └── config └── index.ts /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.wxt/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /module/vue3-context-menu.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@imengyu/vue3-context-menu'; -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar"] 3 | } 4 | -------------------------------------------------------------------------------- /public/icon/128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/984507092/platform-link/HEAD/public/icon/128.png -------------------------------------------------------------------------------- /public/icon/16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/984507092/platform-link/HEAD/public/icon/16.png -------------------------------------------------------------------------------- /public/icon/32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/984507092/platform-link/HEAD/public/icon/32.png -------------------------------------------------------------------------------- /public/icon/48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/984507092/platform-link/HEAD/public/icon/48.png -------------------------------------------------------------------------------- /public/icon/96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/984507092/platform-link/HEAD/public/icon/96.png -------------------------------------------------------------------------------- /entrypoints/background.ts: -------------------------------------------------------------------------------- 1 | export default defineBackground(() => { 2 | console.log('Hello background!', { id: browser.runtime.id }); 3 | }); 4 | -------------------------------------------------------------------------------- /entrypoints/content.ts: -------------------------------------------------------------------------------- 1 | export default defineContentScript({ 2 | matches: ['*://*.google.com/*'], 3 | main() { 4 | console.log('Hello content.'); 5 | }, 6 | }); 7 | -------------------------------------------------------------------------------- /types/tree.ts: -------------------------------------------------------------------------------- 1 | export interface LinkNodeType { 2 | id?: string | number; 3 | name: string; 4 | link: string; 5 | icon: string; 6 | parentName: string | null; 7 | children?: LinkNodeType[] 8 | } 9 | -------------------------------------------------------------------------------- /styles/index.css: -------------------------------------------------------------------------------- 1 | @import './style.css'; 2 | @import './reset.css'; 3 | 4 | * { 5 | margin: 0; 6 | padding: 0; 7 | } 8 | 9 | /*滚动条样式修改*/ 10 | ::-webkit-scrollbar { 11 | width: 5px; 12 | } 13 | 14 | ::-webkit-scrollbar-thumb { 15 | background: #dedee0; 16 | border-radius: 6px; 17 | } -------------------------------------------------------------------------------- /components/svgIcon/svg.vue: -------------------------------------------------------------------------------- 1 | 6 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .output 12 | stats.html 13 | stats-*.json 14 | .wxt 15 | web-ext.config.ts 16 | 17 | # Editor directories and files 18 | .vscode/* 19 | !.vscode/extensions.json 20 | .idea 21 | .DS_Store 22 | *.suo 23 | *.ntvs* 24 | *.njsproj 25 | *.sln 26 | *.sw? 27 | -------------------------------------------------------------------------------- /entrypoints/popup/main.ts: -------------------------------------------------------------------------------- 1 | import {createApp} from 'vue'; 2 | import '../../styles/index.css'; 3 | import 'virtual:uno.css' 4 | import 'virtual:svg-icons-register' 5 | import App from './App.vue'; 6 | import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css' 7 | 8 | import ContextMenu from '@imengyu/vue3-context-menu' 9 | 10 | 11 | const app = createApp(App) 12 | app.use(ContextMenu) 13 | app.mount('#app'); 14 | -------------------------------------------------------------------------------- /entrypoints/popup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Default Popup Title 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # platform-link 2 | 3 | 对各个平台文档进行一个汇总的浏览器插件 4 | 5 | ## Vue React ES6 Node 等多个文档地址 6 | 7 | 此项目仅用来学习使用 8 | 9 | ## Todo List 10 | 11 | ### 数据存储相关 12 | 13 | - [ ] 通过chrome.storage.sync API 进行 Google 帐号数据存储同步 14 | - [x] 通过File System 或 chrome.storage.local API 进行本地数据存储 15 | 16 | ### 数据结构相关 17 | 18 | - [x] 实现树结构和扁平化数据相互转换 19 | - [x] 实现右键新增数据(待完成) 20 | - [x] 实现数据编辑和删除功能(待完成) 21 | - [ ] 实现数据导入和导出功能 22 | 23 | ### 界面功能相关 24 | 25 | - [x] 实现拖拽功能 26 | - [x] 实现数据搜索功能 27 | - [ ] 实现数据排序功能 28 | -------------------------------------------------------------------------------- /assets/svgs/vue.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## 1.0.1 4 | 5 | - 实现基础展示功能 6 | - 图标展示 7 | - 树结构组件处理 8 | - 配置 `auto-import` 工具 9 | 10 | ## 1.0.2 11 | 12 | - 配置 `unocss` 13 | - 重构数据结构(展示通过默认数据结构转为树结构实现) 14 | - 新增搜索功能 15 | 16 | ## 1.0.3 17 | 18 | - 完善了链接目录 19 | - 新增 `github` 目录 20 | - 完善 `vue` 、 `react` 等目录 21 | - 修复搜索功能导致的一些问题 22 | 23 | ## 1.0.4 24 | 25 | - 修改链接错误 26 | - 修改滚动条样式 27 | - 修改node和小程序链接错误问题 28 | - 修复搜索功能导致的一些问题 29 | 30 | ## 1.0.5 31 | 32 | - 增加拖拽功能 33 | - storage.local API进行本地存储 34 | - 实现数据新增、编辑、删除功能(待完成) 35 | -------------------------------------------------------------------------------- /assets/svgs/uniapp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // Generated by unplugin-vue-components 5 | // Read more: https://github.com/vuejs/core/pull/3399 6 | export {} 7 | 8 | declare module 'vue' { 9 | export interface GlobalComponents { 10 | ElButton: typeof import('element-plus/es')['ElButton'] 11 | ElDialog: typeof import('element-plus/es')['ElDialog'] 12 | ElForm: typeof import('element-plus/es')['ElForm'] 13 | ElFormItem: typeof import('element-plus/es')['ElFormItem'] 14 | ElInput: typeof import('element-plus/es')['ElInput'] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /components/tree/treeItem.vue: -------------------------------------------------------------------------------- 1 | 12 | 20 | 25 | -------------------------------------------------------------------------------- /utils/index.ts: -------------------------------------------------------------------------------- 1 | import type { LinkNodeType } from '@/types/tree'; 2 | 3 | export function flatToTree(nodes: LinkNodeType[]): LinkNodeType[] { 4 | const tree: LinkNodeType[] = []; 5 | const map: { [key: string]: LinkNodeType } = {}; 6 | 7 | // 创建一个映射,以节点的name作为键 8 | for (const node of nodes) { 9 | map[node.name] = node; 10 | } 11 | 12 | // 构建树状结构 13 | for (const node of nodes) { 14 | if (node.parentName) { 15 | // 如果当前节点有父节点,将其添加到父节点的children数组中 16 | if (map[node.parentName]) { 17 | 18 | if (!map[node.parentName].children) { 19 | map[node.parentName].children = []; 20 | } 21 | map[node.parentName].children!.push(node); 22 | } 23 | } else { 24 | // 如果当前节点没有父节点,将其添加到树数组中 25 | tree.push(node); 26 | } 27 | } 28 | 29 | return tree; 30 | } 31 | -------------------------------------------------------------------------------- /assets/svgs/gitee.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/pluginmanagement.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "platform-link", 3 | "description": "manifest.json description", 4 | "private": true, 5 | "version": "1.0.5", 6 | "type": "module", 7 | "scripts": { 8 | "dev": "wxt", 9 | "dev:firefox": "wxt -b firefox", 10 | "build": "wxt build", 11 | "build:firefox": "wxt build -b firefox", 12 | "zip": "wxt zip", 13 | "zip:firefox": "wxt zip -b firefox", 14 | "compile": "vue-tsc --noEmit", 15 | "postinstall": "wxt prepare" 16 | }, 17 | "dependencies": { 18 | "@imengyu/vue3-context-menu": "^1.4.1", 19 | "element-plus": "^2.7.1", 20 | "vue": "^3.4.0", 21 | "vuedraggable": "^4.1.0" 22 | }, 23 | "devDependencies": { 24 | "@vitejs/plugin-vue": "^5.0.1", 25 | "sass": "^1.72.0", 26 | "sass-loader": "^14.1.1", 27 | "typescript": "^5.3.3", 28 | "unocss": "^0.58.6", 29 | "unplugin-auto-import": "^0.17.5", 30 | "unplugin-vue-components": "^0.26.0", 31 | "vite-plugin-svg-icons": "^2.0.1", 32 | "vue-tsc": "^2.0.6", 33 | "wxt": "^0.17.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /public/wxt.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /entrypoints/popup/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 17 | 18 | 48 | -------------------------------------------------------------------------------- /assets/svgs/miniprogram.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /wxt.config.ts: -------------------------------------------------------------------------------- 1 | import {defineConfig} from 'wxt'; 2 | import vue from '@vitejs/plugin-vue'; 3 | import {createSvgIconsPlugin} from "vite-plugin-svg-icons"; 4 | import UnoCSS from 'unocss/vite' 5 | import path from "path"; 6 | import AutoImport from 'unplugin-auto-import/vite' 7 | import Components from 'unplugin-vue-components/vite' 8 | import {ElementPlusResolver} from 'unplugin-vue-components/resolvers' 9 | 10 | // See https://wxt.dev/api/config.html 11 | export default defineConfig({ 12 | imports: { 13 | addons: { 14 | vueTemplate: true, 15 | }, 16 | }, 17 | vite: () => ({ 18 | plugins: [ 19 | vue(), 20 | UnoCSS(), 21 | AutoImport({ 22 | // targets to transform 23 | include: [/\.[tj]sx?$/, /\.vue$/, /\.vue\?vue/, /\.md$/], 24 | 25 | // global imports to register 26 | imports: [ 27 | // vue auto import 28 | 'vue', 29 | ], 30 | resolvers: [ElementPlusResolver()], 31 | }), 32 | Components({ 33 | resolvers: [ElementPlusResolver()], 34 | }), 35 | createSvgIconsPlugin({ 36 | // 指定目录(svg存放目录) 37 | iconDirs: [path.resolve(process.cwd(), "assets/svgs")], 38 | // 使用 svg 图标的格式(name为图片名称) 39 | symbolId: "icon-[name]", 40 | //生成组件插入位置 只有两个值 boby-last | body-first 41 | inject: 'body-last' 42 | }), 43 | ], 44 | }), 45 | manifest: { 46 | permissions: ['storage'], 47 | }, 48 | }); 49 | -------------------------------------------------------------------------------- /assets/svgs/gitlab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/mdnwebdocs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /styles/reset.css: -------------------------------------------------------------------------------- 1 | /* http://meyerweb.com/eric/tools/css/reset/ 2 | v5.0.1 | 20191019 3 | License: none (public domain) 4 | */ 5 | 6 | html, body, div, span, applet, object, iframe, 7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 8 | a, abbr, acronym, address, big, cite, code, 9 | del, dfn, em, img, ins, kbd, q, s, samp, 10 | small, strike, strong, sub, sup, tt, var, 11 | b, u, i, center, 12 | dl, dt, dd, ol, ul, li, 13 | fieldset, form, label, legend, 14 | table, caption, tbody, tfoot, thead, tr, th, td, 15 | article, aside, canvas, details, embed, 16 | figure, figcaption, footer, header, hgroup, 17 | main, menu, nav, output, ruby, section, summary, 18 | time, mark, audio, video { 19 | margin: 0; 20 | padding: 0; 21 | border: 0; 22 | font-size: 100%; 23 | font: inherit; 24 | vertical-align: baseline; 25 | } 26 | /* HTML5 display-role reset for older browsers */ 27 | article, aside, details, figcaption, figure, 28 | footer, header, hgroup, main, menu, nav, section { 29 | display: block; 30 | } 31 | /* HTML5 hidden-attribute fix for newer browsers */ 32 | *[hidden] { 33 | display: none; 34 | } 35 | body { 36 | line-height: 1; 37 | } 38 | menu, ol, ul { 39 | list-style: none; 40 | } 41 | blockquote, q { 42 | quotes: none; 43 | } 44 | blockquote:before, blockquote:after, 45 | q:before, q:after { 46 | content: ''; 47 | content: none; 48 | } 49 | table { 50 | border-collapse: collapse; 51 | border-spacing: 0; 52 | } -------------------------------------------------------------------------------- /utils/storage.ts: -------------------------------------------------------------------------------- 1 | import {storage} from 'wxt/storage'; 2 | import type {LinkNodeType} from '@/types/tree' 3 | 4 | enum typeItem { 5 | local = "local", 6 | session = "session", 7 | sync = "sync", 8 | managed = "managed", 9 | } 10 | 11 | type NodeType = "local" | "session" | "sync" | "managed" 12 | 13 | async function getItem(name: string, type: NodeType = "local"): Promise { 14 | return await storage.getItem(`${typeItem[type]}:${name}`) 15 | } 16 | 17 | async function setItem(name: string, data: T, type: NodeType = "local"): Promise { 18 | await storage.setItem(`${typeItem[type]}:${name}`, data) 19 | } 20 | 21 | async function removeItem(name: string, type: NodeType = "local"): Promise { 22 | await storage.removeItem(`${typeItem[type]}:${name}`) 23 | } 24 | 25 | //对象 26 | async function getMeta(name: string, type: NodeType = "local"): Promise { 27 | return await storage.getMeta(`${typeItem[type]}:${name}`) 28 | } 29 | 30 | async function setMeta(name: string, data: T, type: NodeType = "local"): Promise { 31 | await storage.setMeta(`${typeItem[type]}:${name}`, data) 32 | } 33 | 34 | async function removeMeta(name: string, type: NodeType = "local"): Promise { 35 | await storage.removeMeta(`${typeItem[type]}:${name}`) 36 | } 37 | 38 | export { 39 | removeMeta, 40 | setMeta, 41 | getMeta, 42 | getItem, 43 | setItem, 44 | removeItem 45 | } -------------------------------------------------------------------------------- /assets/svgs/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/nuxt.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/reactrouter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/es6.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, // https://github.com/antfu/unocss/blob/main/src/types/config.ts 3 | // 预设 attributify 4 | presetAttributify, // https://unocss.dev/preset/attributify 5 | // 预设 icon 6 | presetIcons, // https://unocss.dev/preset/icons 7 | // 预设 typography 8 | presetTypography, // https://unocss.dev/preset/typography 9 | // 预设 preset 10 | presetUno, // https://unocss.dev/preset/uno 11 | // 预设 web-font 12 | presetWebFonts, // https://unocss.dev/preset/web-fonts 13 | // 自动导入指令 14 | transformerDirectives, // https://github.com/antfu/unocss/blob/main/src/transformers/directives.ts 15 | } from "unocss"; 16 | 17 | export default defineConfig({ 18 | // 自定义配置 19 | shortcuts: { 20 | "flex-center": "flex items-center justify-center", 21 | "border-base": "border-gray-200 dark:border-gray-500", 22 | "bg-active": "bg-gray:10", 23 | "bg-mask": "bg-white-80 dark:bg-black-30", 24 | }, 25 | // 额外选项 26 | rules: [ 27 | [/^t-a-(\d+)$/, ([, d]) => ({ transition: `all 0.${d}s linear` })], 28 | [ 29 | /^bg-white-(\d+)$/, 30 | ([, d]) => ({ "background-color": `rgb(255 255 255 / ${d}%)` }), 31 | ], 32 | [ 33 | /^bg-black-(\d+)$/, 34 | ([, d]) => ({ "background-color": `rgb(0 0 0 / ${d}%)` }), 35 | ], 36 | [/^l-s-(\d+)$/, ([, d]) => ({ "letter-spacing": `${d}px` })], 37 | ], 38 | // 主题 39 | theme: { 40 | colors: { 41 | primary: { 42 | DEFAULT: "#00DC82", 43 | }, 44 | }, 45 | }, 46 | // 预设 47 | presets: [ 48 | presetUno(), 49 | presetIcons(), 50 | presetAttributify(), 51 | presetWebFonts({ 52 | provider: "bunny", 53 | fonts: { 54 | sans: "DM Sans", 55 | mono: "DM Mono", 56 | ping: "PingFangMedium" 57 | }, 58 | }), 59 | presetTypography(), 60 | ], 61 | // 交互 62 | transformers: [transformerDirectives()], 63 | }); 64 | -------------------------------------------------------------------------------- /styles/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; 3 | line-height: 1.5; 4 | font-weight: 400; 5 | 6 | color-scheme: light dark; 7 | color: rgba(255, 255, 255, 0.87); 8 | background-color: #242424; 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | a { 18 | font-weight: 500; 19 | color: #646cff; 20 | text-decoration: inherit; 21 | } 22 | 23 | a:hover { 24 | color: #535bf2; 25 | } 26 | 27 | a { 28 | font-weight: 500; 29 | color: #646cff; 30 | text-decoration: inherit; 31 | } 32 | 33 | a:hover { 34 | color: #535bf2; 35 | } 36 | 37 | ul li { 38 | list-style: none; 39 | } 40 | 41 | body { 42 | margin: 0; 43 | display: flex; 44 | place-items: center; 45 | min-width: 260px; 46 | min-height: 100vh; 47 | } 48 | 49 | h1 { 50 | font-size: 3.2em; 51 | line-height: 1.1; 52 | } 53 | 54 | button { 55 | border-radius: 8px; 56 | border: 1px solid transparent; 57 | padding: 0.6em 1.2em; 58 | font-size: 1em; 59 | font-weight: 500; 60 | font-family: inherit; 61 | background-color: #1a1a1a; 62 | cursor: pointer; 63 | transition: border-color 0.25s; 64 | } 65 | 66 | button:hover { 67 | border-color: #646cff; 68 | } 69 | 70 | button:focus, 71 | button:focus-visible { 72 | outline: 4px auto -webkit-focus-ring-color; 73 | } 74 | 75 | .card { 76 | padding: 2em; 77 | } 78 | 79 | #app { 80 | max-width: 1280px; 81 | margin: 0 auto; 82 | /*padding: 2rem;*/ 83 | /*text-align: center;*/ 84 | } 85 | 86 | @media (prefers-color-scheme: light) { 87 | :root { 88 | color: #213547; 89 | background-color: #ffffff; 90 | } 91 | 92 | a:hover { 93 | color: #747bff; 94 | } 95 | 96 | button { 97 | background-color: #f9f9f9; 98 | } 99 | } 100 | 101 | -------------------------------------------------------------------------------- /assets/svgs/nextjs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/nodejs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/redux.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/typescript.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/dialog/dialog.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 96 | 97 | 100 | -------------------------------------------------------------------------------- /assets/svgs/createreactapp.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /auto-imports.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | /* prettier-ignore */ 3 | // @ts-nocheck 4 | // noinspection JSUnusedGlobalSymbols 5 | // Generated by unplugin-auto-import 6 | export {} 7 | declare global { 8 | const EffectScope: typeof import('vue')['EffectScope'] 9 | const computed: typeof import('vue')['computed'] 10 | const createApp: typeof import('vue')['createApp'] 11 | const customRef: typeof import('vue')['customRef'] 12 | const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] 13 | const defineComponent: typeof import('vue')['defineComponent'] 14 | const effectScope: typeof import('vue')['effectScope'] 15 | const getCurrentInstance: typeof import('vue')['getCurrentInstance'] 16 | const getCurrentScope: typeof import('vue')['getCurrentScope'] 17 | const h: typeof import('vue')['h'] 18 | const inject: typeof import('vue')['inject'] 19 | const isProxy: typeof import('vue')['isProxy'] 20 | const isReactive: typeof import('vue')['isReactive'] 21 | const isReadonly: typeof import('vue')['isReadonly'] 22 | const isRef: typeof import('vue')['isRef'] 23 | const markRaw: typeof import('vue')['markRaw'] 24 | const nextTick: typeof import('vue')['nextTick'] 25 | const onActivated: typeof import('vue')['onActivated'] 26 | const onBeforeMount: typeof import('vue')['onBeforeMount'] 27 | const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] 28 | const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] 29 | const onDeactivated: typeof import('vue')['onDeactivated'] 30 | const onErrorCaptured: typeof import('vue')['onErrorCaptured'] 31 | const onMounted: typeof import('vue')['onMounted'] 32 | const onRenderTracked: typeof import('vue')['onRenderTracked'] 33 | const onRenderTriggered: typeof import('vue')['onRenderTriggered'] 34 | const onScopeDispose: typeof import('vue')['onScopeDispose'] 35 | const onServerPrefetch: typeof import('vue')['onServerPrefetch'] 36 | const onUnmounted: typeof import('vue')['onUnmounted'] 37 | const onUpdated: typeof import('vue')['onUpdated'] 38 | const provide: typeof import('vue')['provide'] 39 | const reactive: typeof import('vue')['reactive'] 40 | const readonly: typeof import('vue')['readonly'] 41 | const ref: typeof import('vue')['ref'] 42 | const resolveComponent: typeof import('vue')['resolveComponent'] 43 | const shallowReactive: typeof import('vue')['shallowReactive'] 44 | const shallowReadonly: typeof import('vue')['shallowReadonly'] 45 | const shallowRef: typeof import('vue')['shallowRef'] 46 | const toRaw: typeof import('vue')['toRaw'] 47 | const toRef: typeof import('vue')['toRef'] 48 | const toRefs: typeof import('vue')['toRefs'] 49 | const toValue: typeof import('vue')['toValue'] 50 | const triggerRef: typeof import('vue')['triggerRef'] 51 | const unref: typeof import('vue')['unref'] 52 | const useAttrs: typeof import('vue')['useAttrs'] 53 | const useCssModule: typeof import('vue')['useCssModule'] 54 | const useCssVars: typeof import('vue')['useCssVars'] 55 | const useSlots: typeof import('vue')['useSlots'] 56 | const watch: typeof import('vue')['watch'] 57 | const watchEffect: typeof import('vue')['watchEffect'] 58 | const watchPostEffect: typeof import('vue')['watchPostEffect'] 59 | const watchSyncEffect: typeof import('vue')['watchSyncEffect'] 60 | } 61 | // for type re-export 62 | declare global { 63 | // @ts-ignore 64 | export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' 65 | import('vue') 66 | } 67 | -------------------------------------------------------------------------------- /assets/svgs/pinia.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/express.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/svgs/umijs.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /config/index.ts: -------------------------------------------------------------------------------- 1 | import type {LinkNodeType} from '@/types/tree' 2 | import {flatToTree} from '@/utils' 3 | 4 | const data: LinkNodeType[] = [ 5 | // ES6相关 6 | {"name": "ES6相关", "link": "https://es6.ruanyifeng.com/", "icon": "es6", "parentName": null}, 7 | {"name": "ES6", "link": "https://es6.ruanyifeng.com/", "icon": "es6", "parentName": "ES6相关"}, 8 | // Vue全套 9 | {"name": "Vue全套", "link": "https://cn.vuejs.org/", "icon": "vue", "parentName": null}, 10 | {"name": "Vue", "link": "https://cn.vuejs.org/", "icon": "vue", "parentName": "Vue全套"}, 11 | { 12 | "name": "Vue Router", 13 | "link": "https://router.vuejs.org/installation.html", 14 | "icon": "vue", 15 | "parentName": "Vue全套" 16 | }, 17 | {"name": "Vuex", "link": "https://vuex.vuejs.org/zh/index.html", "icon": "vue", "parentName": "Vue全套"}, 18 | {"name": "Pinia", "link": "https://pinia.vuejs.org/zh/", "icon": "pinia", "parentName": "Vue全套"}, 19 | {"name": "Vue CLI", "link": "https://cli.vuejs.org/zh/guide/", "icon": "vue", "parentName": "Vue全套"}, 20 | {"name": "VuePress", "link": "https://v2.vuepress.vuejs.org/zh/", "icon": "vue", "parentName": "Vue全套"}, 21 | {"name": "VitePress", "link": "https://vitepress.dev/", "icon": "vue", "parentName": "Vue全套"}, 22 | {"name": "Vue3 One Piece", "link": "https://vue3js.cn/", "icon": "vue", "parentName": "Vue全套"}, 23 | // React全套 24 | {"name": "React全套", "link": "https://zh-hans.react.dev/", "icon": "react", "parentName": null}, 25 | {"name": "React", "link": "https://zh-hans.react.dev/", "icon": "react", "parentName": "React全套"}, 26 | {"name": "Redux", "link": "https://cn.redux.js.org/", "icon": "redux", "parentName": "React全套"}, 27 | { 28 | "name": "React Router", 29 | "link": "https://reactrouter.com/en/main", 30 | "icon": "reactrouter", 31 | "parentName": "React全套" 32 | }, 33 | {"name": "Create React App", "link": "https://cra.nodejs.cn/", "icon": "createreactapp", "parentName": "React全套"}, 34 | {"name": "React Native中文网", "link": "https://reactnative.cn/", "icon": "react", "parentName": "React全套"}, 35 | {"name": "UmiJS", "link": "https://umijs.org/", "icon": "umijs", "parentName": "React全套"}, 36 | // TypeScript相关 37 | {"name": "TypeScript全套", "link": "https://ts.nodejs.cn/", "icon": "typescript", "parentName": null}, 38 | {"name": "TypeScript", "link": "https://ts.nodejs.cn/", "icon": "typescript", "parentName": "TypeScript全套"}, 39 | { 40 | "name": "TypeScript 入门教程", 41 | "link": "https://ts.xcatliu.com/", 42 | "icon": "typescript", 43 | "parentName": "TypeScript全套" 44 | }, 45 | { 46 | "name": "深入理解 TypeScript", 47 | "link": "https://jkchao.github.io/typescript-book-chinese/", 48 | "icon": "typescript", 49 | "parentName": "TypeScript全套" 50 | }, 51 | // uniapp相关 52 | {"name": "uniapp相关", "link": "https://uniapp.dcloud.net.cn/", "icon": "uniapp", "parentName": null}, 53 | {"name": "uniapp", "link": "https://uniapp.dcloud.net.cn/", "icon": "uniapp", "parentName": "uniapp相关"}, 54 | // 小程序相关 55 | {"name": "小程序", "link": "https://developers.weixin.qq.com/miniprogram/dev/framework/", "icon": "miniprogram", "parentName": null}, 56 | { 57 | "name": "微信小程序", 58 | "link": "https://developers.weixin.qq.com/miniprogram/dev/framework/", 59 | "icon": "miniprogram", 60 | "parentName": "小程序" 61 | }, 62 | {"name": "支付宝小程序", "link": "https://opendocs.alipay.com/mini", "icon": "miniprogram", "parentName": "小程序"}, 63 | // Node相关 64 | {"name": "Node", "link": "https://nodejs.org/en", "icon": "nodejs", "parentName": null}, 65 | {"name": "Node 中文文档", "link": "https://nodejs.cn/", "icon": "nodejs", "parentName": "Node"}, 66 | {"name": "Node 英文文档", "link": "https://nodejs.org/en", "icon": "nodejs", "parentName": "Node"}, 67 | {"name": "Express", "link": "https://express.nodejs.cn/", "icon": "express", "parentName": "Node"}, 68 | {"name": "Koa", "link": "https://koa.nodejs.cn/", "icon": "koa", "parentName": "Node"}, 69 | // Nest相关 70 | {"name": "Nest", "link": "https://nestjs.com/", "icon": "nestjs", "parentName": null}, 71 | {"name": "Nest英文文档", "link": "https://nestjs.com/", "icon": "nestjs", "parentName": "Nest"}, 72 | {"name": "Nest中文文档", "link": "https://www.nestjs.com.cn/", "icon": "nestjs", "parentName": "Nest"}, 73 | // nuxt相关 74 | {"name": "NUXT", "link": "https://v2.nuxt.com/", "icon": "nuxt", "parentName": null}, 75 | {"name": "NUXT英文文档", "link": "https://v2.nuxt.com/", "icon": "nuxt", "parentName": "NUXT"}, 76 | {"name": "NUXT3中文文档", "link": "https://nuxt.com.cn/", "icon": "nuxt", "parentName": "NUXT"}, 77 | // next相关 78 | {"name": "NEXT", "link": "https://nextjs.org/", "icon": "nextjs", "parentName": null}, 79 | {"name": "NEXT英文文档", "link": "https://nextjs.org/", "icon": "nextjs", "parentName": "NEXT"}, 80 | {"name": "NEXT中文文档", "link": "https://www.nextjs.cn/", "icon": "nextjs", "parentName": "NEXT"}, 81 | // github相关 82 | {"name": "GitHub相关", "link": "https://github.com/", "icon": "github", "parentName": null}, 83 | {"name": "GitHub", "link": "https://github.com/", "icon": "github", "parentName": "GitHub相关"}, 84 | {"name": "Gitee", "link": "https://gitee.com/", "icon": "gitee", "parentName": "GitHub相关"}, 85 | {"name": "GitLab", "link": "https://about.gitlab.com/", "icon": "gitlab", "parentName": "GitHub相关"}, 86 | // WXT相关 87 | {"name": "WXT相关", "link": "https://wxt.dev/", "icon": "pluginmanagement", "parentName": null}, 88 | {"name": "WXT", "link": "https://wxt.dev/", "icon": "pluginmanagement", "parentName": "WXT相关"}, 89 | // MDN相关 90 | { 91 | "name": "MDN相关", 92 | "link": "https://developer.mozilla.org/zh-CN/docs/Learn", 93 | "icon": "mdnwebdocs", 94 | "parentName": null 95 | }, 96 | { 97 | "name": "MDN", 98 | "link": "https://developer.mozilla.org/zh-CN/docs/Learn", 99 | "icon": "mdnwebdocs", 100 | "parentName": 'MDN相关' 101 | } 102 | ] 103 | 104 | 105 | export default flatToTree(data) -------------------------------------------------------------------------------- /assets/svgs/koa.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /entrypoints/view/catalogue.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 237 | 238 | 318 | -------------------------------------------------------------------------------- /assets/svgs/nestjs.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------