add QuillEditor Component
This commit is contained in:
parent
075c6cc7e4
commit
a2101db747
3 changed files with 187 additions and 29 deletions
110
src/components/QuillEditor.vue
Normal file
110
src/components/QuillEditor.vue
Normal file
|
@ -0,0 +1,110 @@
|
|||
<template>
|
||||
<div ref="quill"></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent, type PropType } from "vue";
|
||||
import Quill, { Delta } from "quill";
|
||||
import "quill/dist/quill.core.css";
|
||||
import "quill/dist/quill.snow.css";
|
||||
|
||||
type RangeStatic = { index: number; length: number };
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export default defineComponent({
|
||||
props: {
|
||||
toolbar: {
|
||||
type: [String, Array, Object],
|
||||
default: "",
|
||||
},
|
||||
modules: {
|
||||
type: Object as PropType<Record<string, unknown>>,
|
||||
default: {},
|
||||
},
|
||||
content: {
|
||||
type: [String, Object] as PropType<string | Delta>,
|
||||
default: "",
|
||||
},
|
||||
contentType: {
|
||||
type: String as PropType<"delta" | "html" | "text">,
|
||||
default: "text",
|
||||
},
|
||||
readonly: { type: Boolean, default: false },
|
||||
placeholder: String,
|
||||
},
|
||||
emits: {
|
||||
"update:content": (content: Delta | string) => true,
|
||||
textChange: (tc: { delta: Delta; oldDelta: Delta; source: string }) => true,
|
||||
selectionChange: (sc: { range: RangeStatic; oldRange: RangeStatic; source: string }) => true,
|
||||
focus: () => true,
|
||||
blur: () => true,
|
||||
ready: (quill: Quill) => true,
|
||||
},
|
||||
watch: {
|
||||
conent(val, oldVal) {
|
||||
this.setContent(val);
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
instance: undefined as undefined | Quill,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.instance = new Quill(this.$refs.quill as HTMLElement, {
|
||||
theme: "snow",
|
||||
modules: {
|
||||
toolbar: this.toolbar,
|
||||
},
|
||||
placeholder: this.placeholder,
|
||||
readOnly: this.readonly,
|
||||
});
|
||||
|
||||
this.instance.on("selection-change", (range, oldRange, source) => {
|
||||
if (!range) {
|
||||
this.$emit("blur");
|
||||
} else {
|
||||
this.$emit("focus");
|
||||
}
|
||||
this.$emit("selectionChange", { range, oldRange, source });
|
||||
});
|
||||
this.instance.on("text-change", (delta, oldDelta, source) => {
|
||||
this.$emit("update:content", this.getContent());
|
||||
this.$emit("textChange", { delta, oldDelta, source });
|
||||
});
|
||||
|
||||
this.$emit("ready", this.instance as Quill);
|
||||
this.setContent(this.content);
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.instance = undefined;
|
||||
},
|
||||
methods: {
|
||||
getContent(): string | Delta {
|
||||
if (this.contentType === "delta") {
|
||||
return (this.instance?.getContents() ?? {}) as Delta;
|
||||
} else if (this.contentType === "html") {
|
||||
return this.instance?.getSemanticHTML() ?? "";
|
||||
} else {
|
||||
return this.instance?.getText() ?? "";
|
||||
}
|
||||
},
|
||||
setContent(content: Delta | string) {
|
||||
if (this.contentType === "delta") {
|
||||
if (typeof content !== "string") {
|
||||
this.instance?.setContents(content);
|
||||
}
|
||||
} else if (this.contentType === "html") {
|
||||
if (typeof content === "string" && this.instance) {
|
||||
this.instance.root.innerHTML = content;
|
||||
}
|
||||
} else {
|
||||
if (typeof content === "string") {
|
||||
this.instance?.setText(content);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue