1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
| <script setup lang="ts">
| import Quill from 'quill'
| import { useTemplateRef } from 'vue'
| import 'quill/dist/quill.snow.css'
|
| defineOptions({
| name: 'RichTextEditor',
| })
|
| const { disabled } = defineProps<Props>()
| interface Props {
| disabled?: boolean
| }
| const model = defineModel<string>()
|
| let editorInst = null
|
| const editorModel = ref<string>()
|
| onMounted(() => {
| initEditor()
| })
|
| const editorRef = useTemplateRef<HTMLElement>('editorRef')
| function initEditor() {
| const options = {
| modules: {
| toolbar: [
| { header: [1, 2, 3, 4, 5, 6, false] }, // 标题
| 'bold', // 加粗
| 'italic', // 斜体
| 'strike', // 删除线
| { size: ['small', false, 'large', 'huge'] }, // 字体大小
| { font: [] }, // 字体种类
| { color: [] }, // 字体颜色、
| { background: [] }, // 字体背景颜色
| 'link', // 插入链接
| 'image', // 插入图片
| 'blockquote', // 引用
| 'link', // 超链接
| 'image', // 插入图片
| 'video', // 插入视频
| { list: 'bullet' }, // 无序列表
| { list: 'ordered' }, // 有序列表
| { script: 'sub' }, // 下标
| { script: 'super' }, // 上标
| { align: [] }, // 对齐方式
| 'formula', // 公式
| 'clean', // remove formatting button
| ],
| },
|
| placeholder: 'Insert text here ...',
| theme: 'snow',
| }
| const quill = new Quill(editorRef.value!, options)
|
| quill.on('text-change', (_delta, _oldDelta, _source) => {
| editorModel.value = quill.getSemanticHTML()
| })
|
| if (disabled)
| quill.enable(false)
|
| editorInst = quill
|
| if (model.value)
| setContents(model.value)
| }
|
| function setContents(html: string) {
| editorInst!.setContents(editorInst!.clipboard.convert({ html }))
| }
|
| watch(
| () => model.value,
| (newValue, _oldValue) => {
| if (newValue && newValue !== editorModel.value) {
| setContents(newValue)
| }
| else if (!newValue) {
| setContents('')
| }
| },
| )
|
| watch(editorModel, (newValue, oldValue) => {
| if (newValue && newValue !== oldValue)
| model.value = newValue
|
| else if (!newValue)
| editorInst!.setContents([])
| })
|
| watch(
| () => disabled,
| (newValue, _oldValue) => {
| editorInst!.enable(!newValue)
| },
| )
|
| onBeforeUnmount(() => editorInst = null)
| </script>
|
| <template>
| <div ref="editorRef" />
| </template>
|
|