在 Nuxt 3.9 使用 Quill 建立文字編輯器

做法

安裝套件。

1
npm install @vueup/vue-quill@latest

plugins 資料夾建立 quill.client.js 檔。

1
2
3
4
5
6
import { QuillEditor } from '@vueup/vue-quill';
import '@vueup/vue-quill/dist/vue-quill.snow.css';

export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component('QuillEditor', QuillEditor);
});

components 資料夾建立 AppMessageInput.vue 元件。

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
<script setup>
const props = defineProps({
autofocus: {
type: Boolean,
default: false,
},
onSubmit: {
type: Function,
default: () => {},
},
});

const state = reactive({
content: '',
isSubmitting: false,
});

const reset = () => {
// 重置文字編輯器的文字
state.content = '\n';
nextTick(() => {
// 重置狀態
state.content = '';
});
};

const submit = async () => {
const content = state.content.trim();
if (!content) return;
if (state.isSubmitting) return;
state.isSubmitting = true;
reset();
await props.onSubmit(content);
state.isSubmitting = false;
};

const editorOption = {
theme: 'snow',
placeholder: '',
modules: {
keyboard: {
bindings: {
enter: {
key: 13,
handler: () => {
submit();
},
},
},
},
},
};
</script>

<template>
<v-sheet
rounded
>
<quill-editor
v-model:content="state.content"
:options="editorOption"
content-type="text"
@ready="(editor) => props.autofocus ? editor.focus() : null"
/>
<v-btn
:width="28"
:min-width="28"
color="indigo-lighten-2"
size="small"
variant="flat"
@click="submit"
>
<v-icon icon="mdi-send" />
</v-btn>
</v-sheet>
</template>

<style lang="scss" scoped>
.v-sheet {
border: 1px solid #FFFFFF;
background: inherit;
}
:deep(.ql-container) {
display: flex;
flex-direction: column-reverse;
max-height: 200px;
overflow: auto;
border: none;
color: #FFFFFF;
font-size: 16px;
}
:deep(.ql-toolbar) {
display: none;
}
:deep(.ql-editor) {
padding: 8px 42px 8px 16px;
}
.v-btn {
position: absolute;
bottom: 54px;
right: 56px;
}
</style>

參考資料