This commit is contained in:
parent
0ab544e08e
commit
dd95c3d40a
|
|
@ -60,13 +60,13 @@
|
||||||
"component": "vab/upload"
|
"component": "vab/upload"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "/vab/edit",
|
"path": "/vab/editor",
|
||||||
"name": "edit",
|
"name": "editor",
|
||||||
"meta": {
|
"meta": {
|
||||||
"title": "富文本编辑器",
|
"title": "富文本编辑器",
|
||||||
"type": "menu"
|
"type": "menu"
|
||||||
},
|
},
|
||||||
"component": "vab/edit"
|
"component": "vab/editor"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="sceditor">
|
|
||||||
<div class="toolbar-container"></div>
|
|
||||||
<div class="content-container">
|
|
||||||
<ckeditor v-model="value" :editor="editor" :config="editorConfig" :disabled="disabled" @ready="onReady" @input="onEditorInput"></ckeditor>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import ClassicEditor from './build-classic/ckeditor.js';
|
|
||||||
import CKEditor from './ckeditor.js';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
ckeditor: CKEditor.component
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
modelValue: { type: String, default: "" },
|
|
||||||
disabled: { type: Boolean, default: false }
|
|
||||||
},
|
|
||||||
data(){
|
|
||||||
return {
|
|
||||||
value: this.modelValue,
|
|
||||||
editor: ClassicEditor,
|
|
||||||
editorConfig: {
|
|
||||||
toolbar: [ 'heading', '|', 'fontSize', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'imageUpload' ,'insertTable'],
|
|
||||||
placeholder: '请填写内容',
|
|
||||||
image: {
|
|
||||||
toolbar: [
|
|
||||||
'imageTextAlternative',
|
|
||||||
'imageStyle:full',
|
|
||||||
'imageStyle:side'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
table: {
|
|
||||||
contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableCellProperties', 'tableProperties' ]
|
|
||||||
},
|
|
||||||
ckfinder: {
|
|
||||||
uploadUrl: 'https://www.fastmock.site/mock/44c807475f7eeba73409792255781935/api/upload'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch:{
|
|
||||||
modelValue(){
|
|
||||||
this.value = this.modelValue
|
|
||||||
},
|
|
||||||
},
|
|
||||||
mounted(){
|
|
||||||
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onReady(editor) {
|
|
||||||
const toolbarContainer = document.querySelector( '.toolbar-container' );
|
|
||||||
toolbarContainer.prepend( editor.ui.view.toolbar.element );
|
|
||||||
},
|
|
||||||
onEditorInput(val){
|
|
||||||
this.$emit('update:modelValue', val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
.sceditor {
|
|
||||||
|
|
||||||
}
|
|
||||||
.sceditor .ck-toolbar {background: #fff;border-color: #DCDFE6;box-shadow: 2px 2px 1px rgba(0,0,0,.05); position: relative;z-index: 1;}
|
|
||||||
.content-container {
|
|
||||||
background: #f6f8f9;
|
|
||||||
overflow-y: scroll;
|
|
||||||
padding:30px;
|
|
||||||
max-height:300px;
|
|
||||||
border: 1px solid #DCDFE6;
|
|
||||||
border-top: 0;
|
|
||||||
}
|
|
||||||
.content-container .ck-content {
|
|
||||||
margin: 0 auto;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #DCDFE6!important;
|
|
||||||
box-shadow: 2px 2px 1px rgba(0,0,0,.05)!important;
|
|
||||||
padding:40px;
|
|
||||||
min-height: 300px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
<template>
|
||||||
|
<div class="sceditor">
|
||||||
|
<div class="toolbar-container"></div>
|
||||||
|
<div class="content-container">
|
||||||
|
<ckeditor v-model="value" :editor="editor" :config="editorConfig" :disabled="disabled" @ready="onReady"
|
||||||
|
@input="onEditorInput"></ckeditor>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ClassicEditor from './build-classic/ckeditor.js';
|
||||||
|
import CKEditor from './ckeditor.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
ckeditor: CKEditor.component
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
placeholder: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
toolbar: {
|
||||||
|
type: Array,
|
||||||
|
default: () => { return ['heading', '|', 'fontSize', 'fontFamily', 'fontColor', '|', 'bold', 'italic', 'underline', 'strikethrough', '|', 'alignment', '|', 'bulletedList', 'numberedList', '|', 'outdent', 'indent', '|', 'todoList', 'blockQuote', 'link', 'imageUpload', 'mediaEmbed', 'insertTable', '|', 'undo', 'redo'] }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
value: this.modelValue,
|
||||||
|
editor: ClassicEditor,
|
||||||
|
editorConfig: {
|
||||||
|
toolbar: this.toolbar,
|
||||||
|
placeholder: this.placeholder,
|
||||||
|
fontSize: {
|
||||||
|
options: ['default', 10, 12, 14, 16, 18, 20, 24, 36]
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
styles: ['alignLeft', 'alignCenter', 'alignRight'],
|
||||||
|
toolbar: [ 'imageStyle:alignCenter', 'imageStyle:alignLeft', 'imageStyle:alignRight', '|', 'imageTextAlternative' ]
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
contentToolbar: ['tableColumn', 'tableRow', 'mergeTableCells', 'tableCellProperties', 'tableProperties']
|
||||||
|
},
|
||||||
|
ckfinder: {
|
||||||
|
uploadUrl: 'https://www.fastmock.site/mock/44c807475f7eeba73409792255781935/api/upload'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
modelValue() {
|
||||||
|
this.value = this.modelValue
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onReady(editor) {
|
||||||
|
const toolbarContainer = document.querySelector('.toolbar-container');
|
||||||
|
toolbarContainer.prepend(editor.ui.view.toolbar.element);
|
||||||
|
},
|
||||||
|
onEditorInput() {
|
||||||
|
this.$emit('update:modelValue', this.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.sceditor {}
|
||||||
|
.ck .ck-placeholder:before {color: #bbb;}
|
||||||
|
.sceditor .ck-toolbar {
|
||||||
|
background: #fff;
|
||||||
|
border-color: #DCDFE6;
|
||||||
|
box-shadow: 2px 2px 1px rgba(0, 0, 0, .05);
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-container {
|
||||||
|
background: #f6f8f9;
|
||||||
|
overflow-y: scroll;
|
||||||
|
padding: 30px;
|
||||||
|
height: 400px;
|
||||||
|
border: 1px solid #DCDFE6;
|
||||||
|
border-top: 0;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content-container .ck-content {
|
||||||
|
margin: 0 auto;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #DCDFE6 !important;
|
||||||
|
box-shadow: 2px 2px 1px rgba(0, 0, 0, .05) !important;
|
||||||
|
padding: 40px;
|
||||||
|
min-height: 340px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-main>
|
|
||||||
<el-card shadow="never">
|
|
||||||
<sc-edit v-model="html"></sc-edit>
|
|
||||||
</el-card>
|
|
||||||
</el-main>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import scEdit from '@/components/scEdit';
|
|
||||||
export default {
|
|
||||||
name: "edit",
|
|
||||||
components: {
|
|
||||||
scEdit
|
|
||||||
},
|
|
||||||
data(){
|
|
||||||
return {
|
|
||||||
html: '<h2 style="text-align:center;"><span style="font-family:Georgia, serif;">The Flavorful Tuscany Meetup</span></h2><h3 style="text-align:center;"><span style="font-family:Georgia, serif;">Welcome letter</span></h3><p><span class="text-big">Dear Guest,</span></p><p><span class="text-big">We are delighted to welcome you to the annual Flavorful Tuscany Meetup and hope you will enjoy the programme as well as your stay at the Bilancino Hotel.</span></p><p><span class="text-big">Please find attached the full schedule of the event.</span></p><p> </p><figure class="table" style="width:100%;"><table><tbody><tr><td style="background-color:hsl(0, 0%, 60%);height:40px;text-align:center;" colspan="2"><span class="text-big">Saturday, July 14</span></td></tr><tr><td style="background-color:hsl(0, 0%, 90%);height:40px;padding:15px;width:180px;">9:30 AM - 11:30 AM</td><td style="padding:15px;"><p><span class="text-big">Americano vs. Brewed - “know your coffee” with:</span></p><p> </p><p>Giulia Bianchi<br>Stefano Garau<br>Giuseppe Russo</p></td></tr><tr><td style="background-color:hsl(0, 0%, 90%);padding:15px;">1:00 PM - 3:00 PM</td><td style="padding:15px;"><p><span class="text-big">Pappardelle al pomodoro - live cooking</span></p><p> </p><p>Incorporate the freshest ingredients <br>with Rita Fresco</p></td></tr></tbody></table></figure>'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<el-main>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<sc-editor v-model="html" placeholder="请输入"></sc-editor>
|
||||||
|
</el-card>
|
||||||
|
</el-main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { defineAsyncComponent } from 'vue';
|
||||||
|
const scEditor = defineAsyncComponent(() => import('@/components/scEditor'));
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "editor",
|
||||||
|
components: {
|
||||||
|
scEditor
|
||||||
|
},
|
||||||
|
data(){
|
||||||
|
return {
|
||||||
|
html: '<h2 style="text-align:center;"><span style="font-size:24px;">CKEditor 5</span></h2><p style="text-align:center;">SCUI 二次封装</p><p> </p><p> </p><p>关于富文本编辑器真的是个大坑,在选择的过程中我也走了不少弯路,基本上世面上几款主流的富文本编辑器都试过来了。</p><p> </p><p>先说下为什么选择ckeditor5作为SCUI的富文本默认编辑器,第一次用ckeditor是早期DEDECMS年代,它后台所使用的就是ckeditor,经过了近10年的更新也迭代到了5.0,而ckeditor官网的online builder(在线编译)是我最后选择它的原因。不用import各种样式、工具和插件,傻瓜式的操作生成出中文的自定义组件的属于自己的ckeditor5,它的文档也是相比的几款编辑器中最全,演示最多的,唯一不足的就是没有官方中文文档。最后它的几款增值服务真的非常牛(协同编辑等),有兴趣的同学可以去它的 <a href="https://ckeditor.com/"><span style="color:hsl(210, 75%, 60%);">官网</span></a> 了解下。</p><p> </p><p>这次封装后支持v-model双向绑定模式,也开放了几个props</p><figure class="table" style="width:100%;"><table><tbody><tr><td style="background-color:hsl(0, 0%, 60%);padding:15px;width:200px;" colspan="3"><p style="text-align:center;"><span style="color:hsl(0, 0%, 100%);"><strong>props</strong></span></p></td></tr><tr><td style="background-color:hsl(0, 0%, 90%);padding:15px;width:200px;">v-model</td><td style="padding:15px;width:200px;">String</td><td style="padding:15px;">编辑器内的富文本</td></tr><tr><td style="background-color:hsl(0, 0%, 90%);padding:15px;">placeholder</td><td style="padding:15px;">String</td><td style="padding:15px;">属性提供可描述输入字段预期值的提示信息,默认为空</td></tr><tr><td style="background-color:hsl(0, 0%, 90%);padding:15px;">toolbar</td><td style="padding:15px;">Array</td><td style="padding:15px;">需要显示的头部工具,配置相当暴力直接,默认全部</td></tr><tr><td style="background-color:hsl(0, 0%, 90%);padding:15px;">disabled</td><td style="padding:15px;">Boolean</td><td style="padding:15px;">是否禁用编辑器</td></tr></tbody></table></figure><p>当前页面使用了异步加载组件,因为ckeditor5打包后的文件实在太大了(1M),采用异步加载可极大加快页面打开速度。正因为文件大小的关系,不再考虑将编辑器作为全局组件,毕竟使用频次比表单之类的要少很多。因为非常独立,耦合度基本为零,可随意删除,减少打包后的文件大小</p>'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue