VueQuill富文本编辑器使用

注意我这边基于java后端

VueQuill官网

VueQuill服务文本编辑器是基于Vue的,最好先安装vue3。具体怎么安装看vue官网。

我这里是基于vue组件的格式写的。

安装VueQuill

1
2
3
npm install @vueup/vue-quill@latest --save
# OR
yarn add @vueup/vue-quill@latest

Editor.vue

直接上代码。css不用管,就是弄点能看的样式。

解释全在代码中,有注释

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<script setup lang="js">
import {QuillEditor} from '@vueup/vue-quill';
import '@vueup/vue-quill/dist/vue-quill.snow.css';
import ImageUploader from 'quill-image-uploader';
import {ref} from 'vue';
import {ElMessage} from "element-plus";
import request from "../../../utils/request.ts";

const quillRef = ref(null);

const modules = ref({
name: 'imageUploader',
module: ImageUploader,
options: {
upload: (file) => {
//这个就是你传入的文件
console.log(file);
const formData = new FormData();
formData.append('img', file);

//这里是你后端处理逻辑,比如我用的oss,你传给后端处理,返回给前端url就可以了
return request.post('/upload', formData)
.then((res) => {
//res被处理过,我的request封装过axios,本质就是axios.post
/*
res取到后端数据需要res.data.你后端封装的响应体
我这边接到的是res.data.data
但是我这边axios返回值处理过,只需要res.data;如果你要用需要res.data.data
*/
console.log(res);
// 假设 res.data.url 是返回的图片 URL
const imageUrl = res.data;

//这里如果直接return imageUrl也能用,只是图片很大


// 获取Quill实例
const quill = quillRef.value.getQuill();
// 插入图片并设置样式
const range = quill.getSelection();
quill.insertEmbed(range.index, 'image', imageUrl, 'user');
// 获取插入的图片元素并设置样式
const img = document.querySelector('.ql-editor img');
if (img) {
//根据需要改这部分大小就可以了
img.style.width = '100px'; // 设置图片宽度
img.style.height = 'auto'; // 保持图片比例
}
//必须返回url,否则图片不显示
return imageUrl;
})
.catch((err) => {
console.error('Error:', err);
throw err; // 抛出错误
});
},
},
});

const content = ref('');
// 清空编辑器内容
const clearEditor = () => {
content.value = ''; // 清空绑定的数据
if (quillRef.value) {
const quill = quillRef.value.getQuill(); // 获取 Quill 实例
quill.setContents([]); // 清空编辑器内容
}
};
const submit = () => {
console.log(content.value);
// 发送请求
request.post('/submit', {content: content.value})
.then((res) => {
console.log(res.msg);
}).catch((e) => {
ElMessage.error('提交失败:', e);
})
}


</script>

<template>
<div class="common-layout">
<div class="header" style="padding: 1% 1% 1% 1%">
<span><el-text type="primary" size="large" >投稿</el-text></span>
<!-- <div class="extra">
<el-button type="primary" @click="dialogVisible = true; title = '添加分类'">添加分类</el-button>
</div>-->
</div>
<el-container>
<el-container style="">
<el-container>
<el-main style="height: auto">
<div class="editor-container">
<QuillEditor
ref="quillRef"
toolbar="full"
:modules="modules"
v-model:content="content"
contentType="html"
/>
</div>
<!--这个是预览部分,专门弄过来看的-->
<div class="preview-container">
<div v-html="content"></div>
</div>
</el-main>
<el-footer>
<el-button type="danger" @click="submit">提交</el-button>

<el-button type="danger" @click="clearEditor">清空</el-button>
</el-footer>
</el-container>
</el-container>
</el-container>
</div>
</template>


<style scoped>
html, body {
height: 100%;
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
}

.common-layout {
min-height: 100%;
box-sizing: border-box;
height: 100%;
display: flex;
flex-direction: column;
background-color: rgba(240, 240, 240, 0.8); /* 浅色背景,透明度为0.8 */
}

.el-container {
flex: 1;
display: flex;
}

.el-header {
background-color: rgba(26, 26, 26, 0.8); /* 深色背景,透明度为0.8 */
color: white;
text-align: center;
line-height: 60px;
padding: 0 20px;
}

.el-header .mx-1 {
margin: 0 10px;
}

.el-aside {
background-color: rgba(211, 220, 230, 0.8); /* 浅色背景,透明度为0.8 */
color: #333;
text-align: center;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}

.el-aside div {
background-image: url('/imgs/丛雨.jpg');
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: red;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.el-main {
background-color: rgba(233, 238, 243, 0.8); /* 浅色背景,透明度为0.8 */
color: #333;
padding: 20px;
flex: 1;
display: flex;
justify-content: space-between;
align-items: flex-start;
}

.el-main .editor-container, .el-main .preview-container {
width: 48%; /* 使两个容器各占一半宽度 */
box-sizing: border-box;
}

.el-main .editor-container .ql-editor {
min-height: 500px; /* 设置编辑器的最小高度 */
border: 1px solid #ccc;
border-radius: 8px;
padding: 10px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.el-main .preview-container {
border: 1px solid #1a1a1a;
padding: 20px;
border-radius: 8px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
height: 100%;
overflow-y: auto; /* 添加滚动条 */
}

.el-footer {
background-color: rgba(179, 192, 209, 0.8); /* 浅色背景,透明度为0.8 */
color: #333;
text-align: center;
line-height: 60px;
padding: 0 20px;
}

.preview-container >>> img {
width: 300px;
height: auto;
}

.header {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>

图片