Compare commits

...

1 Commits

Author SHA1 Message Date
fan
2d070a2cf4 富文本框调整 2024-03-08 19:16:24 +08:00
2 changed files with 205 additions and 14 deletions

View File

@ -19,6 +19,16 @@
}, },
"dependencies": { "dependencies": {
"@stomp/stompjs": "^5.4.4", "@stomp/stompjs": "^5.4.4",
"@tiptap/extension-color": "^2.2.4",
"@tiptap/extension-table": "^2.2.4",
"@tiptap/extension-table-cell": "^2.2.4",
"@tiptap/extension-table-header": "^2.2.4",
"@tiptap/extension-table-row": "^2.2.4",
"@tiptap/extension-text-align": "^2.2.4",
"@tiptap/extension-text-style": "^2.2.4",
"@tiptap/pm": "^2.2.4",
"@tiptap/starter-kit": "^2.2.4",
"@tiptap/vue-2": "^2.2.4",
"axios": "^0.18.0", "axios": "^0.18.0",
"dayjs": "^1.11.5", "dayjs": "^1.11.5",
"echarts": "^4.7.0", "echarts": "^4.7.0",

View File

@ -1,15 +1,81 @@
<template> <template>
<el-dialog v-dialogDrag v-loading="loading" title="编辑赛季内容" :visible.sync="dialogVisible" width="80%" :before-close="handleClose" center :close-on-click-modal="false"> <el-dialog v-dialogDrag v-loading="loading" title="编辑赛季内容" :visible.sync="dialogVisible" width="80%" :before-close="handleClose" center :close-on-click-modal="false">
<quill-editor <!-- <quill-editor-->
:ref="'contentInput'" <!-- :ref="'contentInput'"-->
v-model="seasonContent" <!-- v-model="seasonContent"-->
style="width: 80%;margin-left: 10%;margin-top: 10px;" <!-- style="width: 80%;margin-left: 10%;margin-top: 10px;"-->
:margin-bottom="20" <!-- :margin-bottom="20"-->
editor-type="default" <!-- editor-type="default"-->
:no-handle-p="true" <!-- :no-handle-p="true"-->
:height="450" <!-- :height="450"-->
placeholder="请输入" <!-- placeholder="请输入"-->
/> <!-- />-->
<div v-if="editor">
<button :disabled="!editor.can().chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }" @click="editor.chain().focus().toggleBold().run()">
bold
</button>
<button :disabled="!editor.can().chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }" @click="editor.chain().focus().toggleItalic().run()">
italic
</button>
<button :disabled="!editor.can().chain().focus().toggleStrike().run()" :class="{ 'is-active': editor.isActive('strike') }" @click="editor.chain().focus().toggleStrike().run()">
strike
</button>
<button :disabled="!editor.can().chain().focus().toggleCode().run()" :class="{ 'is-active': editor.isActive('code') }" @click="editor.chain().focus().toggleCode().run()">
code
</button>
<button @click="editor.chain().focus().unsetAllMarks().run()">
clear marks
</button>
<button @click="editor.chain().focus().clearNodes().run()">
clear nodes
</button>
<button :class="{ 'is-active': editor.isActive('paragraph') }" @click="editor.chain().focus().setParagraph().run()">
paragraph
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }" @click="editor.chain().focus().toggleHeading({ level: 1 }).run()">
h1
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }" @click="editor.chain().focus().toggleHeading({ level: 2 }).run()">
h2
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }" @click="editor.chain().focus().toggleHeading({ level: 3 }).run()">
h3
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }" @click="editor.chain().focus().toggleHeading({ level: 4 }).run()">
h4
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }" @click="editor.chain().focus().toggleHeading({ level: 5 }).run()">
h5
</button>
<button :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }" @click="editor.chain().focus().toggleHeading({ level: 6 }).run()">
h6
</button>
<button :class="{ 'is-active': editor.isActive('bulletList') }" @click="editor.chain().focus().toggleBulletList().run()">
bullet list
</button>
<button :class="{ 'is-active': editor.isActive('orderedList') }" @click="editor.chain().focus().toggleOrderedList().run()">
ordered list
</button>
<button :class="{ 'is-active': editor.isActive('codeBlock') }" @click="editor.chain().focus().toggleCodeBlock().run()">
code block
</button>
<button :class="{ 'is-active': editor.isActive('blockquote') }" @click="editor.chain().focus().toggleBlockquote().run()">
blockquote
</button>
<button @click="editor.chain().focus().setHorizontalRule().run()">
horizontal rule
</button>
<button @click="editor.chain().focus().setHardBreak().run()">
hard break
</button>
<button :disabled="!editor.can().chain().focus().undo().run()" @click="editor.chain().focus().undo().run()">
undo
</button>
<button :disabled="!editor.can().chain().focus().redo().run()" @click="editor.chain().focus().redo().run()">
redo
</button>
</div>
<editor-content :editor="editor" />
<span slot="footer" class="dialog-footer"> <span slot="footer" class="dialog-footer">
<el-button v-loading="loading" type="primary" @click="doSave">{{ $t('global.confirm') }}</el-button> <el-button v-loading="loading" type="primary" @click="doSave">{{ $t('global.confirm') }}</el-button>
<el-button @click="handleClose">{{ $t('global.cancel') }}</el-button> <el-button @click="handleClose">{{ $t('global.cancel') }}</el-button>
@ -18,20 +84,71 @@
</template> </template>
<script> <script>
import { editSeasonContent, getSeasonContent } from '@/api/contest'; import { editSeasonContent, getSeasonContent } from '@/api/contest';
import QuillEditor from '@/components/QuillEditor/index'; // import QuillEditor from '@/components/QuillEditor/index';
import { Editor, EditorContent } from '@tiptap/vue-2';
import StarterKit from '@tiptap/starter-kit';
import ExtensionColor from '@tiptap/extension-color';
import ExtensionTable from '@tiptap/extension-table';
import ExtensionTableHeader from '@tiptap/extension-table-header';
import ExtensionTableRow from '@tiptap/extension-table-row';
import ExtensionTableCell from '@tiptap/extension-table-cell';
import ExtensionTextStyle from '@tiptap/extension-text-style';
import ExtensionTextAlign from '@tiptap/extension-text-align';
export default { export default {
name: 'EditContent', name: 'EditContent',
components: { components: {
QuillEditor EditorContent
}, },
data() { data() {
return { return {
dialogVisible: false, dialogVisible: false,
seasonContent:'', seasonContent:'',
id: '', id: '',
loading: false loading: false,
editor: null
}; };
}, },
mounted() {
ExtensionTextAlign.configure({
types: ['heading', 'paragraph']
});
ExtensionTable.configure({
HTMLAttributes: {
class: 'my-custom-class'
}
});
ExtensionTableHeader.configure({
HTMLAttributes: {
class: 'my-custom-class1'
}
});
ExtensionTableCell.configure({
HTMLAttributes: {
class: 'my-custom-class'
}
});
this.editor = new Editor({
content: '',
extensions: [
StarterKit,
ExtensionTextStyle,
ExtensionColor,
ExtensionTable,
ExtensionTableHeader,
ExtensionTableRow,
ExtensionTableCell,
ExtensionTextAlign
],
onUpdate: () => {
}
});
},
beforeDestroy() {
this.editor.destroy();
},
methods:{ methods:{
doShow(row) { doShow(row) {
this.dialogVisible = true; this.dialogVisible = true;
@ -40,6 +157,7 @@ export default {
this.id = row.id; this.id = row.id;
getSeasonContent(row.id).then(resp => { getSeasonContent(row.id).then(resp => {
this.seasonContent = resp.data.html || ''; this.seasonContent = resp.data.html || '';
this.editor.commands.setContent( this.seasonContent, false);
this.loading = false; this.loading = false;
}).catch(e => { }).catch(e => {
this.loading = false; this.loading = false;
@ -54,7 +172,7 @@ export default {
this.loading = false; this.loading = false;
}, },
doSave() { doSave() {
editSeasonContent(this.id, {htmlContent: this.seasonContent}).then(resp => { editSeasonContent(this.id, {htmlContent: this.editor.getHTML()}).then(resp => {
this.handleClose(); this.handleClose();
this.$message.success('修改内容成功!'); this.$message.success('修改内容成功!');
}).catch(e => { }).catch(e => {
@ -64,4 +182,67 @@ export default {
} }
}; };
</script> </script>
<style scoped>
.my-custom-class{
border: 1px solid #5B6163;
}
.my-custom-class1 {
border: 1px solid #5B6163;
background-color: #ccc;
}
.tiptap {
> * + * {
margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
}
code {
background-color: rgba(#616161, 0.1);
color: #616161;
}
pre {
background: #0D0D0D;
color: #FFF;
font-family: 'JetBrainsMono', monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
}
}
img {
max-width: 100%;
height: auto;
}
blockquote {
padding-left: 1rem;
border-left: 2px solid rgba(#0D0D0D, 0.1);
}
hr {
border: none;
border-top: 2px solid rgba(#0D0D0D, 0.1);
margin: 2rem 0;
}
}
</style>