功能需求:
在同一页面引用多个富文本编辑器
问题描述:
最开始考虑使用wangEditor,但发现上传图片时位置错乱,每次都会上传到最后一个编辑器上(如图1所示)于是更换vue-quill-editor插件,问题得到解决。
图 1
解决方案:
1.安装
npm install vue-quill-editor --save
2.在 main.js 引入
import VueQuillEditor from 'vue-quill-editor'
Vue.use(VueQuillEditor);
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
3.自定义组件封装(按功能需求自定义,本例封装文件为 vEditor.vue,可按照水平、垂直方式展示两个富文本编辑器)
<style lang="less" scoped>
.leftUpload {
display: none;
}
.rightUpload {
display: none;
}
</style>
<template>
<div>
<Upload class="leftUpload"
:show-upload-list="false"
:on-success="handleSuccess"
:format="['jpg','jpeg','png','gif']"
:max-size="2048"
multiple
:action="uploadPath+'leftQuill'"
>
<Button icon="ios-cloud-upload-outline" ></Button>
</Upload>
<Upload class="rightUpload"
:show-upload-list="false"
:on-success="handleSuccess"
:format="['jpg','jpeg','png','gif']"
:max-size="2048"
multiple
:action="uploadPath+'rightQuill'"
>
<Button icon="ios-cloud-upload-outline" ></Button>
</Upload>
<Row v-if="layOutType=='x-axis'">
<Col span="12">
<h4>{{leftContent}}</h4>
<quill-editor
v-model="content.leftText"
:options="leftOption"
@change="leftTextChange"
ref="leftQuill" :style="{height:contentHeight+'px'}">
</quill-editor>
</Col>
<Col span="12">
<h4>{{rightContent}}</h4>
<quill-editor
v-model="content.rightText"
:options="rightOption"
@change="rightTextChange"
ref="rightQuill" :style="{height:contentHeight+'px'}">
</quill-editor>
</Col>
</Row>
<div v-if="layOutType=='y-axis'">
<h4>{{leftContent}}</h4>
<quill-editor
v-model="content.leftText"
:options="leftOption"
@change="leftTextChange"
ref="leftQuill" :style="{height:contentHeight+'px'}">
</quill-editor>
</div>
<div v-if="layOutType=='y-axis'" style="margin-top:50px">
<h4>{{rightContent}}</h4>
<quill-editor
v-model="content.rightText"
:options="rightOption"
@change="rightTextChange"
ref="rightQuill" :style="{height:contentHeight+'px'}">
</quill-editor>
</div>
</div>
</template>
<script>
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
['blockquote', 'code-block'], // 引用 代码块
[{ header: 1 }, { header: 2 }], // 1、2 级标题
[{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
[{ script: 'sub' }, { script: 'super' }], // 上标/下标
[{ indent: '-1' }, { indent: '+1' }], // 缩进
[{ size: ['small', false, 'large', 'huge'] }], // 字体大小
[{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
// [{ font: [] }], // 字体种类
[{ align: [] }], // 对齐方式
['clean'], // 清除文本格式
['link', 'image', 'video'] // 链接、图片、视频
]
import http from '@/api/http'
import Constants from '@/commons/constants'
export default {
data() {
return {
layOutType:'', //排列布局(水平、垂直)
leftContent:'', //左(上)侧标题
leftText:'', //左(上)侧内容
rightContent:'', //右(下)侧标题
rightText:'', //右(下)侧标题
uploadPath:'', //图片上传路径
contentHeight: window.innerHeight - 500,
content:{leftText:'',rightText:''},
leftOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
'image': function (value) {
if (value) {
// 调用Upload组件进行图片上传
document.querySelector('.leftUpload .ivu-btn').click()
} else {
this.quill.format('image', false);
}
}
}
}
},
placeholder: "请在这里输入内容",
},
rightOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
'image': function (value) {
if (value) {
// 调用Upload组件进行图片上传
document.querySelector('.rightUpload .ivu-btn').click()
} else {
this.quill.format('image', false);
}
}
}
}
},
placeholder: "请在这里输入内容",
},
}
},
computed: {},
props: {
editor: {type: Object},
},
methods: {
init(){
this.layOutType = this.editor.layOutType;
this.leftContent = this.editor.leftContent;
this.leftText = this.editor.leftText;
this.rightContent = this.editor.rightContent;
this.rightText = this.editor.rightText;
this.uploadPath = this.editor.uploadPath;
this.content.leftText = this.editor.leftText;
this.content.rightText = this.editor.rightText;
},
leftTextChange(){
this.$emit('input', this.content);
},
rightTextChange(){
this.$emit('input', this.content);
},
handleSuccess (res) {
let fileRes = res.data;
let filePath = fileRes.filePath;
// console.log(filePath)
let imgType = fileRes.imgType;
let quill = null;
// 获取富文本组件实例
if(imgType == 'rightQuill'){
quill = this.$refs.rightQuill.quill
}else{
quill = this.$refs.leftQuill.quill
}
// 如果上传成功
if (res) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片,res为服务器返回的图片链接地址
quill.insertEmbed(length, 'image', filePath)
// 调整光标到最后
quill.setSelection(length + 1)
} else {
// 提示信息,需引入Message
Message.error('图片插入失败')
}
},
},
watch: {//检测数据
editor(val){
if(val){
this.init();
}
}
},
components: {},
mounted() {
this.init();
},
created() {}
}
</script>
4.功能页面使用
html部分
<v-editor v-model="content" :style="{height:divH+'px'}" :editor="editor"></v-editor>
<script>部分
import VEditor from '../../components/vEditor.vue' //组件存放路径
data() {
return {
layOutTypeList: ['x-axis','y-axis'],
editor:{},
content:{},
divH: window.innerHeight - 350,
}
},
methods: {
//初始化数据
init(){
this.editor={
leftText:'',
rightText:'',
uploadPath:apiPath +'/cwoa/erratr/upload/', //图片上传路径
leftContent:"原文:",
rightContent:"修改为:",
layOutType:this.layOutTypeList[0]
}
},
//表单提交
handleSubmit() {
this.form.originalText = this.content.leftText;
this.form.correctText = this.content.rightText;
//表单数据校验
this.$refs['form'].validate((valid) => {
if (valid) {
//业务逻辑处理
}
})
},
},
//注册组件
components: {VEditor},
created() {
//初始化数据
this.init()
}
实现效果:
(如图2所示:水平排列效果)
图 2