mach-cms的前台,用vue写的
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

99 lines
2.4 KiB

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import { mediaApi } from '@/api/client'
const props = defineProps<{
modelValue: string
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
const editorContainer = ref<HTMLDivElement>()
let quill: Quill | null = null
onMounted(() => {
if (!editorContainer.value) return
quill = new Quill(editorContainer.value, {
theme: 'snow',
placeholder: '开始写作...',
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ indent: '-1' }, { indent: '+1' }],
['link', 'image'],
['clean']
]
}
})
quill.root.innerHTML = props.modelValue
quill.on('text-change', () => {
emit('update:modelValue', quill!.root.innerHTML)
})
const toolbar = quill.getModule('toolbar') as any
toolbar.addHandler('image', () => {
const input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', 'image/*')
input.click()
input.onchange = async () => {
const file = input.files?.[0]
if (file) {
try {
const resp = await mediaApi.apiMediaUploadPost(file, 'images')
const stored = resp.data.data
const url = stored?.url
if (url && quill) {
const sel = quill.getSelection()
const index = sel ? sel.index : 0
quill.insertEmbed(index, 'image', url)
}
} catch (e) {
console.error(e)
}
}
}
})
})
watch(() => props.modelValue, (val) => {
if (quill && val !== quill.root.innerHTML) {
quill.root.innerHTML = val
}
})
</script>
<template>
<div ref="editorContainer" class="quill-editor" />
</template>
<style scoped>
.quill-editor {
min-height: 400px;
background: var(--ac-bg-card, #fff);
}
.quill-editor :deep(.ql-editor) {
min-height: 400px;
font-size: 16px;
line-height: 1.8;
}
.quill-editor :deep(.ql-toolbar) {
border-color: var(--ac-border, #d4c4b0);
background: var(--ac-surface, #faf8f5);
}
.quill-editor :deep(.ql-container) {
border-color: var(--ac-border, #d4c4b0);
}
.quill-editor :deep(.ql-editor.ql-blank::before) {
color: var(--ac-text-disabled);
}
</style>