Переглянути джерело

feat(editor): 添加富文本编辑器组件并更新相关依赖

添加基于Vue-Quill的富文本编辑器组件,支持基本文本格式和图片插入
更新package.json添加vue-quill、quill等依赖
配置vue.config.js解决stream和util的polyfill问题
优化App.vue布局样式并集成编辑器组件
YourName 3 тижнів тому
батько
коміт
de630800c6
5 змінених файлів з 527 додано та 64 видалено
  1. 445 27
      package-lock.json
  2. 4 0
      package.json
  3. 20 36
      src/App.vue
  4. 49 0
      src/components/Editor.vue
  5. 9 1
      vue.config.js

+ 445 - 27
package-lock.json

@@ -8,9 +8,13 @@
       "name": "epub-build",
       "version": "0.1.0",
       "dependencies": {
+        "@vueup/vue-quill": "^1.2.0",
         "core-js": "^3.8.3",
         "element-plus": "^2.10.4",
         "epubjs": "^0.3.93",
+        "quill": "^2.0.3",
+        "stream-browserify": "^3.0.0",
+        "util": "^0.12.5",
         "vue": "^3.2.13"
       },
       "devDependencies": {
@@ -3018,6 +3022,91 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/@vueup/vue-quill": {
+      "version": "1.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/@vueup/vue-quill/-/vue-quill-1.2.0.tgz",
+      "integrity": "sha512-kd5QPSHMDpycklojPXno2Kw2JSiKMYduKYQckTm1RJoVDA557MnyUXgcuuDpry4HY/Rny9nGNcK+m3AHk94wag==",
+      "license": "MIT",
+      "dependencies": {
+        "quill": "^1.3.7",
+        "quill-delta": "^4.2.2"
+      },
+      "peerDependencies": {
+        "vue": "^3.2.41"
+      }
+    },
+    "node_modules/@vueup/vue-quill/node_modules/clone": {
+      "version": "2.1.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=0.8"
+      }
+    },
+    "node_modules/@vueup/vue-quill/node_modules/eventemitter3": {
+      "version": "2.0.3",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/eventemitter3/-/eventemitter3-2.0.3.tgz",
+      "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==",
+      "license": "MIT"
+    },
+    "node_modules/@vueup/vue-quill/node_modules/fast-diff": {
+      "version": "1.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/fast-diff/-/fast-diff-1.2.0.tgz",
+      "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@vueup/vue-quill/node_modules/parchment": {
+      "version": "1.1.4",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/parchment/-/parchment-1.1.4.tgz",
+      "integrity": "sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==",
+      "license": "BSD-3-Clause"
+    },
+    "node_modules/@vueup/vue-quill/node_modules/quill": {
+      "version": "1.3.7",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/quill/-/quill-1.3.7.tgz",
+      "integrity": "sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "clone": "^2.1.1",
+        "deep-equal": "^1.0.1",
+        "eventemitter3": "^2.0.3",
+        "extend": "^3.0.2",
+        "parchment": "^1.1.4",
+        "quill-delta": "^3.6.2"
+      }
+    },
+    "node_modules/@vueup/vue-quill/node_modules/quill-delta": {
+      "version": "4.2.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/quill-delta/-/quill-delta-4.2.2.tgz",
+      "integrity": "sha512-qjbn82b/yJzOjstBgkhtBjN2TNK+ZHP/BgUQO+j6bRhWQQdmj2lH6hXG7+nwwLF41Xgn//7/83lxs9n2BkTtTg==",
+      "license": "MIT",
+      "dependencies": {
+        "fast-diff": "1.2.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.isequal": "^4.5.0"
+      }
+    },
+    "node_modules/@vueup/vue-quill/node_modules/quill/node_modules/fast-diff": {
+      "version": "1.1.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/fast-diff/-/fast-diff-1.1.2.tgz",
+      "integrity": "sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==",
+      "license": "Apache-2.0"
+    },
+    "node_modules/@vueup/vue-quill/node_modules/quill/node_modules/quill-delta": {
+      "version": "3.6.3",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/quill-delta/-/quill-delta-3.6.3.tgz",
+      "integrity": "sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==",
+      "license": "MIT",
+      "dependencies": {
+        "deep-equal": "^1.0.1",
+        "extend": "^3.0.2",
+        "fast-diff": "1.1.2"
+      },
+      "engines": {
+        "node": ">=0.10"
+      }
+    },
     "node_modules/@vueuse/core": {
       "version": "9.13.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/@vueuse/core/-/core-9.13.0.tgz",
@@ -3642,6 +3731,21 @@
         "postcss": "^8.1.0"
       }
     },
