vue-quill-editor 富文本编辑器(可上传视频图片),组件挂载的方式实现

本文主要是介绍vue-quill-editor 富文本编辑器(可上传视频图片),组件挂载的方式实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.安装

npm install vue-quill-editor --save
npm install quill-image-drop-module --save     
npm install quill-image-resize-module --save

2.在组件下面新增组件 QlEditor

在这里插入图片描述

(1)index.vue

<template><div><div id='quillEditorQiniu'><!-- 基于elementUi的上传组件 el-upload begin--><el-uploadclass="avatar-uploader":action="uploadImgUrl":accept="'image/*,video/*'":show-file-list="false":on-success="uploadEditorSuccess":on-error="uploadEditorError":before-upload="beforeEditorUpload":headers="headers"></el-upload><!-- 基于elementUi的上传组件 el-upload end--><quill-editorclass="editor"v-model="content"ref="customQuillEditor":options="editorOption"@blur="onEditorBlur($event)"@focus="onEditorFocus($event)"@change="onEditorChange($event)"></quill-editor></div></div>
</template><script>
import Vue from 'vue'
//引入quill-editor编辑器
import VueQuillEditor from 'vue-quill-editor'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'
Vue.use(VueQuillEditor)//实现quill-editor编辑器拖拽上传图片
import Quill from 'quill'
import { ImageDrop } from 'quill-image-drop-module'
Quill.register('modules/imageDrop', ImageDrop)//实现quill-editor编辑器调整图片尺寸
import ImageResize from 'quill-image-resize-module'
Quill.register('modules/imageResize', ImageResize)// 这里引入修改过的video模块并注册
import Video from './video'
Quill.register(Video, true)//获取登录token,引入文件,如果只是简单测试,没有上传文件是否登录的限制的话,
//这个token可以不用获取,文件可以不引入,把上面对应的上传文件携带请求头  :headers="headers" 这个代码删掉即可
import {getToken} from "@/utils/auth";const toolbarOptions = [['bold', 'italic', 'underline', 'strike'],        // toggled buttons['blockquote', 'code-block'],[{'header': 1}, {'header': 2}],               // custom button values[{'list': 'ordered'}, {'list': 'bullet'}],[{'script': 'sub'}, {'script': 'super'}],      // superscript/subscript[{'indent': '-1'}, {'indent': '+1'}],          // outdent/indent[{'direction': 'rtl'}],                         // text direction[{'size': ['small', false, 'large', 'huge']}],  // custom dropdown[{'header': [1, 2, 3, 4, 5, 6, false]}],[{'color': []}, {'background': []}],          // dropdown with defaults from theme[{'font': []}],[{'align': []}],['link', 'image', 'video'],['clean']                                         // remove formatting button
];
export default {name:"QlEditor",props: {/* 编辑器的内容 */value: {type: String,default: "",},/* 高度 */height: {type: Number,default: null,},/* 最小高度 */minHeight: {type: Number,default: null,},/* 只读 */readOnly: {type: Boolean,default: false,},/* 上传文件大小限制(MB) */fileSize: {type: Number,default: 5,},},model: {//v-model本质上是一个语法糖 这一步在父组件中可使用v-modelprop: "value",event: "change",},data(){return {headers: {Authorization: "Bearer " + getToken(),},uploadImgUrl:process.env.VUE_APP_BASE_API + "/common/upload",uploadUrlPath:"没有文件上传",quillUpdateImg:false,content:'',    //最终保存的内容editorOption:{placeholder:'你想说什么?',modules: {imageResize: {displayStyles: {backgroundColor: 'black',border: 'none',color: 'white'},modules: [ 'Resize', 'DisplaySize', 'Toolbar' ]},toolbar: {container: toolbarOptions,  // 工具栏handlers: {'image': function (value) {if (value) {document.querySelector('#quillEditorQiniu .avatar-uploader input').click()} else {this.quill.format('image', false);}},'video': function (value) {if (value) {document.querySelector('#quillEditorQiniu .avatar-uploader input').click()} else {this.quill.format('video', false);}},}}}},}},methods:{//上传图片之前asyncbeforeEditorUpload(res, file){//显示上传动画this.quillUpdateImg = true;//  const res1 = await uploadImage()// console.log(res1,'=====');// this.$emit('before',res, file)console.log(res);console.log(file);},// 上传图片成功uploadEditorSuccess(res, file) {//拼接出上传的图片在服务器的完整地址let url=res.url;let type=url.substring(url.lastIndexOf(".")+1);// 获取富文本组件实例let quill = this.$refs.customQuillEditor.quill;// 获取光标所在位置let length = quill.getSelection().index;// 插入图片||视频  res.info为服务器返回的图片地址if(type=='mp4' || type=='MP4'){window.jsValue=url;quill.insertEmbed(length, 'video', url)}else{quill.insertEmbed(length, 'image', url)}// 调整光标到最后quill.setSelection(length + 1)//取消上传动画this.quillUpdateImg = false;},// 上传(文件)图片失败uploadEditorError(res, file) {//页面提示this.$message.error('上传图片失败')//取消上传动画this.quillUpdateImg = false;},//上传组件返回的结果uploadResult:function (res){this.uploadUrlPath=res;},// 失去焦点事件onEditorBlur(quill) {console.log('editor blur!', quill)},// 获得焦点事件onEditorFocus(quill) {console.log('editor focus!', quill)},// 准备富文本编辑器onEditorReady(quill) {console.log('editor ready!', quill)},// 内容改变事件onEditorChange({ quill, html, text }) {console.log('editor change!', quill, html, text)this.content = html}},created () {},//只执行一次,加载执行mounted () {console.log("开始加载")// 初始给编辑器设置title},watch: {value: {handler(val) {if (val !== this.content) {this.content = val === null ? "" : val;}},immediate: true,},},
}
</script><style>
.editor {line-height: normal !important;height: 400px;margin-bottom: 50px;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {border-right: 0px;content: "保存";padding-right: 0px;
}.ql-snow .ql-tooltip[data-mode="video"]::before {content: "请输入视频地址:";
}.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {content: "32px";
}.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {content: "标题6";
}.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {content: "等宽字体";
}
</style>

(2)video.js

import  { Quill }  from 'vue-quill-editor'// 源码中是import直接倒入,这里要用Quill.import引入
const BlockEmbed = Quill.import('blots/block/embed')
// const Link = Quill.import('formats/link')const ATTRIBUTES = ['height', 'width']class Video extends BlockEmbed {static create (value) {const node = super.create(value)// console.log("js文件"+ window.jsValue)// 添加video标签所需的属性node.setAttribute('controls', 'controls') // 控制播放器//删除原生video的控制条的下载或者全屏按钮的方法//<video controls controlsList='nofullscreen nodownload noremote footbar' ></video>//不用哪个在下面加上哪个node.setAttribute('controlsList', 'nofullscreen') // 控制删除node.setAttribute('type', 'video/mp4')node.setAttribute('style', 'object-fit:fill;width: 100%;')node.setAttribute('preload', 'auto')    // auto - 当页面加载后载入整个视频  meta - 当页面加载后只载入元数据  none - 当页面加载后不载入视频node.setAttribute('playsinline', 'true')node.setAttribute('x-webkit-airplay', 'allow')// node.setAttribute('x5-video-player-type', 'h5') // 启用H5播放器,是wechat安卓版特性node.setAttribute('x5-video-orientation', 'portraint') // 竖屏播放 声明了h5才能使用  播放器支付的方向,landscape横屏,portraint竖屏,默认值为竖屏node.setAttribute('x5-playsinline', 'true') // 兼容安卓 不全屏播放node.setAttribute('x5-video-player-fullscreen', 'true')    // 全屏设置,设置为 true 是防止横屏node.setAttribute('src', window.jsValue)return node}static formats (domNode) {return ATTRIBUTES.reduce((formats, attribute) => {if (domNode.hasAttribute(attribute)) {formats[attribute] = domNode.getAttribute(attribute)}return formats}, {})}// static sanitize (url) {////      // eslint-disable-line import/no-named-as-default-member// }static value (domNode) {return domNode.getAttribute('src')}format (name, value) {if (ATTRIBUTES.indexOf(name) > -1) {if (value) {this.domNode.setAttribute(name, value)} else {this.domNode.removeAttribute(name)}} else {super.format(name, value)}}html () {const { video } = this.value()return `<a href="${video}" rel="external nofollow" >${video}</a>`}
}
Video.blotName = 'video' // 这里不用改,楼主不用iframe,直接替换掉原来,如果需要也可以保留原来的,这里用个新的blot
Video.className = 'ql-video'
Video.tagName = 'video' // 用video标签替换iframeexport default Video

3.main.js

import Vue from 'vue'
import QlEditor from "@/components/QlEditor"
// 全局组件挂载
Vue.component('QlEditor', QlEditor)

4.vue.config.js中加入

const webpack = require('webpack');
new webpack.ProvidePlugin({'window.Quill': 'quill/dist/quill.js','Quill': 'quill/dist/quill.js'
}),

加入位置如图
在这里插入图片描述
参考:https://www.cnblogs.com/wihimi/p/14246911.html

5.页面使用

<el-form-item label="内容"><QlEditor v-model="form.content" ref="qlEditorRef" :min-height="192"/>
</el-form-item><script>
/** 提交按钮 */
submitForm() {this.$refs["form"].validate(valid => {this.form.content=this.$refs.qlEditorRef.content;});
},
</script>

6.上传效果图

在这里插入图片描述
参考:https://www.jb51.net/article/264842.htm

这篇关于vue-quill-editor 富文本编辑器(可上传视频图片),组件挂载的方式实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/873485

相关文章

全面解析HTML5中Checkbox标签

《全面解析HTML5中Checkbox标签》Checkbox是HTML5中非常重要的表单元素之一,通过合理使用其属性和样式自定义方法,可以为用户提供丰富多样的交互体验,这篇文章给大家介绍HTML5中C... 在html5中,Checkbox(复选框)是一种常用的表单元素,允许用户在一组选项中选择多个项目。本

HTML5 搜索框Search Box详解

《HTML5搜索框SearchBox详解》HTML5的搜索框是一个强大的工具,能够有效提升用户体验,通过结合自动补全功能和适当的样式,可以创建出既美观又实用的搜索界面,这篇文章给大家介绍HTML5... html5 搜索框(Search Box)详解搜索框是一个用于输入查询内容的控件,通常用于网站或应用程

Linux脚本(shell)的使用方式

《Linux脚本(shell)的使用方式》:本文主要介绍Linux脚本(shell)的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录概述语法详解数学运算表达式Shell变量变量分类环境变量Shell内部变量自定义变量:定义、赋值自定义变量:引用、修改、删

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

Java使用HttpClient实现图片下载与本地保存功能

《Java使用HttpClient实现图片下载与本地保存功能》在当今数字化时代,网络资源的获取与处理已成为软件开发中的常见需求,其中,图片作为网络上最常见的资源之一,其下载与保存功能在许多应用场景中都... 目录引言一、Apache HttpClient简介二、技术栈与环境准备三、实现图片下载与保存功能1.

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

CSS3中的字体及相关属性详解

《CSS3中的字体及相关属性详解》:本文主要介绍了CSS3中的字体及相关属性,详细内容请阅读本文,希望能对你有所帮助... 字体网页字体的三个来源:用户机器上安装的字体,放心使用。保存在第三方网站上的字体,例如Typekit和Google,可以link标签链接到你的页面上。保存在你自己Web服务器上的字

Nexus安装和启动的实现教程

《Nexus安装和启动的实现教程》:本文主要介绍Nexus安装和启动的实现教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、Nexus下载二、Nexus安装和启动三、关闭Nexus总结一、Nexus下载官方下载链接:DownloadWindows系统根