├── .gitignore ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public ├── favicon.ico └── index.html ├── src ├── App.vue ├── api │ ├── notebooks.js │ ├── notes.js │ ├── request.js │ └── users.js ├── assets │ └── css │ │ ├── iconfont.css │ │ ├── iconfont.js │ │ ├── iconfont.ttf │ │ └── style.css ├── components │ ├── breadcrumb │ │ └── BBreadcrumb.vue │ ├── header │ │ └── BHeader.vue │ ├── note │ │ └── Note.vue │ └── notebook │ │ └── Notebook.vue ├── main.js ├── reliance │ ├── elementPlus.js │ ├── mdEditor.js │ ├── mdPreview.js │ └── utils.js ├── router │ └── index.js ├── store │ └── index.js ├── utils │ ├── htmlUtils.js │ └── timeUtils.js └── views │ ├── admin │ ├── Home.vue │ ├── detail │ │ └── Detail.vue │ ├── list │ │ ├── List.vue │ │ └── components │ │ │ └── columns.js │ └── nList │ │ ├── NList.vue │ │ └── components │ │ └── columns.js │ └── user │ ├── Home.vue │ ├── Login.vue │ ├── NotFound.vue │ ├── detail │ ├── Detail.vue │ └── components │ │ └── ToolBar.vue │ ├── nDetail │ ├── NDetail.vue │ └── components │ │ └── NoteTable.vue │ ├── overview │ ├── Overview.vue │ └── components │ │ ├── List.vue │ │ ├── NList.vue │ │ └── Profile.vue │ └── search │ ├── Search.vue │ └── components │ └── options.js └── vue.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rainforest-blog-frontend -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"], 3 | plugins: [ 4 | [ 5 | "import", 6 | { 7 | libraryName: "element-plus", 8 | customStyleName: (name) => { 9 | return `element-plus/lib/theme-chalk/${name}.css`; 10 | }, 11 | }, 12 | ], 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rainforest-blog-frontend", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vue-cli-service serve", 7 | "build": "vue-cli-service build --report", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "@kangc/v-md-editor": "^2.2.2", 12 | "axios": "^0.21.1", 13 | "core-js": "^3.6.5", 14 | "element-plus": "^1.0.2-beta.70", 15 | "highlight.js": "^10.7.2", 16 | "vue": "^3.0.0", 17 | "vue-router": "^4.0.0-0", 18 | "vuex": "^4.0.2" 19 | }, 20 | "devDependencies": { 21 | "@vue/cli-plugin-babel": "~4.5.0", 22 | "@vue/cli-plugin-eslint": "~4.5.0", 23 | "@vue/cli-plugin-router": "~4.5.0", 24 | "@vue/cli-service": "~4.5.0", 25 | "@vue/compiler-sfc": "^3.0.0", 26 | "@vue/eslint-config-prettier": "^6.0.0", 27 | "babel-eslint": "^10.1.0", 28 | "babel-plugin-import": "^1.13.3", 29 | "compression-webpack-plugin": "^5.0.1", 30 | "eslint": "^6.7.2", 31 | "eslint-plugin-prettier": "^3.3.1", 32 | "eslint-plugin-vue": "^7.0.0", 33 | "node-sass": "^4.12.0", 34 | "prettier": "^2.2.1", 35 | "sass-loader": "^8.0.2" 36 | }, 37 | "eslintConfig": { 38 | "root": true, 39 | "env": { 40 | "node": true 41 | }, 42 | "extends": [ 43 | "plugin:vue/vue3-essential", 44 | "eslint:recommended", 45 | "@vue/prettier" 46 | ], 47 | "parserOptions": { 48 | "parser": "babel-eslint" 49 | }, 50 | "rules": {} 51 | }, 52 | "browserslist": [ 53 | "> 1%", 54 | "last 2 versions", 55 | "not dead" 56 | ], 57 | "_id": "rainforest-blog-frontend@0.1.0", 58 | "readme": "ERROR: No README data found!" 59 | } 60 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inkmarkink/rainforest-blog-frontend/48dbec21f08f13e6b5657f158e58a2fdc82d34cf/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= htmlWebpackPlugin.options.title %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 13 | -------------------------------------------------------------------------------- /src/api/notebooks.js: -------------------------------------------------------------------------------- 1 | import { request } from "./request"; 2 | 3 | // 增加 4 | export function newNotebook(notebookData) { 5 | return request({ 6 | url: "/notebook/new", 7 | method: "post", 8 | data: notebookData, 9 | }); 10 | } 11 | 12 | // 删除 13 | 14 | // 修改 15 | export function updateNotebook(id, notebookData) { 16 | return request({ 17 | url: `/notebook/update/${id}`, 18 | method: "patch", 19 | data: notebookData, 20 | }); 21 | } 22 | 23 | // 查询单个 24 | export function getNotebookDetail(id) { 25 | return request({ 26 | url: `/notebook/${id}`, 27 | method: "get", 28 | }); 29 | } 30 | 31 | // 查询多个 32 | export function getNotebookList(queryData) { 33 | return request({ 34 | url: "/notebook/list", 35 | method: "post", 36 | data: queryData, 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /src/api/notes.js: -------------------------------------------------------------------------------- 1 | import { request } from "./request"; 2 | 3 | // 增加 4 | export function newNote(noteData) { 5 | return request({ 6 | url: "/note/new", 7 | method: "post", 8 | data: noteData, 9 | }); 10 | } 11 | 12 | // 删除 13 | export function deleteBlog(id, author) { 14 | return request({ 15 | url: "/blog/del", 16 | method: "post", 17 | data: { 18 | id, 19 | author, 20 | }, 21 | }); 22 | } 23 | 24 | // 修改 25 | export function updateNote(id, noteData) { 26 | return request({ 27 | url: `/note/${id}`, 28 | method: "patch", 29 | data: noteData, 30 | }); 31 | } 32 | 33 | // 查询单个 34 | export function getNoteDetail(queryData) { 35 | return request({ 36 | url: `/note/`, 37 | method: "post", 38 | data: queryData, 39 | }); 40 | } 41 | 42 | // 查询多个 43 | export function getNoteList(queryData) { 44 | return request({ 45 | url: "/note/list", 46 | method: "post", 47 | data: queryData, 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /src/api/request.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | // import router from "@/router"; 3 | // import store from "@/store"; 4 | 5 | export function request(config) { 6 | const instance = axios.create({ 7 | baseURL: "/api", 8 | }); 9 | 10 | // instance.interceptors.response.use((res) => { 11 | // // 拦截响应,做统一处理 12 | // if (res.data.code === 401) { 13 | // router.replace("/login"); 14 | // store.commit("logout"); 15 | // } 16 | // return res; 17 | // }); 18 | 19 | return instance(config); 20 | } 21 | -------------------------------------------------------------------------------- /src/api/users.js: -------------------------------------------------------------------------------- 1 | import { request } from "./request"; 2 | 3 | export function login(userData) { 4 | return request({ 5 | url: "/user/login", 6 | method: "post", 7 | data: userData, 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /src/assets/css/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; /* Project id */ 3 | src: url('iconfont.ttf?t=1625158476472') format('truetype'); 4 | } 5 | 6 | .iconfont { 7 | font-family: "iconfont" !important; 8 | font-size: 16px; 9 | font-style: normal; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | .icon-comment:before { 15 | content: "\e62c"; 16 | color: #ffd33d; 17 | } 18 | 19 | .icon-time:before { 20 | content: "\e61f"; 21 | color: #d15704; 22 | } 23 | 24 | .icon-edit:before { 25 | content: "\e636"; 26 | color: #fe898a; 27 | } 28 | 29 | .icon-add:before { 30 | content: "\e502"; 31 | } 32 | 33 | .icon-file:before { 34 | content: "\e678"; 35 | color: #00a1e3; 36 | } 37 | 38 | .icon-view:before { 39 | content: "\e609"; 40 | color: #2166d6; 41 | } 42 | 43 | .icon-back:before { 44 | content: "\e639"; 45 | color: #e34c26; 46 | } 47 | 48 | .icon-update:before { 49 | content: "\e6b6"; 50 | color: #28a745; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /src/assets/css/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(e){var t,n,o,i,c,l,d='',a=(a=document.getElementsByTagName("script"))[a.length-1].getAttribute("data-injectcss");if(a&&!e.__iconfont__svg__cssinject__){e.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(e){console&&console.log(e)}}function s(){c||(c=!0,o())}t=function(){var e,t,n;(n=document.createElement("div")).innerHTML=d,d=null,(t=n.getElementsByTagName("svg")[0])&&(t.setAttribute("aria-hidden","true"),t.style.position="absolute",t.style.width=0,t.style.height=0,t.style.overflow="hidden",e=t,(n=document.body).firstChild?(t=n.firstChild).parentNode.insertBefore(e,t):n.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(t,0):(n=function(){document.removeEventListener("DOMContentLoaded",n,!1),t()},document.addEventListener("DOMContentLoaded",n,!1)):document.attachEvent&&(o=t,i=e.document,c=!1,(l=function(){try{i.documentElement.doScroll("left")}catch(e){return void setTimeout(l,50)}s()})(),i.onreadystatechange=function(){"complete"==i.readyState&&(i.onreadystatechange=null,s())})}(window); -------------------------------------------------------------------------------- /src/assets/css/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inkmarkink/rainforest-blog-frontend/48dbec21f08f13e6b5657f158e58a2fdc82d34cf/src/assets/css/iconfont.ttf -------------------------------------------------------------------------------- /src/assets/css/style.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --color-header-bg: #24292a; 3 | --color-text-white: #fff; 4 | --main-color: #fff; 5 | --assist-color: #0aa679; 6 | --accent-color: #e63657; 7 | --secondary-color: #50505c; 8 | --third-color: #808091; 9 | --border-color: #eaecef; 10 | --link-color: #0366d6; 11 | --text-font: Optima-Regular,Optima,-apple-system,system-ui,Segoe UI,Roboto,Ubuntu,Cantarell,Noto Sans,sans-serif,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Hiragino Sans GB,Microsoft YaHei,Arial; 12 | } -------------------------------------------------------------------------------- /src/components/breadcrumb/BBreadcrumb.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 18 | 19 | 25 | -------------------------------------------------------------------------------- /src/components/header/BHeader.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 38 | 39 | 153 | -------------------------------------------------------------------------------- /src/components/note/Note.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 27 | 28 | 81 | -------------------------------------------------------------------------------- /src/components/notebook/Notebook.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 17 | 18 | 49 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import App from "@/App.vue"; 3 | import router from "@/router"; 4 | import store from "@/store"; 5 | import VueMarkdownEditor from "@/reliance/mdEditor.js"; 6 | import VMdPreview from "@/reliance/mdPreview.js"; 7 | import utils from "@/reliance/utils"; 8 | import components from "@/reliance/elementPlus.js"; 9 | 10 | const app = createApp(App); 11 | app.use(router); 12 | app.use(store); 13 | app.use(VueMarkdownEditor); 14 | app.use(VMdPreview); 15 | components.forEach((item) => { 16 | app.use(item); 17 | }); 18 | app.config.globalProperties.$utils = utils; 19 | app.mount("#app"); 20 | -------------------------------------------------------------------------------- /src/reliance/elementPlus.js: -------------------------------------------------------------------------------- 1 | import { 2 | ElBacktop, 3 | ElButton, 4 | ElBreadcrumb, 5 | ElBreadcrumbItem, 6 | ElIcon, 7 | ElInput, 8 | ElMenu, 9 | ElMenuItem, 10 | ElOption, 11 | ElSelect, 12 | ElSubmenu, 13 | ElTable, 14 | ElTableColumn, 15 | ElDrawer, 16 | ElForm, 17 | ElFormItem, 18 | ElMessage, 19 | } from "element-plus"; 20 | import "element-plus/lib/theme-chalk/index.css"; 21 | 22 | const components = [ 23 | ElBacktop, 24 | ElButton, 25 | ElBreadcrumb, 26 | ElBreadcrumbItem, 27 | ElDrawer, 28 | ElForm, 29 | ElFormItem, 30 | ElIcon, 31 | ElInput, 32 | ElMenu, 33 | ElMenuItem, 34 | ElMessage, 35 | ElOption, 36 | ElSelect, 37 | ElSubmenu, 38 | ElTable, 39 | ElTableColumn, 40 | ]; 41 | 42 | export default components; 43 | -------------------------------------------------------------------------------- /src/reliance/mdEditor.js: -------------------------------------------------------------------------------- 1 | import VueMarkdownEditor from "@kangc/v-md-editor"; 2 | import "@kangc/v-md-editor/lib/style/base-editor.css"; 3 | import githubTheme from "@kangc/v-md-editor/lib/theme/github.js"; 4 | import "@kangc/v-md-editor/lib/theme/style/github.css"; 5 | // import createMermaidPlugin from "@kangc/v-md-editor/lib/plugins/mermaid/cdn"; 6 | import "@kangc/v-md-editor/lib/plugins/mermaid/mermaid.css"; 7 | 8 | VueMarkdownEditor.use(githubTheme); 9 | // VueMarkdownEditor.use(createMermaidPlugin()); 10 | 11 | export default VueMarkdownEditor; 12 | -------------------------------------------------------------------------------- /src/reliance/mdPreview.js: -------------------------------------------------------------------------------- 1 | import VMdPreview from "@kangc/v-md-editor/lib/preview"; 2 | import "@kangc/v-md-editor/lib/style/preview.css"; 3 | import githubTheme from "@kangc/v-md-editor/lib/theme/github.js"; 4 | import "@kangc/v-md-editor/lib/theme/style/github.css"; 5 | import "@kangc/v-md-editor/lib/plugins/mermaid/mermaid.css"; 6 | import createCopyCodePlugin from "@kangc/v-md-editor/lib/plugins/copy-code/index"; 7 | import "@kangc/v-md-editor/lib/plugins/copy-code/copy-code.css"; 8 | import createTodoListPlugin from "@kangc/v-md-editor/lib/plugins/todo-list/index"; 9 | import "@kangc/v-md-editor/lib/plugins/todo-list/todo-list.css"; 10 | import c from "highlight.js/lib/languages/c.js"; 11 | import java from "highlight.js/lib/languages/java.js"; 12 | import json from "highlight.js/lib/languages/json.js"; 13 | import python from "highlight.js/lib/languages/python.js"; 14 | import sql from "highlight.js/lib/languages/sql.js"; 15 | 16 | VMdPreview.use(githubTheme, { 17 | extend(md, hljs) { 18 | // md为 markdown-it 实例,可以在此处进行修改配置,并使用 plugin 进行语法扩展 19 | // md.set(option).use(plugin); 20 | // 注册语言包 21 | hljs.registerLanguage("c", c); 22 | hljs.registerLanguage("json", json); 23 | hljs.registerLanguage("java", java); 24 | hljs.registerLanguage("python", python); 25 | hljs.registerLanguage("sql", sql); 26 | }, 27 | }); 28 | VMdPreview.use(createCopyCodePlugin()); 29 | VMdPreview.use(createTodoListPlugin()); 30 | 31 | export default VMdPreview; 32 | -------------------------------------------------------------------------------- /src/reliance/utils.js: -------------------------------------------------------------------------------- 1 | import { htmlDecode, htmlDecodeObject } from "../utils/htmlUtils"; 2 | import { getYearMonthDay, getMonthDay } from "../utils/timeUtils"; 3 | import router from "../router/index"; 4 | 5 | function changeRoute(path) { 6 | router.push({ 7 | path: path, 8 | }); 9 | } 10 | 11 | export default { 12 | htmlDecode, 13 | htmlDecodeObject, 14 | getYearMonthDay, 15 | getMonthDay, 16 | changeRoute, 17 | }; 18 | -------------------------------------------------------------------------------- /src/router/index.js: -------------------------------------------------------------------------------- 1 | import { createRouter, createWebHistory } from "vue-router"; 2 | import store from "../store"; 3 | 4 | const routes = [ 5 | { 6 | path: "/", 7 | component: () => import("@/views/user/Home.vue"), 8 | redirect: "/overview", 9 | meta: { 10 | title: "Overview", 11 | }, 12 | children: [ 13 | { 14 | path: "/overview", 15 | component: () => import("@/views/user/overview/Overview.vue"), 16 | }, 17 | { 18 | path: "/search", 19 | component: () => import("@/views/user/search/Search.vue"), 20 | }, 21 | { 22 | path: "/nDetail/:id", 23 | component: () => import("@/views/user/nDetail/NDetail.vue"), 24 | meta: { 25 | title: "Notebook", 26 | }, 27 | }, 28 | { 29 | path: "/detail/:id", 30 | component: () => import("@/views/user/detail/Detail.vue"), 31 | meta: { 32 | title: "Note", 33 | }, 34 | }, 35 | { 36 | path: "/:pathMatch(.*)*", 37 | name: "NotFound", 38 | component: () => import("@/views/user/NotFound.vue"), 39 | }, 40 | ], 41 | }, 42 | { 43 | path: "/admin", 44 | name: "Home", 45 | component: () => import("@/views/admin/Home.vue"), 46 | meta: { 47 | title: "Admin", 48 | requireAuth: true, 49 | }, 50 | redirect: "/admin/nList", 51 | children: [ 52 | { 53 | path: "nList", 54 | name: "NList", 55 | component: () => import("@/views/admin/nList/NList.vue"), 56 | meta: { 57 | title: "NotebookList", 58 | }, 59 | }, 60 | { 61 | path: "list/:id", 62 | component: () => import("@/views/admin/list/List.vue"), 63 | meta: { 64 | title: "NoteList", 65 | }, 66 | }, 67 | { 68 | path: "detail/:pid/:id", 69 | component: () => import("@/views/admin/detail/Detail.vue"), 70 | meta: { 71 | title: "Detail", 72 | }, 73 | }, 74 | ], 75 | }, 76 | { 77 | path: "/login", 78 | name: "Login", 79 | component: () => import("@/views/user/Login.vue"), 80 | }, 81 | ]; 82 | 83 | const router = createRouter({ 84 | history: createWebHistory(process.env.BASE_URL), 85 | routes, 86 | }); 87 | 88 | router.beforeEach((to) => { 89 | if (to.meta.requireAuth && store.getters.getLoginStatus === false) { 90 | return { 91 | path: "/login", 92 | }; 93 | } 94 | }); 95 | 96 | export default router; 97 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { createStore } from "vuex"; 2 | 3 | const store = createStore({ 4 | state() { 5 | return { 6 | isLogin: false, 7 | }; 8 | }, 9 | mutations: { 10 | login(state) { 11 | state.isLogin = true; 12 | }, 13 | logout(state) { 14 | state.isLogin = false; 15 | }, 16 | }, 17 | getters: { 18 | getLoginStatus(state) { 19 | return state.isLogin; 20 | }, 21 | }, 22 | }); 23 | 24 | export default store; 25 | -------------------------------------------------------------------------------- /src/utils/htmlUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {String} str 3 | * @returns 4 | */ 5 | export function htmlDecode(str) { 6 | if (str.length === 0) { 7 | return ""; 8 | } 9 | return str 10 | .replace(/&/g, "&") 11 | .replace(/'/g, "'") 12 | .replace(/>/g, ">") 13 | .replace(/</g, "<") 14 | .replace(/"/g, '"') 15 | .replace(/ /g, " "); 16 | } 17 | 18 | /** 19 | * @param {Object} obj 20 | * @returns 21 | */ 22 | export function htmlDecodeObject(obj) { 23 | if (obj === {}) { 24 | return {}; 25 | } 26 | let newObj = obj; 27 | for (let key in newObj) { 28 | if (typeof newObj[key] === "string") { 29 | newObj[key] = htmlDecode(newObj[key]); 30 | } 31 | } 32 | return newObj; 33 | } 34 | -------------------------------------------------------------------------------- /src/utils/timeUtils.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Number} time 3 | * @returns 4 | */ 5 | export function getYearMonthDay(time) { 6 | let date = new Date(time); 7 | let year = date.getFullYear(); 8 | let month = 9 | date.getMonth() + 1 < 10 10 | ? "0" + (date.getMonth() + 1) 11 | : date.getMonth() + 1; 12 | let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); 13 | return year + "/" + month + "/" + day; 14 | } 15 | 16 | export function getMonthDay(time) { 17 | let date = new Date(time); 18 | let month = 19 | date.getMonth() + 1 < 10 20 | ? "0" + (date.getMonth() + 1) 21 | : date.getMonth() + 1; 22 | let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate(); 23 | return month + "/" + day; 24 | } 25 | -------------------------------------------------------------------------------- /src/views/admin/Home.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 24 | 38 | -------------------------------------------------------------------------------- /src/views/admin/detail/Detail.vue: -------------------------------------------------------------------------------- 1 | 24 | 25 | 81 | 82 | 93 | -------------------------------------------------------------------------------- /src/views/admin/list/List.vue: -------------------------------------------------------------------------------- 1 | 42 | 43 | 73 | 74 | 85 | -------------------------------------------------------------------------------- /src/views/admin/list/components/columns.js: -------------------------------------------------------------------------------- 1 | const columns = [ 2 | { 3 | label: "标题", 4 | prop: "title", 5 | }, 6 | { 7 | label: "摘要", 8 | prop: "abstract", 9 | }, 10 | ]; 11 | 12 | export default columns; 13 | -------------------------------------------------------------------------------- /src/views/admin/nList/NList.vue: -------------------------------------------------------------------------------- 1 | 48 | 49 | 120 | 121 | 138 | -------------------------------------------------------------------------------- /src/views/admin/nList/components/columns.js: -------------------------------------------------------------------------------- 1 | const columns = [ 2 | { 3 | label: "名字", 4 | prop: "name", 5 | }, 6 | { 7 | label: "描述", 8 | prop: "description", 9 | }, 10 | ]; 11 | 12 | export default columns; 13 | -------------------------------------------------------------------------------- /src/views/user/Home.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /src/views/user/Login.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 93 | 94 | 224 | -------------------------------------------------------------------------------- /src/views/user/NotFound.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 30 | 31 | 57 | -------------------------------------------------------------------------------- /src/views/user/detail/Detail.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 45 | 46 | 61 | -------------------------------------------------------------------------------- /src/views/user/detail/components/ToolBar.vue: -------------------------------------------------------------------------------- 1 | 25 | 26 | 34 | 51 | -------------------------------------------------------------------------------- /src/views/user/nDetail/NDetail.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 45 | 46 | 57 | -------------------------------------------------------------------------------- /src/views/user/nDetail/components/NoteTable.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 54 | 55 | 90 | -------------------------------------------------------------------------------- /src/views/user/overview/Overview.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 38 | 39 | 54 | -------------------------------------------------------------------------------- /src/views/user/overview/components/List.vue: -------------------------------------------------------------------------------- 1 | 28 | 29 | 68 | 69 | 91 | -------------------------------------------------------------------------------- /src/views/user/overview/components/NList.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 42 | 43 | 51 | -------------------------------------------------------------------------------- /src/views/user/overview/components/Profile.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 32 | 33 | 55 | -------------------------------------------------------------------------------- /src/views/user/search/Search.vue: -------------------------------------------------------------------------------- 1 | 40 | 41 | 88 | 89 | 105 | -------------------------------------------------------------------------------- /src/views/user/search/components/options.js: -------------------------------------------------------------------------------- 1 | const options = [ 2 | { 3 | value: "lastUpdate", 4 | label: "按时间排序", 5 | }, 6 | { 7 | value: "name", 8 | label: "按标题排序", 9 | }, 10 | ]; 11 | 12 | export default options; 13 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | const compressionPlugin = require("compression-webpack-plugin"); 2 | 3 | module.exports = { 4 | devServer: { 5 | port: 9000, 6 | proxy: { 7 | "/api": { 8 | target: "http://localhost:3000", // 你请求的第三方接口 9 | changeOrigin: true, // 在本地会创建一个虚拟服务端,然后发送请求的数据,并同时接收请求的数据,这样服务端和服务端进行数据的交互就不会有跨域问题 10 | pathRewrite: { 11 | // 路径重写, 12 | "^/api": "", // 替换target中的请求地址,也就是说 /api=/target,请求 /target 这个地址的时候直接写成 /api即可。 13 | }, 14 | }, 15 | }, 16 | }, 17 | // 修改 index.html 里面的 html-webpack-plugin 的值 18 | chainWebpack: (config) => { 19 | config.plugin("html").tap((args) => { 20 | args[0].title = "rainforest 的资料分享"; 21 | return args; 22 | }); 23 | }, 24 | // 配置 gzip 压缩 25 | configureWebpack: () => { 26 | return { 27 | plugins: [ 28 | new compressionPlugin({ 29 | test: /\.js$|\.html$|\.css/, 30 | threshold: 10240, 31 | deleteOriginalAssets: false, 32 | }), 33 | ], 34 | }; 35 | }, 36 | productionSourceMap: true, 37 | }; 38 | --------------------------------------------------------------------------------