+    "node_modules/available-typed-arrays": {
+      "version": "1.0.7",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
+      "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
+      "license": "MIT",
+      "dependencies": {
+        "possible-typed-array-names": "^1.0.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/babel-loader": {
       "version": "8.4.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/babel-loader/-/babel-loader-8.4.1.tgz",
@@ -3969,7 +4073,6 @@
       "version": "1.0.8",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/call-bind/-/call-bind-1.0.8.tgz",
       "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.0",
@@ -3988,7 +4091,6 @@
       "version": "1.0.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
       "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-errors": "^1.3.0",
@@ -4002,7 +4104,6 @@
       "version": "1.0.4",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/call-bound/-/call-bound-1.0.4.tgz",
       "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.2",
@@ -4946,6 +5047,26 @@
         }
       }
     },
+    "node_modules/deep-equal": {
+      "version": "1.1.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/deep-equal/-/deep-equal-1.1.2.tgz",
+      "integrity": "sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==",
+      "license": "MIT",
+      "dependencies": {
+        "is-arguments": "^1.1.1",
+        "is-date-object": "^1.0.5",
+        "is-regex": "^1.1.4",
+        "object-is": "^1.1.5",
+        "object-keys": "^1.1.1",
+        "regexp.prototype.flags": "^1.5.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/deep-is/-/deep-is-0.1.4.tgz",
@@ -5056,7 +5177,6 @@
       "version": "1.1.4",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/define-data-property/-/define-data-property-1.1.4.tgz",
       "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-define-property": "^1.0.0",
@@ -5084,7 +5204,6 @@
       "version": "1.2.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/define-properties/-/define-properties-1.2.1.tgz",
       "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "define-data-property": "^1.0.1",
@@ -5276,7 +5395,6 @@
       "version": "1.0.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/dunder-proto/-/dunder-proto-1.0.1.tgz",
       "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.1",
@@ -5462,7 +5580,6 @@
       "version": "1.0.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/es-define-property/-/es-define-property-1.0.1.tgz",
       "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -5472,7 +5589,6 @@
       "version": "1.3.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/es-errors/-/es-errors-1.3.0.tgz",
       "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -5489,7 +5605,6 @@
       "version": "1.1.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
       "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-errors": "^1.3.0"
@@ -6257,6 +6372,12 @@
         "type": "^2.7.2"
       }
     },
+    "node_modules/extend": {
+      "version": "3.0.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+      "license": "MIT"
+    },
     "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6264,6 +6385,12 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/fast-diff": {
+      "version": "1.3.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/fast-diff/-/fast-diff-1.3.0.tgz",
+      "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
+      "license": "Apache-2.0"
+    },
     "node_modules/fast-glob": {
       "version": "3.3.3",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/fast-glob/-/fast-glob-3.3.3.tgz",
@@ -6518,6 +6645,21 @@
         }
       }
     },
