From 0567ec32f842d9bb8761ea09fc55db9c55f42f9d Mon Sep 17 00:00:00 2001
From: xuhuajiao <13476289682@163.com>
Date: Thu, 11 Sep 2025 16:50:20 +0800
Subject: [PATCH] =?UTF-8?q?=E5=AF=8C=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91?=
=?UTF-8?q?=E5=99=A8=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 1 +
src/components/quillEditor/index.vue | 206 +++++++++----
src/components/quillEditor/index2.vue | 374 +++++++++++++++++++++++
src/components/quillEditor/indexlast.vue | 296 ++++++++++++++++++
src/views/inquiryMachine/content.vue | 10 +-
5 files changed, 835 insertions(+), 52 deletions(-)
create mode 100644 src/components/quillEditor/index2.vue
create mode 100644 src/components/quillEditor/indexlast.vue
diff --git a/package.json b/package.json
index c1dd4ea..804db2f 100644
--- a/package.json
+++ b/package.json
@@ -78,6 +78,7 @@
"qrcodejs2": "^0.0.2",
"qs": "^6.10.1",
"quill": "^2.0.0-dev.3",
+ "quill-better-table": "^1.2.10",
"quill-image-resize-module": "^3.0.0",
"screenfull": "4.2.0",
"sm-crypto": "^0.3.2",
diff --git a/src/components/quillEditor/index.vue b/src/components/quillEditor/index.vue
index bc336bc..44d3603 100644
--- a/src/components/quillEditor/index.vue
+++ b/src/components/quillEditor/index.vue
@@ -12,6 +12,10 @@ import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import '@/assets/styles/quillEditor.css'
+import QuillBetterTable from 'quill-better-table'
+import 'quill-better-table/dist/quill-better-table.css'
+Quill.register({ 'modules/better-table': QuillBetterTable }, true)
+
var fonts = [
'SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'sans-serif'
]
@@ -56,6 +60,31 @@ const titleConfig = {
'ql-table-delete-column': '删除列'
}
+// better-table配置
+const betterTable = {
+ // 右键菜单
+ operationMenu: {
+ items: {
+ insertColumnRight: { text: '右边插入一列' },
+ insertColumnLeft: { text: '左边插入一列' },
+ insertRowUp: { text: '上边插入一行' },
+ insertRowDown: { text: '下边插入一行' },
+ mergeCells: { text: '合并单元格' },
+ unmergeCells: { text: '拆分单元格' },
+ deleteColumn: { text: '删除列' },
+ deleteRow: { text: '删除行' },
+ deleteTable: { text: '删除表格' }
+ },
+ background: {
+ color: '#333'
+ },
+ color: {
+ colors: ['green', 'red', 'yellow', 'blue', 'white', '#558ff2', '#595959', '#9fd9c5'],
+ text: '背景色:'
+ }
+ }
+}
+
export default {
name: 'Editor',
props: {
@@ -84,13 +113,14 @@ export default {
[{ align: [] }],
['link', 'image'],
['clean'],
- [
- { table: 'TD' },
- { 'table-insert-row': 'TIR' },
- { 'table-insert-column': 'TIC' },
- { 'table-delete-row': 'TDR' },
- { 'table-delete-column': 'TDC' }
- ]
+ ['table']
+ // [
+ // { table: 'TD' },
+ // { 'table-insert-row': 'TIR' },
+ // { 'table-insert-column': 'TIC' },
+ // { 'table-delete-row': 'TDR' },
+ // { 'table-delete-column': 'TDC' }
+ // ]
],
handlers: {
image: function(value) {
@@ -135,24 +165,37 @@ export default {
this.quill.format('image', false)
}
},
- table: function(val) {
- this.quill.getModule('table').insertTable(2, 3)
- },
- 'table-insert-row': function() {
- this.quill.getModule('table').insertRowBelow()
- },
- 'table-insert-column': function() {
- this.quill.getModule('table').insertColumnRight()
- },
- 'table-delete-row': function() {
- this.quill.getModule('table').deleteRow()
- },
- 'table-delete-column': function() {
- this.quill.getModule('table').deleteColumn()
+ table: function() {
+ // this.quill.getModule('better-table').insertTable(3, 4)
+ // 确保模块已加载
+ if (this.quill.getModule('better-table')) {
+ this.quill.getModule('better-table').insertTable(3, 4)
+ } else {
+ console.error('better-table模块未正确加载')
+ }
}
+ // table: function(val) {
+ // this.quill.getModule('table').insertTable(2, 3)
+ // },
+ // 'table-insert-row': function() {
+ // this.quill.getModule('table').insertRowBelow()
+ // },
+ // 'table-insert-column': function() {
+ // this.quill.getModule('table').insertColumnRight()
+ // },
+ // 'table-delete-row': function() {
+ // this.quill.getModule('table').deleteRow()
+ // },
+ // 'table-delete-column': function() {
+ // this.quill.getModule('table').deleteColumn()
+ // }
}
},
- table: true
+ table: false,
+ 'better-table': betterTable,
+ keyboard: {
+ bindings: QuillBetterTable.keyboardBindings
+ }
},
placeholder: ''
},
@@ -161,48 +204,61 @@ export default {
},
watch: {
value(newVal) {
- if (newVal === this.quill.root.innerHTML) return
- this.quill.setContents([])
- this.quill.clipboard.dangerouslyPasteHTML(0, newVal)
+ // if (newVal === this.quill.root.innerHTML) return
+ // this.quill.setContents([])
+ // this.quill.clipboard.dangerouslyPasteHTML(0, newVal)
+ if (newVal === this.quill?.root.innerHTML) return
+ // 优化:先清除内容再粘贴新内容
+ if (this.quill) {
+ this.quill.deleteText(0, this.quill.getLength())
+ this.quill.clipboard.dangerouslyPasteHTML(0, newVal || '')
+ }
}
},
+ // 关键:组件销毁时清理Quill实例和残留DOM
+ beforeDestroy() {
+ this.destroyEditor()
+ },
mounted() {
- const dom = this.$refs.editorContainer
- this.quill = new Quill(dom, this.options)
+ this.initEditor()
+ // const dom = this.$refs.editorContainer
+ // this.quill = new Quill(dom, this.options)
- if (this.value) {
- this.quill.clipboard.dangerouslyPasteHTML(this.value)
- }
+ // if (this.value) {
+ // this.quill.clipboard.dangerouslyPasteHTML(this.value)
+ // }
- // 监听内容变化并发射事件
+ // // 监听内容变化并发射事件
// this.quill.on('text-change', () => {
// const content = this.quill.root.innerHTML
- // console.log('content', content)
+ // // console.log('content', content)
// // this.$emit('input', content)
- // // this.$emit('contentData', content)
+ // this.$emit('contentData', content)
// })
- // 设置表格相关图标
- this.$el.querySelector('.ql-table-insert-row').innerHTML =
- ``
+ // this.addQuillTitle()
+ },
+ methods: {
+ // 初始化编辑器
+ initEditor() {
+ const dom = this.$refs.editorContainer
+ if (!dom) return
- this.$el.querySelector('.ql-table-insert-column').innerHTML =
- ``
+ this.$nextTick(() => {
+ this.quill = new Quill(dom, this.options)
- this.$el.querySelector('.ql-table-delete-row').innerHTML =
- ``
+ if (this.value) {
+ this.quill.clipboard.dangerouslyPasteHTML(this.value)
+ }
- this.$el.querySelector('.ql-table-delete-column').innerHTML =
- ``
+ this.quill.on('text-change', () => {
+ const content = this.quill.root.innerHTML
+ this.$emit('contentData', content)
+ })
- this.addQuillTitle()
- },
- // activated() {
- // if (this.value && this.quill) {
- // this.quill.clipboard.dangerouslyPasteHTML(this.value)
- // }
- // },
- methods: {
+ this.addQuillTitle()
+ })
+ },
addQuillTitle() {
const oToolBar = document.querySelector('.ql-toolbar')
const aButton = oToolBar.querySelectorAll('button')
@@ -222,6 +278,35 @@ export default {
item.parentNode.title = titleConfig[item.classList[0]]
})
},
+ // 销毁编辑器实例
+ destroyEditor() {
+ if (this.quill) {
+ // 1. 移除事件监听
+ this.quill.off('text-change')
+
+ // 2. 清除编辑器内容
+ this.quill.deleteText(0, this.quill.getLength())
+
+ // 3. 销毁表格模块相关的DOM和事件
+ const tableModule = this.quill.getModule('better-table')
+ if (tableModule && tableModule.destroy) {
+ tableModule.destroy()
+ }
+
+ // 4. 移除编辑器容器内容
+ const container = this.$refs.editorContainer
+ if (container) {
+ container.innerHTML = ''
+ }
+
+ // 5. 释放实例引用
+ this.quill = null
+ }
+
+ // 6. 清除可能残留的表格操作菜单
+ const residualMenus = document.querySelectorAll('.qlbt-operation-menu, .quill-better-table')
+ residualMenus.forEach(menu => menu.remove())
+ },
getHtmlContent() {
return this.quill.root.innerHTML
},
@@ -232,5 +317,24 @@ export default {
}
-
diff --git a/src/components/quillEditor/index2.vue b/src/components/quillEditor/index2.vue
new file mode 100644
index 0000000..987876a
--- /dev/null
+++ b/src/components/quillEditor/index2.vue
@@ -0,0 +1,374 @@
+
+