包含两种上传方式,第一种点开弹新页面可选url和点击上传。本文中是第二种,自己拼的。像点击上传图片一样,直接传video文件,原创不易,纯纯踩坑;
因为现阶段能搜索到的内容,99.5%都是一样的内容,无法满足需求。
我的需求是在ruoyi-vue里面用quill富文本,但里面一部分功能没有。
但作者给了自定义插件通道。
如果根据我的代码去写,上传完视频 就拿不到光标,只能拿到最后一个字的长度,因此上传视频被提成bug。
自猜:点击完tag的上传视频 是打开个子页面,父子页面传值可能存在问题。
无奈之下只能自己手拼。看代码吧。如有问题请及时指正。
所有代码在同级目录下
贴代码
index.vue
- <template>
- <div>
-
- <el-upload
- :action="uploadUrl"
- :before-upload="handleBeforeUpload"
- :http-request="uploadURL"
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: none"
- ref="upload"
- v-if="this.type == 'url'"
- >
- </el-upload>
-
- <div class="editor" ref="editor" :style="styles"></div>
-
- <!--视频上传 begin -->
-
- <!-- <el-tab-pane label="添加视频链接" name="second">
- <el-input v-model="videoDialog.videoLink" placeholder="请输入视频链接" clearable></el-input>
- <el-button type="primary" size="small" style="margin: 20px 0px 0px 0px" @click="addVideoLink(videoDialog.videoLink)">添加 </el-button>
- </el-tab-pane> -->
-
- <!--<div>
- <el-dialog :close-on-click-modal="false" width="50%" style="margin-top: 1px" title="视频上传" :visible.sync="videoDialog.show" append-to-body ref="dialogRef">
- <el-tabs v-model="videoDialog.activeName">
-
- <el-tab-pane label="本地视频上传" >
-
- <el-upload
- v-loading="uploading"
- style="text-align: center"
- drag
- action=""
- accept="video/*"
- :http-request="uploadVideoURL"
- :multiple="false"
- :before-upload="videoHandleBeforeUpload"
- v-if="this.type == 'video'"
- >
-
- <i class="el-icon-upload"></i>
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
- </el-upload>
- </el-tab-pane>
- </el-tabs>
- </el-dialog>
- </div> -->
-
- <!-- :http-request="uploadVideoURL"
- :multiple="false"
- :before-upload="videoHandleBeforeUpload"
- style="display: none" -->
- <el-upload
-
-
- name="file"
- :show-file-list="false"
- :headers="headers"
- style="display: none"
- ref="uploadVideo"
-
- :http-request="uploadVideoURL"
- :before-upload="videoHandleBeforeUpload"
- action="uploadVideoURL"
- :multiple="false"
- v-if="this.video == 'r'"
- >
-
- <i class="el-icon-upload"></i>
- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
- </el-upload>
-
-
- <!--视频上传 end -->
- </div>
- </template>
-
- <script>
- import Quill from "quill";
- import "quill/dist/quill.core.css";
- import "quill/dist/quill.snow.css";
- import "quill/dist/quill.bubble.css";
- import { getToken } from "@/utils/auth";
- import {client, getFileNameUUID} from '@/utils/alioss';
-
- let fontFamily = ['SimSun', 'SimHei', 'Microsoft-YaHei', 'KaiTi', 'FangSong', 'Arial', 'Times-New-Roman', 'sans-serif'];
- Quill.imports['formats/font'].whitelist = fontFamily;
- Quill.register(Quill.imports['formats/font']);
- let fontSize = ['10px', '11px','12px', '14px', '15px', '16px', '17px', '18px', '20px', '24px', '36px']
- Quill.imports['attributors/style/size'].whitelist = fontSize;
- Quill.register(Quill.imports['attributors/style/size']);
-
- import Video from "./video.js";
- // import Buffer from "vue-buffer";
-
-
- Quill.register(Video, true);
-
-
-
- // 行高
- import { lineHeightStyle } from './lineHeight.js';
- Quill.register({ 'formats/lineHeight': lineHeightStyle }, true);
-
- // 行间距
- import { letterSpacingStyle } from './letterSpacing.js';
- Quill.register({ 'formats/letterSpacing': letterSpacingStyle }, true);
-
- Quill.register({ 'formats/lineHeight': lineHeightStyle }, true);
-
- export default {
- name: "Editor",
- 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,
- },
- /* 类型(base64格式、url格式) */
- type: {
- type: String,
- default: "url",
- },
- video: {
- type: String,
- default: "r",
- }
- },
- data() {
- return {
- aliyun :{},
- uploading : false,
- videoDialog: {show: false,activeName: null,videoLink:null},
- uploadUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
- headers: {
- Authorization: "Bearer " + getToken()
- },
- Quill: null,
- currentValue: "",
- options: {
- theme: "snow",
- bounds: document.body,
- debug: "warn",
- modules: {
- // 工具栏配置
- toolbar: {
- handlers: {
- // lineHeight: (value) => {
- // if (value) {
- // let quill = this.$refs.myQuillEditor.quill;
- // quill.format("lineHeight", value);
- // }
- // },
- // lineHeight :['initial', '1', '1.5', '1.75', '2', '3', '4', '5'],
- video: (value) => {
- this.videoDialog.show = true;
- },
- },
- container :
- [
- ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
- ["blockquote", "code-block"], // 引用 代码块
- [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
- [{ indent: "-1" }, { indent: "+1" }], // 缩进
- // [{ size: ["small", false, "large", "huge"] }], // 字体大小
- [{ size:fontSize }], // 字体大小
-
- // [{ size: [ "ten",false,"eleven", "twelve", "thirteen",
- // "fourteen", "fifteen", "sixteen", "seventeen",
- // "eighteen", "nineteen", "twenty"]}],
-
- [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
- [{ color: ['aqua', 'black', 'blue', 'brown', 'cyan', 'gold', 'gray', 'green', 'indigo', 'lavender', 'lime', 'magenta', 'maroon', 'navy', 'olive', 'orange', 'pink', 'purple', 'red', 'silver', 'teal', 'violet', 'white', 'yellow'] },
- { background: ['aqua', 'black', 'blue', 'brown', 'cyan', 'gold', 'gray', 'green', 'indigo', 'lavender', 'lime', 'magenta', 'maroon', 'navy', 'olive', 'orange', 'pink', 'purple', 'red', 'silver', 'teal', 'violet', 'white', 'yellow']
- }], // 字体颜色、字体背景颜色
- [{ align: [] }], // 对齐方式
- ["clean"], // 清除文本格式
- ["image", "video"], // 链接、图片、视频
- [{lineheight: ['initial', '1', '2', '3', '4', '5','20'] }],
- [{ letterSpacing: [ 'initial','2px','4px', '6px','8px','10px', '12px', '14px', '16px'],},], //行间距
- // ["link", "image", "video"] // 链接、图片、视频
-
- ],
- }
- },
-
- placeholder: "请输入内容",
- readOnly: this.readOnly,
-
-
- },
- };
- },
- computed: {
- styles() {
- let style = {};
- if (this.minHeight) {
- style.minHeight = `${this.minHeight}px`;
- }
- if (this.height) {
- style.height = `${this.height}px`;
- }
- return style;
- },
- },
- watch: {
- value: {
- handler(val) {
- if (val !== this.currentValue) {
- this.currentValue = val === null ? "" : val;
- if (this.Quill) {
- this.Quill.pasteHTML(this.currentValue);
- }
- }
- },
- immediate: true,
- },
- },
- mounted() {
-
- this.init();
-
- },
- methods: {
-
-
- // 上传文件之前
- videoHandleBeforeUpload(file) {
- const isJpgOrPng =
- file.type === 'video/ogg' ||
- file.type === 'video/flv' ||
- file.type === 'video/avi' ||
- file.type === 'video/wmv' ||
- file.type === 'video/mov' ||
- file.type === 'video/mp4'
- if (!isJpgOrPng) {
- this.$message.error('只能上传图片/视频!')
- return
- }
- },
- uploadURL(file) {
- //注意哦,这里指定文件夹'image/',尝试过写在配置文件,但是各种不行,写在这里就可以
- var fileName = 'imgs/'+'editor' + getFileNameUUID() + "." + file.file.name.replace(/.+\./, "");//'.jpg';
- client().multipartUpload(fileName, file.file,{
- progress: function(percentage, cpt) {
- console.log('打印进度',percentage)
- }
- }).then((res)=>{
- //此处赋值,是相当于上传成功之后,手动拼接服务器地址和文件名
- let quill = this.Quill;
- let length = quill.getSelection().index;
- console.log("quill.getSelection().index===",length);
- console.log(quill.getSelection());
- // 插入图片 res.url为服务器返回的图片地址
- quill.insertEmbed(length, "image", 'https://oss-cn-beijing.aliyuncs.com/' + fileName);
- // 调整光标到最后
- quill.setSelection(length + 1);
- })
- },
-
- init() {
- const editor = this.$refs.editor;
- this.Quill = new Quill(editor, this.options);
- // 如果设置了上传地址则自定义图片上传事件
- if (this.type == 'url') {
- let toolbar = this.Quill.getModule("toolbar");
- toolbar.addHandler("image", (value) => {
- this.uploadType = "image";
- if (value) {
- this.$refs.upload.$children[0].$refs.input.click();
- } else {
- this.quill.format("image", false);
- }
- });
- }
- //todo begin
- console.log("this.video",this.video);
- if (this.video == 'r') {
- let toolbar = this.Quill.getModule("toolbar");
- toolbar.addHandler("video", (value) => {
- this.uploadType = "video";
- console.log("value",value);
- if (value) {
- this.$refs.uploadVideo.$children[0].$refs.input.click();
- } else {
- this.quill.format("video", false);
- }
- });
- }
- //todo end
- this.Quill.pasteHTML(this.currentValue);
- this.Quill.on("text-change", (delta, oldDelta, source) => {
- const html = this.$refs.editor.children[0].innerHTML;
- const text = this.Quill.getText();
- const quill = this.Quill;
- this.currentValue = html;
- this.$emit("input", html);
- this.$emit("on-change", { html, text, quill });
- });
- this.Quill.on("text-change", (delta, oldDelta, source) => {
- this.$emit("on-text-change", delta, oldDelta, source);
- });
- this.Quill.on("selection-change", (range, oldRange, source) => {
- this.$emit("on-selection-change", range, oldRange, source);
- });
- this.Quill.on("editor-change", (eventName, ...args) => {
- this.$emit("on-editor-change", eventName, ...args);
- });
- },
- handleBeforeUpload(file) {
- const isJPEG = file.name.split('.')[1] === 'jpeg';
- const isJPG = file.name.split('.')[1] === 'jpg';
- const isPNG = file.name.split('.')[1] === 'png';
- const isWEBP = file.name.split('.')[1] === 'webp';
- const isGIF = file.name.split('.')[1] === 'gif';
- const isLt500K = file.size / 1024 / 1024 / 1024 / 1024 < 4;
- if (!isJPG && !isJPEG && !isPNG && !isWEBP && !isGIF) {
- this.$message.error('上传图片只能是 JPEG/JPG/PNG 格式!');
- }
- if (!isLt500K) {
- this.$message.error('单张图片大小不能超过 4mb!');
- }
- return (isJPEG || isJPG || isPNG || isWEBP || isGIF) && isLt500K;
- },
-
- uploadVideoURL(file) {
- //注意哦,这里指定文件夹'image/',尝试过写在配置文件,但是各种不行,写在这里就可以
- var fileName = 'imgs/'+'editor' + getFileNameUUID() + "." + file.file.name.replace(/.+\./, "");//'.jpg';
- client().multipartUpload(fileName, file.file,{
- progress: function(percentage, cpt) {
- // console.log('打印进度',percentage)
- }
- }).then((res)=>{
- //此处赋值,是相当于上传成功之后,手动拼接服务器地址和文件名
-
- this.videoDialog.show = false;
- // console.log("this.$parent.editor",this.$parent.editor);
-
-
- // let editor = this.$refs['editor'];
- // this.init();
- let quill = this.Quill;
- let lengthSelection = quill.getSelection().index;
- console.log("quill.getSelection().index===",lengthSelection);
-
- // console.log("this.$refs.editer.quill.selection.savedRange.index",this.$refs.editer.quill.selection.savedRange.index);
-
- console.log("quill.getLength()",quill.getLength());
- // 获取富文本
- // let range = quill.getSelection().index;
- // 获取光标位置:当编辑器中没有输入文本时,这里获取到的 range 为 null
- // let index = range ? range.index : 0
-
- // let quill = this.Quill;
-
- var length = quill.getLength();
- if(quill.getSelection()){
- length = quill.getSelection().index;
- // console.log("quill.getSelection().index===",length);
- }
- // console.log(quill.getSelection());
- let resp = 'https://oss-cn-beijing.aliyuncs.com/' + fileName;
-
-
- // 插入
- quill.insertEmbed(length, "video", resp);
- // 调整光标到最后
- quill.setSelection(length + 1);
-
-
-
-
- this.$forceUpdate();
- })
- },
-
- },
- };
-
- </script>
-
- <style>
- .editor, .ql-toolbar {
- white-space: pre-wrap !important;
- line-height: normal !important;
- }
- .quill-img {
- display: none;
- }
- .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";
- }
- /*todo begin*/
-
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='10px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='10px']::before {
- content: '10px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='11px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='11px']::before {
- content: '11px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='12px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='12px']::before {
- content: '12px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='14px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='14px']::before {
- content: '14px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='15px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='15px']::before {
- content: '15px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='16px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='16px']::before {
- content: '16px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='17px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='17px']::before {
- content: '17px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='18px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='18px']::before {
- content: '18px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='20px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='20px']::before {
- content: '20px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='24px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='24px']::before {
- content: '24px';
- }
- .ql-snow .ql-picker.ql-size .ql-picker-label[data-value='36px']::before,
- .ql-snow .ql-picker.ql-size .ql-picker-item[data-value='36px']::before {
- content: '36px';
- }
-
-
-
-
-
-
-
- /*todo end*/
- .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>
-
-
- <style>
- /* .ql-snow .ql-picker.ql-lineheight .ql-picker-label::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item::before {
- content: '行高';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="行高"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='initial']::before {
- content: '默认';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1']::before {
- content: '1px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1.5"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.5']::before {
- content: '1.5px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1.75"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='1.75']::before {
- content: '1.75px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="2"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='2']::before {
- content: '2px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="3"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='3']::before {
- content: '3px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="4"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='4']::before {
- content: '4px';
- }
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="5"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value='5']::before {
- content: '5px';
- }
- .ql-snow .ql-picker.ql-lineheight {
- width: 70px;
- }*/
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item::before {
- content: '字符间距';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="字符间距"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='initial']::before {
- content: '默认';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="2px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='2px']::before {
- content: '2px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="4px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='4px']::before {
- content: '4px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="6px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='6px']::before {
- content: '6px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="8px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='8px']::before {
- content: '8px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="10px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='10px']::before {
- content: '10px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="12px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='12px']::before {
- content: '12px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="14px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='14px']::before {
- content: '14px';
- }
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-label[data-value="16px"]::before,
- .ql-snow .ql-picker.ql-letterSpacing .ql-picker-item[data-value='16px']::before {
- content: '16px';
- }
- .ql-snow .ql-picker.ql-letterSpacing {
- width: 90px;
- }
-
- </style>
-
-
-
-
- <style>
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item::before {
- content: '行高';
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="1"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="1"]::before {
- content: "1";
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="2"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="2"]::before {
- content: "2";
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="3"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="3"]::before {
- content: "3";
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="4"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="4"]::before {
- content: "4";
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="5"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="5"]::before {
- content: "5";
- }
-
- .ql-snow .ql-picker.ql-lineheight .ql-picker-label[data-value="20"]::before,
- .ql-snow .ql-picker.ql-lineheight .ql-picker-item[data-value="20"]::before {
- content: "20";
- }
-
- .ql-snow .ql-picker.ql-lineheight {
- width: 70px;
- }
-
-
-
-
-
- </style>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
letterSpacing.js
- import Quill from 'quill'
- let Parchment = Quill.import('parchment')
- // 字符间距
- class letterSpacingAttributor extends Parchment.Attributor.Style {}
- const letterSpacingStyle = new letterSpacingAttributor(
- 'letter-spacing',
- 'letterSpacing',
- {
- scope: Parchment.Scope.INLINE,
- whitelist: [
- 'initial',
- '2px',
- '4px',
- '6px',
- '8px',
- '10px',
- '12px',
- '14px',
- '16px',
- ],
- }
- )
- export { letterSpacingStyle }
lineHeight.js
- import Quill from 'quill'
- let Parchment = Quill.import('parchment')
-
- // 行高
- class lineHeightAttributor extends Parchment.Attributor.Style {}
- const lineHeightStyle = new lineHeightAttributor(
- // 'line-height', 'lineHeight',
-
- // 'lineheight', 'ql-lineheight',
- 'lineheight', 'line-height',
-
-
- // 'line-height','lineheight',
-
- {
- scope: Parchment.Scope.INLINE,
- whitelist: ['initial', '1', '2', '3', '4', '5','20'],
- })
- export { lineHeightStyle }
-
-
-
-
quill-title.js
- const titleConfig = {
- 'ql-bold': '加粗',
- 'ql-color': '颜色',
- 'ql-font': '字体',
- 'ql-code': '插入代码',
- 'ql-italic': '斜体',
- 'ql-link': '添加链接',
- 'ql-background': '背景颜色',
- 'ql-size': '字体大小',
- 'ql-strike': '删除线',
- 'ql-script': '上标/下标',
- 'ql-underline': '下划线',
- 'ql-blockquote': '引用',
- 'ql-header': '标题',
- 'ql-indent': '缩进',
- 'ql-list': '列表',
- 'ql-align': '文本对齐',
- 'ql-direction': '文本方向',
- 'ql-code-block': '代码块',
- 'ql-formula': '公式',
- 'ql-image': '图片',
- 'ql-video': '视频',
- 'ql-clean': '清除字体样式',
- 'ql-lineheight': '行高',
- 'ql-letterSpacing': '字符间距',
- }
-
- export function addQuillTitle() {
- const oToolBar = document.querySelector('.ql-toolbar'),
- aButton = oToolBar.querySelectorAll('button'),
- aSelect = oToolBar.querySelectorAll('select')
- aButton.forEach(function (item) {
- if (item.className === 'ql-script') {
- item.value === 'sub' ? (item.title = '下标') : (item.title = '上标')
- } else if (item.className === 'ql-indent') {
- item.value === '+1'
- ? (item.title = '向右缩进')
- : (item.title = '向左缩进')
- } else {
- item.title = titleConfig[item.classList[0]]
- }
- })
- aSelect.forEach(function (item) {
- item.parentNode.title = titleConfig[item.classList[0]]
- })
- }
-
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);
- // 添加video标签所需的属性
- node.setAttribute("controls", "controls");
- node.setAttribute("type", "video/mp4");
- node.setAttribute("src", this.sanitize(value));
- //为了兼容 iOS 设备上,显示海报图(视频封面)
- node.setAttribute("preload", "metadata");
-
- // node.setAttribute("poster", value.poster);
- node.setAttribute("webkit-playsinline", "true");
-
- return node;
- }
- static formats(domNode) {
- return ATTRIBUTES.reduce((formats, attribute) => {
- if (domNode.hasAttribute(attribute)) {
- formats[attribute] = domNode.getAttribute(attribute);
- }
- return formats;
- }, {});
- }
- static sanitize(url) {
- return Link.sanitize(url); // eslint-disable-line import/no-named-as-default-member
- }
- static value(domNode) {
- return domNode.getAttribute("src");
- // return {
- // url: domNode.getAttribute('src'),
- // poster: domNode.getAttribute('poster')
- // }
- }
- 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}">${video}</a>`;
- }
- }
- Video.blotName = "video";
- Video.className = "ql-video";
- Video.tagName = "video"; // 用video标签替换iframe
- export default Video;