+    "node_modules/for-each": {
+      "version": "0.3.5",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/for-each/-/for-each-0.3.5.tgz",
+      "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
+      "license": "MIT",
+      "dependencies": {
+        "is-callable": "^1.2.7"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/forwarded": {
       "version": "0.2.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/forwarded/-/forwarded-0.2.0.tgz",
@@ -6586,7 +6728,6 @@
       "version": "1.1.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/function-bind/-/function-bind-1.1.2.tgz",
       "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
-      "dev": true,
       "license": "MIT",
       "funding": {
         "url": "https://github.com/sponsors/ljharb"
@@ -6599,6 +6740,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/functions-have-names": {
+      "version": "1.2.3",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/functions-have-names/-/functions-have-names-1.2.3.tgz",
+      "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -6623,7 +6773,6 @@
       "version": "1.3.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
       "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "call-bind-apply-helpers": "^1.0.2",
@@ -6648,7 +6797,6 @@
       "version": "1.0.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/get-proto/-/get-proto-1.0.1.tgz",
       "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "dunder-proto": "^1.0.1",
@@ -6764,7 +6912,6 @@
       "version": "1.2.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/gopd/-/gopd-1.2.0.tgz",
       "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -6817,7 +6964,6 @@
       "version": "1.0.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
       "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "es-define-property": "^1.0.0"
@@ -6830,7 +6976,6 @@
       "version": "1.1.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/has-symbols/-/has-symbols-1.1.0.tgz",
       "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -6839,6 +6984,21 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/has-tostringtag": {
+      "version": "1.0.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+      "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+      "license": "MIT",
+      "dependencies": {
+        "has-symbols": "^1.0.3"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/hash-sum": {
       "version": "2.0.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/hash-sum/-/hash-sum-2.0.0.tgz",
@@ -6850,7 +7010,6 @@
       "version": "2.0.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/hasown/-/hasown-2.0.2.tgz",
       "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "function-bind": "^1.1.2"
@@ -7250,6 +7409,22 @@
         "node": ">= 10"
       }
     },
+    "node_modules/is-arguments": {
+      "version": "1.2.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-arguments/-/is-arguments-1.2.0.tgz",
+      "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-arrayish": {
       "version": "0.2.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -7270,6 +7445,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-callable": {
+      "version": "1.2.7",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-callable/-/is-callable-1.2.7.tgz",
+      "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-ci": {
       "version": "1.2.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-ci/-/is-ci-1.2.1.tgz",
@@ -7299,6 +7486,22 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/is-date-object": {
+      "version": "1.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-date-object/-/is-date-object-1.1.0.tgz",
+      "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-docker": {
       "version": "2.2.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-docker/-/is-docker-2.2.1.tgz",
@@ -7345,6 +7548,24 @@
         "node": ">=8"
       }
     },
+    "node_modules/is-generator-function": {
+      "version": "1.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-generator-function/-/is-generator-function-1.1.0.tgz",
+      "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.3",
+        "get-proto": "^1.0.0",
+        "has-tostringtag": "^1.0.2",
+        "safe-regex-test": "^1.1.0"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-glob/-/is-glob-4.0.3.tgz",
@@ -7404,6 +7625,24 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-regex": {
+      "version": "1.2.1",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-regex/-/is-regex-1.2.1.tgz",
+      "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2",
+        "hasown": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-stream": {
       "version": "1.1.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-stream/-/is-stream-1.1.0.tgz",
@@ -7414,6 +7653,21 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/is-typed-array": {
+      "version": "1.1.15",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-typed-array/-/is-typed-array-1.1.15.tgz",
+      "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
+      "license": "MIT",
+      "dependencies": {
+        "which-typed-array": "^1.1.16"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/is-unicode-supported": {
       "version": "0.1.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
@@ -7845,6 +8099,12 @@
         "lodash-es": "*"
       }
     },
+    "node_modules/lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
+      "license": "MIT"
+    },
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
@@ -7859,6 +8119,13 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/lodash.isequal": {
+      "version": "4.5.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+      "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
+      "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.",
+      "license": "MIT"
+    },
     "node_modules/lodash.kebabcase": {
       "version": "4.1.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
@@ -8116,7 +8383,6 @@
       "version": "1.1.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
       "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -8668,11 +8934,26 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/object-is": {
+      "version": "1.1.6",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/object-is/-/object-is-1.1.6.tgz",
+      "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.7",
+        "define-properties": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/object-keys": {
       "version": "1.1.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/object-keys/-/object-keys-1.1.1.tgz",
       "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">= 0.4"
@@ -8922,6 +9203,12 @@
         "tslib": "^2.0.3"
       }
     },
+    "node_modules/parchment": {
+      "version": "3.0.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/parchment/-/parchment-3.0.0.tgz",
+      "integrity": "sha512-HUrJFQ/StvgmXRcQ1ftY6VEZUq3jA2t9ncFN4F84J/vN0/FPpQF+8FKXb3l6fLces6q0uOHj6NJn+2xvZnxO6A==",
+      "license": "BSD-3-Clause"
+    },
     "node_modules/parent-module": {
       "version": "1.0.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/parent-module/-/parent-module-1.0.1.tgz",
@@ -9105,6 +9392,15 @@
         "node": ">= 10.12"
       }
     },
+    "node_modules/possible-typed-array-names": {
+      "version": "1.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+      "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.5.6",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/postcss/-/postcss-8.5.6.tgz",
@@ -9952,6 +10248,41 @@
       ],
       "license": "MIT"
     },
+    "node_modules/quill": {
+      "version": "2.0.3",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/quill/-/quill-2.0.3.tgz",
+      "integrity": "sha512-xEYQBqfYx/sfb33VJiKnSJp8ehloavImQ2A6564GAbqG55PGw1dAWUn1MUbQB62t0azawUS2CZZhWCjO8gRvTw==",
+      "license": "BSD-3-Clause",
+      "dependencies": {
+        "eventemitter3": "^5.0.1",
+        "lodash-es": "^4.17.21",
+        "parchment": "^3.0.0",
+        "quill-delta": "^5.1.0"
+      },
+      "engines": {
+        "npm": ">=8.2.3"
+      }
+    },
+    "node_modules/quill-delta": {
+      "version": "5.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/quill-delta/-/quill-delta-5.1.0.tgz",
+      "integrity": "sha512-X74oCeRI4/p0ucjb5Ma8adTXd9Scumz367kkMK5V/IatcX6A0vlgLgKbzXWy5nZmCGeNJm2oQX0d2Eqj+ZIlCA==",
+      "license": "MIT",
+      "dependencies": {
+        "fast-diff": "^1.3.0",
+        "lodash.clonedeep": "^4.5.0",
+        "lodash.isequal": "^4.5.0"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      }
+    },
+    "node_modules/quill/node_modules/eventemitter3": {
+      "version": "5.0.1",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/eventemitter3/-/eventemitter3-5.0.1.tgz",
+      "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
+      "license": "MIT"
+    },
     "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/randombytes/-/randombytes-2.1.0.tgz",
@@ -10046,7 +10377,6 @@
       "version": "3.6.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/readable-stream/-/readable-stream-3.6.2.tgz",
       "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "inherits": "^2.0.3",
@@ -10090,6 +10420,26 @@
         "node": ">=4"
       }
     },
+    "node_modules/regexp.prototype.flags": {
+      "version": "1.5.4",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+      "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bind": "^1.0.8",
+        "define-properties": "^1.2.1",
+        "es-errors": "^1.3.0",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "set-function-name": "^2.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/regexpp": {
       "version": "3.2.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/regexpp/-/regexpp-3.2.0.tgz",
@@ -10316,7 +10666,6 @@
       "version": "5.2.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/safe-buffer/-/safe-buffer-5.2.1.tgz",
       "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -10333,6 +10682,23 @@
       ],
       "license": "MIT"
     },
+    "node_modules/safe-regex-test": {
+      "version": "1.1.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+      "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+      "license": "MIT",
+      "dependencies": {
+        "call-bound": "^1.0.2",
+        "es-errors": "^1.3.0",
+        "is-regex": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/safer-buffer": {
       "version": "2.1.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/safer-buffer/-/safer-buffer-2.1.2.tgz",
@@ -10558,7 +10924,6 @@
       "version": "1.2.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/set-function-length/-/set-function-length-1.2.2.tgz",
       "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "define-data-property": "^1.1.4",
@@ -10572,6 +10937,21 @@
         "node": ">= 0.4"
       }
     },
+    "node_modules/set-function-name": {
+      "version": "2.0.2",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/set-function-name/-/set-function-name-2.0.2.tgz",
+      "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==",
+      "license": "MIT",
+      "dependencies": {
+        "define-data-property": "^1.1.4",
+        "es-errors": "^1.3.0",
+        "functions-have-names": "^1.2.3",
+        "has-property-descriptors": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      }
+    },
     "node_modules/setimmediate": {
       "version": "1.0.5",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/setimmediate/-/setimmediate-1.0.5.tgz",
@@ -10915,11 +11295,20 @@
         "node": ">= 0.8"
       }
     },
+    "node_modules/stream-browserify": {
+      "version": "3.0.0",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/stream-browserify/-/stream-browserify-3.0.0.tgz",
+      "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "~2.0.4",
+        "readable-stream": "^3.5.0"
+      }
+    },
     "node_modules/string_decoder": {
       "version": "1.3.0",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/string_decoder/-/string_decoder-1.3.0.tgz",
       "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "safe-buffer": "~5.2.0"
@@ -11539,6 +11928,19 @@
         "punycode": "^2.1.0"
       }
     },
+    "node_modules/util": {
+      "version": "0.12.5",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/util/-/util-0.12.5.tgz",
+      "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
+      "license": "MIT",
+      "dependencies": {
+        "inherits": "^2.0.3",
+        "is-arguments": "^1.0.4",
+        "is-generator-function": "^1.0.7",
+        "is-typed-array": "^1.1.3",
+        "which-typed-array": "^1.1.2"
+      }
+    },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -12166,11 +12568,6 @@
         "node": ">=10.0.0"
       }
     },
-    "node_modules/webpack-sources": {
-      "dev": true,
-      "optional": true,
-      "peer": true
-    },
     "node_modules/webpack-virtual-modules": {
       "version": "0.4.6",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz",
@@ -12311,6 +12708,27 @@
         "node": ">= 8"
       }
     },
+    "node_modules/which-typed-array": {
+      "version": "1.1.19",
+      "resolved": "https://mirrors.huaweicloud.com/repository/npm/which-typed-array/-/which-typed-array-1.1.19.tgz",
+      "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
+      "license": "MIT",
+      "dependencies": {
+        "available-typed-arrays": "^1.0.7",
+        "call-bind": "^1.0.8",
+        "call-bound": "^1.0.4",
+        "for-each": "^0.3.5",
+        "get-proto": "^1.0.1",
+        "gopd": "^1.2.0",
+        "has-tostringtag": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 0.4"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
+    },
     "node_modules/wildcard": {
       "version": "2.0.1",
       "resolved": "https://mirrors.huaweicloud.com/repository/npm/wildcard/-/wildcard-2.0.1.tgz",

+ 4 - 0
package.json

@@ -8,9 +8,13 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@vueup/vue-quill": "^1.2.0",
     "core-js": "^3.8.3",
     "element-plus": "^2.10.4",
     "epubjs": "^0.3.93",
+    "quill": "^2.0.3",
+    "stream-browserify": "^3.0.0",
+    "util": "^0.12.5",
     "vue": "^3.2.13"
   },
   "devDependencies": {

+ 20 - 36
src/App.vue

@@ -1,8 +1,13 @@
+<script setup>
+import Editor from './components/Editor.vue'
+</script>
+
 <template>
   <div class="container">
     <el-card class="chapter-panel" shadow="never">
       <template #header>
-        <div class="panel-header">
+        <div class="panel-title">
+          <el-icon><Notebook /></el-icon>
           <span>书籍章节列表</span>
         </div>
       </template>
@@ -11,69 +16,48 @@
 
     <el-card class="content-panel" shadow="never">
       <template #header>
-        <div class="panel-header">
+        <div class="panel-title">
+          <el-icon><Document /></el-icon>
           <span>当前章节内容</span>
         </div>
       </template>
-      <div class="placeholder-text">请从左侧选择章节</div>
+      <Editor />
     </el-card>
   </div>
 </template>
 
 <style scoped>
-*{
-  margin: 0;
-  padding: 0;
-}
 .container {
   height: 98vh;
-  box-sizing: border-box;
   display: flex;
-  flex-direction: row;
-  flex-wrap: nowrap;
-}
-
-.placeholder-text {
-  height: calc(100% - 80px);
-  flex: 0 0 300px;
-  overflow-y: auto;
+  gap: 20px;
+  padding: 20px;
+  box-sizing: border-box;
 }
 
 .chapter-panel {
   flex: 0 0 20vw;
-  overflow: hidden;
 }
 
 .content-panel {
   flex: 1;
-  overflow: hidden;
-}
-
-.chapter-panel {
-  flex: 0 0 20vw;
-}
-
-.content-panel {
-  flex: 0 0 78vw;
-  margin-left: 1vw;
 }
 
-.el-card__body {
-  width: calc(100% - 1px);
-  height: calc(100% - 57px);
-  overflow: auto;
-}
-
-.panel-header {
+.panel-title {
   display: flex;
   align-items: center;
   gap: 8px;
-  font-weight: 500;
+  font-size: 16px;
+}
+
+.content-panel :deep(.el-card__body) {
+  padding: 0;
+  height: calc(100% - 57px);
 }
 
 .placeholder-text {
   color: #909399;
+  padding: 20px;
   text-align: center;
-  padding: 40px 0;
 }
 </style>

+ 49 - 0
src/components/Editor.vue

@@ -0,0 +1,49 @@
+<!-- eslint-disable vue/multi-word-component-names -->
+<template>
+  <div class="editor-container">
+    <QuillEditor
+      v-model:content="content"
+      :options="editorOptions"
+      class="editor"
+    />
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { QuillEditor } from '@vueup/vue-quill';
+import '@vueup/vue-quill/dist/vue-quill.snow.css';
+
+const content = ref('<p>请输入章节内容...</p>');
+const editorOptions = {
+  theme: 'snow',
+  modules: {
+    toolbar: [
+      ['bold', 'italic', 'underline', 'strike'],
+      [{ 'header': [1, 2, 3, false] }],
+      [{ 'list': 'ordered'}, { 'list': 'bullet' }],
+      ['link', 'image']
+    ]
+  }
+};
+</script>
+
+<style scoped>
+.editor-container {
+  height: 100%;
+  min-height: 500px;
+  display: flex;
+  flex-direction: column;
+}
+
+.editor {
+  flex: 1;
+  border: 1px solid #e5e7eb;
+  border-radius: 4px;
+  min-height: 400px;
+}
+
+.ql-container {
+  height: 100% !important;
+}
+</style>

+ 9 - 1
vue.config.js

@@ -1,4 +1,12 @@
 const { defineConfig } = require('@vue/cli-service')
 module.exports = defineConfig({
-  transpileDependencies: true
+  transpileDependencies: true,
+  configureWebpack: {
+    resolve: {
+      fallback: {
+        "util": require.resolve("util/"),
+        "stream": require.resolve("stream-browserify")
+      }
+    }
+  }
 })