├── .editorconfig
├── .eslintrc.js
├── .gitignore
├── .prettierrc.js
├── LICENSE
├── README.md
├── babel.config.js
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── assets
│ └── logo.png
├── background.js
├── components
│ ├── FileEdit
│ │ └── index.vue
│ ├── FileList
│ │ └── index.vue
│ └── FileSearch
│ │ └── index.vue
├── datastore
│ └── index.js
├── main.js
├── plugin
│ ├── datastore.js
│ ├── element-ui.js
│ ├── fortawesome.js
│ └── mavonEditor.js
├── router
│ └── index.js
├── store
│ └── index.js
└── views
│ └── Home.vue
└── tree.md
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*.{js,jsx,ts,tsx,vue}]
2 | indent_style = space
3 | indent_size = 2
4 | end_of_line = lf
5 | trim_trailing_whitespace = true
6 | insert_final_newline = true
7 | max_line_length = 120
8 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: {
4 | node: true
5 | },
6 | extends: ['plugin:vue/essential', '@vue/airbnb'],
7 | parserOptions: {
8 | parser: 'babel-eslint'
9 | },
10 | rules: {
11 | 'no-console': 0,
12 | 'no-debugger': 0,
13 | semi: ['error', 'never'], // 禁用 分号
14 | 'no-multiple-empty-lines': ['error'], // 代码空行 数量
15 | 'linebreak-style': [0, 'error', 'windows'], // 使用windows的换行
16 | 'comma-dangle': [2, 'never'], // 对象数组最后一个不带逗号
17 | 'no-trailing-spaces': 0, // 禁用 校验代码末尾带空格
18 | 'import/no-dynamic-require': 0, // 禁用 动态require
19 | 'import/no-unresolved': 0,
20 | 'no-param-reassign': 0, // 声明为函数参数的变量可能会引起误解
21 | 'max-len': ['error', 120], // 单行代码最大长度
22 | 'guard-for-in': 0, // 禁用 禁用for in 循环
23 | 'no-shadow': 0, // 禁用 禁止页面内相容参数名
24 | 'object-shorthand': 0, // 禁用 禁止对象内使用带引号字符串
25 | 'no-restricted-syntax': 0,
26 | 'no-plusplus': 0, // 禁用 ++
27 | 'consistent-return': 0, // 关闭箭头函数必须要return
28 | 'no-return-assign': 0, // return 语句中不能有赋值表达式
29 | 'global-require': 0, // 关闭禁止使用requrie
30 | 'prefer-promise-reject-errors': 0, // 这条规则旨在确保承诺只被Error对象拒绝。
31 | 'import/extensions': 'off', // 禁用文件名详细文件类型后缀
32 | 'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
33 | 'arrow-parens': ['error', 'as-needed'], // 箭头函数参数括号,可选 always:(默认)在所有情况下都需要参数;as-needed:当只有一个参数时允许省略参数
34 | 'no-undef': 0, // 关闭显式声明全局变量的要求
35 | 'class-methods-use-this': 0,
36 | 'no-underscore-dangle': ['error', { allow: ['_id'] }], // 允许指定的标识符具有悬挂下划线
37 | camelcase: 0, // 关闭使用骆驼拼写法
38 | 'no-global-assign': 0, // 允许修改只读全局变量,
39 | 'space-before-function-paren': [
40 | 'error',
41 | {
42 | anonymous: 'never',
43 | named: 'never',
44 | asyncArrow: 'always'
45 | }
46 | ],
47 | // 对象解构不需要换行
48 | 'object-curly-newline': [
49 | 'error',
50 | {
51 | ObjectPattern: {
52 | multiline: true
53 | }
54 | }
55 | ],
56 | 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }] // 允许在表达式中使用三元运算符,类似于短路评估
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 | # local env files
6 | .env.local
7 | .env.*.local
8 |
9 | # Log files
10 | npm-debug.log*
11 | yarn-debug.log*
12 | yarn-error.log*
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 | *.suo
18 | *.ntvs*
19 | *.njsproj
20 | *.sln
21 | *.sw?
22 |
23 | #Electron-builder output
24 | /dist_electron
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | semi: false, // 去掉分号
3 | singleQuote: true, // 使用单引号
4 | printWidth: 120, // 单行代码最大长度
5 | trailingComma: 'none' // 去掉结尾逗号(对象,数组等)
6 | }
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 mengdebiao
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-electron-notes
2 |
3 | ## 安装依赖
4 |
5 | ```
6 | npm install
7 | ```
8 |
9 | ### 本地启动项目
10 |
11 | ```
12 | npm run electron:serve
13 | ```
14 |
15 | ### 构建安装包
16 |
17 | ```
18 | npm run electron:build
19 | ```
20 |
21 | ### Lints and fixes files
22 |
23 | ```
24 | npm run lint
25 | ```
26 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-electron-notes",
3 | "version": "0.1.0",
4 | "private": true,
5 | "license": "MIT",
6 | "author": "sufen",
7 | "description": "An vue + electron + Markdown project",
8 | "repository": "https://github.com/mengdebiao/vue-electron-notes.git",
9 | "scripts": {
10 | "serve": "vue-cli-service serve",
11 | "build": "vue-cli-service build",
12 | "lint": "vue-cli-service lint",
13 | "electron:build": "vue-cli-service electron:build",
14 | "electron:serve": "vue-cli-service electron:serve",
15 | "postinstall": "electron-builder install-app-deps",
16 | "postuninstall": "electron-builder install-app-deps",
17 | "tree": "tree -a -I 'dist_electron|node_modules|.git|.vscode|yarn.lock|tree.md' --dirsfirst >tree.md"
18 | },
19 | "main": "background.js",
20 | "dependencies": {
21 | "@fortawesome/fontawesome-svg-core": "^1.2.28",
22 | "@fortawesome/free-brands-svg-icons": "^5.13.0",
23 | "@fortawesome/free-regular-svg-icons": "^5.13.0",
24 | "@fortawesome/free-solid-svg-icons": "^5.13.0",
25 | "@fortawesome/vue-fontawesome": "^0.1.9",
26 | "core-js": "^3.6.4",
27 | "crypto-js": "^4.0.0",
28 | "dayjs": "^1.8.28",
29 | "element-ui": "^2.13.2",
30 | "mavon-editor": "^2.9.0",
31 | "nedb-promises": "^4.0.3",
32 | "vue": "^2.6.11",
33 | "vue-router": "^3.1.6",
34 | "vuex": "^3.1.3"
35 | },
36 | "devDependencies": {
37 | "@vue/cli-plugin-babel": "~4.3.0",
38 | "@vue/cli-plugin-eslint": "~4.3.0",
39 | "@vue/cli-plugin-router": "~4.3.0",
40 | "@vue/cli-plugin-vuex": "~4.3.0",
41 | "@vue/cli-service": "~4.3.0",
42 | "@vue/eslint-config-airbnb": "^5.0.2",
43 | "babel-eslint": "^10.1.0",
44 | "electron": "^9.0.4",
45 | "eslint": "^6.7.2",
46 | "eslint-plugin-import": "^2.20.2",
47 | "eslint-plugin-vue": "^6.2.2",
48 | "less": "^3.0.4",
49 | "less-loader": "^5.0.0",
50 | "lint-staged": "^9.5.0",
51 | "localforage": "^1.7.4",
52 | "vue-cli-plugin-electron-builder": "~1.4.6",
53 | "vue-template-compiler": "^2.6.11"
54 | },
55 | "browserslist": [
56 | "> 1%",
57 | "last 2 versions"
58 | ],
59 | "gitHooks": {
60 | "pre-commit": "lint-staged"
61 | },
62 | "lint-staged": {
63 | "*.{js,jsx,vue}": [
64 | "vue-cli-service lint",
65 | "git add"
66 | ]
67 | },
68 | "__npminstall_done": false
69 | }
70 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengdebiao/vue-electron-notes/2863013b27582a0227d65b3f211024327a94e80a/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 | We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
21 |
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mengdebiao/vue-electron-notes/2863013b27582a0227d65b3f211024327a94e80a/src/assets/logo.png
--------------------------------------------------------------------------------
/src/background.js:
--------------------------------------------------------------------------------
1 | import { app, protocol, BrowserWindow } from 'electron'
2 | import {
3 | createProtocol
4 | /* installVueDevtools */
5 | } from 'vue-cli-plugin-electron-builder/lib'
6 |
7 | const isDevelopment = process.env.NODE_ENV !== 'production'
8 |
9 | // Keep a global reference of the window object, if you don't, the window will
10 | // be closed automatically when the JavaScript object is garbage collected.
11 | let mainWindow
12 |
13 | // Scheme must be registered before the app is ready
14 | protocol.registerSchemesAsPrivileged([{ scheme: 'app', privileges: { secure: true, standard: true } }])
15 |
16 | function createWindow() {
17 | // Create the browser window.
18 | mainWindow = new BrowserWindow({
19 | width: 1000,
20 | height: 600,
21 | webPreferences: {
22 | nodeIntegration: true,
23 | enableRemoteModule: true
24 | }
25 | })
26 |
27 | if (process.env.WEBPACK_DEV_SERVER_URL) {
28 | // Load the url of the dev server if in development mode
29 | mainWindow.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
30 | if (!process.env.IS_TEST) mainWindow.webContents.openDevTools({ mode: 'detach' })
31 | } else {
32 | createProtocol('app')
33 | // Load the index.html when not in development
34 | mainWindow.loadURL('app://./index.html')
35 | }
36 |
37 | mainWindow.on('closed', () => {
38 | mainWindow = null
39 | })
40 | }
41 |
42 | // Quit when all windows are closed.
43 | app.on('window-all-closed', () => {
44 | // On macOS it is common for applications and their menu bar
45 | // to stay active until the user quits explicitly with Cmd + Q
46 | if (process.platform !== 'darwin') {
47 | app.quit()
48 | }
49 | })
50 |
51 | app.on('activate', () => {
52 | // On macOS it's common to re-create a window in the app when the
53 | // dock icon is clicked and there are no other windows open.
54 | if (mainWindow === null) {
55 | createWindow()
56 | }
57 | })
58 |
59 | // This method will be called when Electron has finished
60 | // initialization and is ready to create browser windows.
61 | // Some APIs can only be used after this event occurs.
62 | app.on('ready', async () => {
63 | if (isDevelopment && !process.env.IS_TEST) {
64 | // Install Vue Devtools
65 | // Devtools extensions are broken in Electron 6.0.0 and greater
66 | // See https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/378 for more info
67 | // Electron will not launch with Devtools extensions installed on Windows 10 with dark mode
68 | // If you are not using Windows 10 dark mode, you may uncomment these lines
69 | // In addition, if the linked issue is closed, you can upgrade electron and uncomment these lines
70 | // try {
71 | // await installVueDevtools()
72 | // } catch (e) {
73 | // console.error('Vue Devtools failed to install:', e.toString())
74 | // }
75 | }
76 | createWindow()
77 | })
78 |
79 | // Exit cleanly on request from parent process in development mode.
80 | if (isDevelopment) {
81 | if (process.platform === 'win32') {
82 | process.on('message', data => {
83 | if (data === 'graceful-exit') {
84 | app.quit()
85 | }
86 | })
87 | } else {
88 | process.on('SIGTERM', () => {
89 | app.quit()
90 | })
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/components/FileEdit/index.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
41 |
42 |
68 |
--------------------------------------------------------------------------------
/src/components/FileList/index.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
19 |
20 | {{ item.title }}
21 |
22 | {{ item.updatedAt }}
23 |
24 |
25 |
28 |
29 |
30 |
31 |
87 |
88 |
126 |
167 |
--------------------------------------------------------------------------------
/src/components/FileSearch/index.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | 新建笔记
17 | 导入文件
18 |
19 |
20 |
21 |
22 |
23 |
42 |
43 |
60 |
--------------------------------------------------------------------------------
/src/datastore/index.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: nedb 数据模型
3 | * @Author: sufen
4 | * @Date: 2020-06-10 22:27:16
5 | * @LastEditTime: 2020-06-10 22:28:59
6 | * @LastEditors: sufen
7 | */
8 | import Datastore from 'nedb-promises'
9 | // import path from 'path'
10 | // import { remote } from 'electron'
11 |
12 | // console.log('数据存储路径:', remote.app.getPath('userData'))
13 |
14 | // const basePath = remote.app.getPath('userData')
15 |
16 | const db = {
17 | printTask: new Datastore({
18 | autoload: true,
19 | timestampData: true
20 | // filename: path.join(basePath, `db/${process.env.VUE_APP_ENV_CONFIG}/print_task_v${clientVersion}.db`)
21 | })
22 | }
23 |
24 | export default db
25 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './store'
5 | import '@/plugin/element-ui'
6 | import '@/plugin/fortawesome'
7 | import '@/plugin/mavonEditor'
8 | import '@/plugin/datastore'
9 |
10 | Vue.config.productionTip = false
11 |
12 | new Vue({
13 | router,
14 | store,
15 | render: h => h(App)
16 | }).$mount('#app')
17 |
--------------------------------------------------------------------------------
/src/plugin/datastore.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 引入 nedb 数据库
3 | * @Author: sufen
4 | * @Date: 2020-06-10 22:30:35
5 | * @LastEditTime: 2020-06-13 18:55:00
6 | * @LastEditors: sufen
7 | */
8 | import Vue from 'vue'
9 | import crypto from 'crypto'
10 | import Datastore from 'nedb-promises'
11 | import { remote } from 'electron'
12 |
13 | const basePath = remote.app.getPath('userData')
14 | console.log('程序数据存储路径:', basePath)
15 |
16 | const algorithm = 'aes-128-cbc' // 加密算法类型
17 | const password = 'vue-electron-notes' // 用于生成秘钥的密码
18 | const key = crypto.scryptSync(password, 'salt', 16) // 秘钥
19 | const iv = Buffer.alloc(16, 0) // 初始化向量
20 |
21 | const db = {
22 | markdown: new Datastore({
23 | autoload: true,
24 | timestampData: true,
25 | filename: basePath,
26 | afterSerialization(plaintext) {
27 | // 实例化一个cipher加密对象,使用加密算法进行加密,key作为密钥
28 | // 使用cipher对 plaintext 进行加密,源数据类型为utf-8,输出数据类型为hex
29 | const cipher = crypto.createCipheriv(algorithm, key, iv)
30 | let crypted = cipher.update(plaintext, 'utf-8', 'hex')
31 | crypted += cipher.final('hex')
32 | return crypted
33 | },
34 | beforeDeserialization(ciphertext) {
35 | // 实例化一个decipher解密对象,使用解密算法进行解密,key作为密钥
36 | // 使用decipher对 ciphertext 进行解密,源数据类型为hex,输出数据类型为utf-8
37 | const decipher = crypto.createDecipheriv(algorithm, key, iv)
38 | let decrypted = decipher.update(ciphertext, 'hex', 'utf-8')
39 | decrypted += decipher.final('utf-8')
40 | return decrypted
41 | }
42 | })
43 | }
44 |
45 | Vue.prototype.$db = db
46 |
--------------------------------------------------------------------------------
/src/plugin/element-ui.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: 引入 element-ui 框架
3 | * @Author: sufen
4 | * @Date: 2020-05-21 09:58:49
5 | * @LastEditTime: 2020-05-21 09:59:20
6 | * @LastEditors: sufen
7 | */
8 | import Vue from 'vue'
9 | import ElementUI from 'element-ui'
10 | import 'element-ui/lib/theme-chalk/index.css'
11 |
12 | Vue.use(ElementUI, { size: 'small' })
13 |
--------------------------------------------------------------------------------
/src/plugin/fortawesome.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: fortawesome 图标库
3 | * @Author: sufen
4 | * @Date: 2020-05-21 09:55:29
5 | * @LastEditTime: 2020-05-21 10:06:46
6 | * @LastEditors: sufen
7 | */
8 | import Vue from 'vue'
9 | import { library } from '@fortawesome/fontawesome-svg-core'
10 | import { faUserSecret } from '@fortawesome/free-solid-svg-icons'
11 | import { faMarkdown } from '@fortawesome/free-brands-svg-icons'
12 | // import { faUserSecret } from '@fortawesome/free-regular-svg-icons'
13 | import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
14 |
15 | library.add(faUserSecret, faMarkdown)
16 |
17 | Vue.component('font-awesome-icon', FontAwesomeIcon)
18 |
--------------------------------------------------------------------------------
/src/plugin/mavonEditor.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Description: markdown 编辑器插件
3 | * @Author: sufen
4 | * @Date: 2020-05-30 16:31:31
5 | * @LastEditTime: 2020-06-02 11:01:31
6 | * @LastEditors: sufen
7 | */
8 | import Vue from 'vue'
9 | import mavonEditor from 'mavon-editor'
10 | import 'mavon-editor/dist/css/index.css'
11 |
12 | Vue.use(mavonEditor)
13 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 |
4 | Vue.use(VueRouter)
5 |
6 | const routes = [
7 | {
8 | path: '/',
9 | name: 'Home',
10 | component: () => import('@/views/Home')
11 | }
12 | ]
13 |
14 | const router = new VueRouter({
15 | base: process.env.BASE_URL,
16 | routes
17 | })
18 |
19 | export default router
20 |
--------------------------------------------------------------------------------
/src/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | export default new Vuex.Store({
7 | state: {
8 | },
9 | mutations: {
10 | },
11 | actions: {
12 | },
13 | modules: {
14 | }
15 | })
16 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
34 |
35 |
36 |
166 |
167 |
187 |
--------------------------------------------------------------------------------
/tree.md:
--------------------------------------------------------------------------------
1 | .
2 | ├── public
3 | │ ├── favicon.ico
4 | │ └── index.html
5 | ├── src
6 | │ ├── assets
7 | │ │ └── logo.png
8 | │ ├── components
9 | │ │ ├── FileEdit
10 | │ │ │ └── index.vue
11 | │ │ ├── FileList
12 | │ │ │ └── index.vue
13 | │ │ └── FileSearch
14 | │ │ └── index.vue
15 | │ ├── datastore
16 | │ │ └── index.js
17 | │ ├── plugin
18 | │ │ ├── datastore.js
19 | │ │ ├── element-ui.js
20 | │ │ ├── fortawesome.js
21 | │ │ └── mavonEditor.js
22 | │ ├── router
23 | │ │ └── index.js
24 | │ ├── store
25 | │ │ └── index.js
26 | │ ├── views
27 | │ │ └── Home.vue
28 | │ ├── App.vue
29 | │ ├── background.js
30 | │ └── main.js
31 | ├── .editorconfig
32 | ├── .eslintrc.js
33 | ├── .gitignore
34 | ├── .prettierrc.js
35 | ├── README.md
36 | ├── babel.config.js
37 | └── package.json
38 |
39 | 12 directories, 24 files
40 |
--------------------------------------------------------------------------------