├── public
├── favicon.ico
└── index.html
├── src
├── assets
│ ├── hint.png
│ ├── logo.png
│ ├── text.png
│ ├── todo.png
│ ├── heading1.png
│ ├── heading2.png
│ ├── heading3.png
│ ├── BulletedList.png
│ └── github.svg
├── main.js
├── App.vue
├── router
│ └── index.js
├── views
│ ├── About.vue
│ └── Home.vue
├── components
│ ├── AddBlockBtn.vue
│ ├── basicBlockComponents
│ │ ├── Heading3.vue
│ │ ├── Heading1.vue
│ │ ├── Heading2.vue
│ │ ├── Hint.vue
│ │ ├── TextBlock.vue
│ │ ├── BulletedList.vue
│ │ └── TodoBlock.vue
│ └── AddBlockContent.vue
└── vuex
│ └── store.js
├── babel.config.js
├── .gitignore
├── package.json
└── README.md
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/assets/hint.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/hint.png
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/text.png
--------------------------------------------------------------------------------
/src/assets/todo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/todo.png
--------------------------------------------------------------------------------
/src/assets/heading1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/heading1.png
--------------------------------------------------------------------------------
/src/assets/heading2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/heading2.png
--------------------------------------------------------------------------------
/src/assets/heading3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/heading3.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/src/assets/BulletedList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CedarXi/All-in-one/HEAD/src/assets/BulletedList.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 | # local env files
5 | .env.local
6 | .env.*.local
7 |
8 | # Log files
9 | npm-debug.log*
10 | yarn-debug.log*
11 | yarn-error.log*
12 |
13 | # Editor directories and files
14 | .idea
15 | .vscode
16 | *.suo
17 | *.ntvs*
18 | *.njsproj
19 | *.sln
20 | *.sw?
21 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import store from './vuex/store' // 引入store
5 |
6 | import ElementUI from 'element-ui';
7 | import 'element-ui/lib/theme-chalk/index.css';
8 |
9 | Vue.use(ElementUI);
10 |
11 | Vue.config.productionTip = false
12 |
13 | new Vue({
14 | router, store,
15 | render: h => h(App)
16 | }).$mount('#app')
17 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
25 |
--------------------------------------------------------------------------------
/src/router/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueRouter from 'vue-router'
3 | import Home from '../views/Home.vue'
4 |
5 | Vue.use(VueRouter)
6 |
7 | const routes = [
8 | {
9 | path: '/',
10 | name: 'Home',
11 | component: Home
12 | },
13 | {
14 | path: '/about',
15 | name: 'About',
16 | // route level code-splitting
17 | // this generates a separate chunk (about.[hash].js) for this route
18 | // which is lazy-loaded when the route is visited.
19 | component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
20 | }
21 | ]
22 |
23 | const router = new VueRouter({
24 | mode: 'history',
25 | base: process.env.BASE_URL,
26 | routes
27 | })
28 |
29 | export default router
30 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | All-in-one
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "block-editor",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build"
8 | },
9 | "dependencies": {
10 | "core-js": "^3.6.4",
11 | "element-ui": "^2.13.0",
12 | "vue": "^2.6.11",
13 | "vue-router": "^3.1.6",
14 | "vuedraggable": "^2.23.2",
15 | "vuex": "^3.1.3"
16 | },
17 | "devDependencies": {
18 | "@vue/cli-plugin-babel": "~4.3.0",
19 | "@vue/cli-plugin-router": "~4.3.0",
20 | "@vue/cli-service": "~4.3.0",
21 | "less": "^3.0.4",
22 | "less-loader": "^5.0.0",
23 | "vue-template-compiler": "^2.6.11"
24 | },
25 | "browserslist": [
26 | "> 1%",
27 | "last 2 versions",
28 | "not dead"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/src/views/About.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | aaa
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/components/AddBlockBtn.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
25 |
26 |
27 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/assets/github.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # DEMO
2 | [all-in-one-kappa.vercel.app/](https://all-in-one-kappa.vercel.app/)
3 |
4 | # 界面
5 | 
6 |
7 |
8 |
9 | # All-in-one是什么
10 | All-in-one 是一个开源的模块化内容构建编辑器,它不同于传统的文本编辑器,所有的内容都是以模块的概念来打造。灵感来自Notion
11 |
12 | ## 灵活的插拔
13 | 所有的模块都以VUE组件的形式编写,可以灵活插拔。你可以用All-in-one编辑器构建一个模块化的内容平台,可以在一个页面里插入任何其他模块,就像Notion一样
14 |
15 | ### 纯净的输出
16 | 所有组件保存的数据,都以Json的形式存储在Vuex里供不同组件调用
17 |
18 |
19 | #### 🐞 由于不是用WYSIWYG的编辑器进行二次开发,目前在文本编辑方面有一些不能解决的Bug
20 |
21 | * 当输入行大于等于2行时,键盘的上下按键没有办法处理光标在同组件的文本内容里上下移动
22 | * 内容无法跨模块复制
23 | * 其他一些小的问题
24 |
25 | #### 👏 已实现的模块
26 | - [x] 纯文本
27 | - [x] 待办清单
28 | - [x] 标题1
29 | - [x] 标题2
30 | - [x] 标题3
31 | - [x] 符号列表
32 | - [x] 提示栏
33 | - [x] 组件的拖拽移动
34 |
35 |
36 | #### 🧑💻 待开发的模块
37 | - [ ] 事件节点组件
38 | - [ ] 图片上传组件
39 | - [ ] 表格组件
40 | - [ ] 看板组件
41 |
42 | ***
43 |
44 | # what is All-in-one
45 | All-in-one is an open source modular content construction editor. It is different from traditional text editors, and all content is built with the concept of modules. Inspired by Notion
46 |
47 | ## Flexible plugging
48 | All modules are written in the form of VUE components, which can be flexibly inserted and removed. You can use the All-in-one editor to build a modular content platform, you can insert any other module in a page, just like Notion
49 |
50 | ### Pure output
51 | The data saved by all components is stored in Vuex in the form of Json for different components to call
52 |
53 |
54 | #### 🐞 Since it is not a secondary development with the WYSIWYG editor, there are currently some unsolvable bugs in text editing
55 |
56 | * When the input line is greater than or equal to 2 lines, the keyboard up and down keys can not handle the cursor to move up and down in the text content of the same component
57 | * Content cannot be copied across modules
58 | * Other minor issues
59 |
60 | #### 👏 Modules has been developed
61 |
62 | - [x] Text
63 | - [x] Todo
64 | - [x] Heading1
65 | - [x] Heading2
66 | - [x] Heading3
67 | - [x] BulletedList
68 | - [x] Hint
69 | - [x] Drag and drop of components
70 |
71 | #### 🧑💻 Modules to be developed
72 |
73 | - [ ] EventNode component
74 | - [ ] Image upload component
75 | - [ ] Form component
76 | - [ ] Kanban components
77 |
--------------------------------------------------------------------------------
/src/vuex/store.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex)
5 |
6 | const state = {
7 | isShowAddMenu: false,
8 | addMenuContentLayerXY: { x: 0, y: 0 },
9 | currentBlockIndex: 0,
10 | currentPageBlocks: [{ "type": "heading1", "data": { "text": "All-in-one 是什么" } }, { "type": "text", "data": { "text": "All-in-one 是一个开源的模块化内容构建编辑器,它不同于传统的文本编辑器,所有的内容都是以模块的概念来打造。灵感来自Notion" } }, { "type": "heading2", "data": { "text": "灵活的插拔" } }, { "type": "text", "data": { "text": "所有的模块都以VUE组件的形式编写,可以灵活插拔。你可以用All-in-one编辑器构建一个模块化的内容平台,可以在一个页面里插入任何其他模块,就像Notion一样" } }, { "type": "heading3", "data": { "text": "纯净的输出" } }, { "type": "text", "data": { "text": "所有组件保存的数据,都以Json的形式存储在Vuex里供不同组件调用" } }, { "type": "text", "data": { "text": "" } }, { "type": "hint", "data": { "text": "🐞由于不是用WYSIWYG的编辑器进行二次开发,目前在文本编辑方面有一些不能解决的Bug" } }, { "type": "text", "data": { "text": "" } }, { "type": "BulletedList", "data": { "text": "当输入行大于等于2行时,键盘的上下按键没有办法处理光标在同组件的文本内容里上下移动" } }, { "type": "BulletedList", "data": { "text": "内容无法跨模块复制" } }, { "type": "BulletedList", "data": { "text": "其他一些小的问题" } }, { "type": "text", "data": { "text": "" } }, { "type": "hint", "data": { "text": "👏 已实现的模块" } }, { "type": "text", "data": { "text": "" } }, { "type": "todo", "data": { "isChecked": true, "text": "纯文本" } }, { "type": "todo", "data": { "isChecked": true, "text": "待办清单" } }, { "type": "todo", "data": { "isChecked": true, "text": "标题1" } }, { "type": "todo", "data": { "isChecked": true, "text": "标题2" } }, { "type": "todo", "data": { "isChecked": true, "text": "标题3" } }, { "type": "todo", "data": { "isChecked": true, "text": "符号列表" } }, { "type": "todo", "data": { "isChecked": true, "text": "提示栏" } }, { "type": "todo", "data": { "isChecked": true, "text": "组件的拖动排序" } }, { "type": "text", "data": { "text": "" } }, { "type": "hint", "data": { "text": "🧑💻待开发的功能清单" } }, { "type": "text", "data": { "text": "" } }, { "type": "todo", "data": { "isChecked": false, "text": " 图片上传组件" } }, { "type": "todo", "data": { "isChecked": false, "text": "事件节点组件" } }, { "type": "todo", "data": { "isChecked": false, "text": "表格组件" } }, { "type": "todo", "data": { "isChecked": false, "text": "看板组件" } }, { "type": "text", "data": { "text": "" } }],
11 | }
12 |
13 | const mutations = {
14 | mutationIsShowAddMenu(state, isShowAddMenu) {
15 | state.isShowAddMenu = isShowAddMenu
16 | },
17 | mutationCurrentBlockIndex(state, index) {
18 | state.currentBlockIndex = index
19 | },
20 | mutationAddMenuContentLayerXY(state, addMenuContentLayerXY) {
21 | state.addMenuContentLayerXY = addMenuContentLayerXY
22 | // state.addMenuContentClientXY = {x:0,y:0}
23 |
24 | },
25 | mutationAddCurrentPageBlocks(state, addBlockInfo) {
26 | let index = addBlockInfo.index + 1
27 | state.currentPageBlocks.splice(index, 0, addBlockInfo.blockItem)
28 | // console.log(state.currentPageBlocks)
29 | }
30 | }
31 |
32 |
33 | const getters = {
34 |
35 | getterCurrentPageBlocks(state) {
36 | return state.currentPageBlocks
37 | },
38 | getterAddMenuContentLayerXY(state) {
39 |
40 | let a = state.addMenuContentLayerXY
41 | let clientHeight = window.innerHeight
42 |
43 | if (a.y > (clientHeight / 2)) {
44 | a.y = a.y - 380
45 | }
46 | a.y = `${a.y + 20}px`
47 | a.x = `${a.x + 48}px`
48 |
49 | // 当前浏览器的高度
50 | return a
51 | }
52 |
53 |
54 | }
55 | export default new Vuex.Store({
56 | state, mutations, getters
57 | })
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/Heading3.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
125 |
126 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/Heading1.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
12 |
13 |
14 |
15 |
130 |
131 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/Heading2.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
129 |
130 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/Hint.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
127 |
128 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/TextBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
151 |
152 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/BulletedList.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | ·
4 |
12 |
13 |
14 |
15 |
150 |
151 |
--------------------------------------------------------------------------------
/src/components/basicBlockComponents/TodoBlock.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
12 |
13 |
14 |
15 |
153 |
154 |
--------------------------------------------------------------------------------
/src/views/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
23 |
24 |
25 |
26 |
27 |
28 |
33 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
129 |
130 |
131 |
201 |
202 |
203 |
--------------------------------------------------------------------------------
/src/components/AddBlockContent.vue:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
28 |
29 |
30 |
31 |
91 |
92 |
93 |
272 |
273 |
274 |
--------------------------------------------------------------------------------