当前位置:   article > 正文

Vue +vue-quill-editor+ Element UI使用富文本编辑器,上传图片,上传视频_elementui富文本编辑器

elementui富文本编辑器

如果你们有问题,可以发评论提问,我看见一定回复!!!!!

一、基本使用

1、下载vue-quill-editor组件
npm install vue-quill-editor -S
  • 1
2、引入· 富文本组件
  • 方式一:全局引入 (在 main.js文件中)
import Vue from 'vue'
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)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 方式二:按需引入 (在单个组件中引用)
import { quillEditor } from 'vue-quill-editor'

export default {
  components: {
    quillEditor
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
3、工具栏相关配置
const toolbarOptions = [
  ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  ["blockquote", "code-block", "formula"], // 引用  代码块 插入公式
  [{ header: 1 }, { header: 2 }], // 1、2 级标题
  [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  [{ script: "sub" }, { script: "super" }], // 上标/下标
  [{ indent: "-1" }, { indent: "+1" }], // 缩进
  [{ direction: "rtl" }], // 文本方向
  [{ size: [false,"14px","16px","18px","20px","22px","26px","28px","30p,] }], // 字体大小
  [{ header: [1, 2, 3, 4, 5,6, false] }], // 标题
  [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  [{ font: ["SimSun","SimHei","Microsoft-YaHei","KaiTi","FangSong","Arial","Times-New-Roman","sans-serif",] }], // 字体种类
  [{ align: [] }], // 对齐方式
  ["clean"], // 清除文本格式
  ["link", "image", "video", "report"], // 链接、图片、视频、自定义行为
];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
4、设置工具栏中文提示
setTitleConfig() {
    // toolbar标题
    const titleConfig = [
        { Choice: '.ql-insertMetric', title: '跳转配置' },
        { Choice: '.ql-bold', title: '加粗' },
        { Choice: '.ql-italic', title: '斜体' },
        { Choice: '.ql-underline', title: '下划线' },
        { Choice: '.ql-header', title: '段落格式' },
        { Choice: '.ql-strike', title: '删除线' },
        { Choice: '.ql-blockquote', title: '块引用' },
        { Choice: '.ql-code', title: '插入代码' },
        { Choice: '.ql-code-block', title: '插入代码段' },
        { Choice: '.ql-font', title: '字体' },
        { Choice: '.ql-size', title: '字体大小' },
        { Choice: '.ql-list[value="ordered"]', title: '编号列表' },
        { Choice: '.ql-list[value="bullet"]', title: '项目列表' },
        { Choice: '.ql-direction', title: '文本方向' },
        { Choice: '.ql-header[value="1"]', title: 'h1' },
        { Choice: '.ql-header[value="2"]', title: 'h2' },
        { Choice: '.ql-align', title: '对齐方式' },
        { Choice: '.ql-color', title: '字体颜色' },
        { Choice: '.ql-background', title: '背景颜色' },
        { Choice: '.ql-image', title: '图像' },
        { Choice: '.ql-video', title: '视频' },
        { Choice: '.ql-link', title: '添加链接' },
        { Choice: '.ql-formula', title: '插入公式' },
        { Choice: '.ql-clean', title: '清除字体格式' },
        { Choice: '.ql-script[value="sub"]', title: '下标' },
        { Choice: '.ql-script[value="super"]', title: '上标' },
        { Choice: '.ql-indent[value="-1"]', title: '向左缩进' },
        { Choice: '.ql-indent[value="+1"]', title: '向右缩进' },
        { Choice: '.ql-header .ql-picker-label', title: '标题大小' },
        { Choice: '.ql-header .ql-picker-item[data-value="1"]', title: '标题一' },
        { Choice: '.ql-header .ql-picker-item[data-value="2"]', title: '标题二' },
        { Choice: '.ql-header .ql-picker-item[data-value="3"]', title: '标题三' },
        { Choice: '.ql-header .ql-picker-item[data-value="4"]', title: '标题四' },
        { Choice: '.ql-header .ql-picker-item[data-value="5"]', title: '标题五' },
        { Choice: '.ql-header .ql-picker-item[data-value="6"]', title: '标题六' },
        { Choice: '.ql-header .ql-picker-item:last-child', title: '标准' },
         { Choice: '.ql-size .ql-picker-item[data-value="small"]', title: '小号' },
        { Choice: '.ql-size .ql-picker-item[data-value="large"]', title: '大号' },
        { Choice: '.ql-size .ql-picker-item[data-value="huge"]', title: '超大号' },
        { Choice: '.ql-size .ql-picker-item:nth-child(2)', title: '标准' },
        { Choice: '.ql-align .ql-picker-item:first-child', title: '居左对齐' },
        { Choice: '.ql-align .ql-picker-item[data-value="center"]', title: '居中对齐' },
        { Choice: '.ql-align .ql-picker-item[data-value="right"]', title: '居右对齐' },
        { Choice: '.ql-align .ql-picker-item[data-value="justify"]', title: '两端对齐' }
    ];
    for (const item of titleConfig) {
        const tip = document.querySelector(".quill-editor " + item.Choice);
        if (!tip) continue;
        tip.setAttribute("title", item.title);
    }
},

// 使用
mounted() {
    this.$nextTick(() => {
      this.setTitleConfig();
    });
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
5、修改vue-quill-editor字体及字号
  • 修改字体和字号
import { Quill } from "vue-quill-editor";
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.bubble.css'

//自定义样式一定要在原插件css下面引入
import "@/assets/css/quillEditor.css";
// 自定义字体大小
var sizes = [false,"14px","16px","18px","20px","22px","26px","28px","30px",];
var Size = Quill.import("formats/size");
Size.whitelist = sizes;
// 自定义字体
var fonts = ["SimSun","SimHei","Microsoft-YaHei","KaiTi","FangSong","Arial","Times-New-Roman","sans-serif",];
var Font = Quill.import("formats/font");
Font.whitelist = fonts;
Quill.register(Font, true);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 在assets/css文件夹下创建css文件quillEditor.css
/* 字体风格 */
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimSun"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimSun"]::before {
  content: "宋体";
  font-family: "SimSun";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="SimHei"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="SimHei"]::before {
  content: "黑体";
  font-family: "SimHei";
}

.ql-snow
  .ql-picker.ql-font
  .ql-picker-label[data-value="Microsoft-YaHei"]::before,
.ql-snow
  .ql-picker.ql-font
  .ql-picker-item[data-value="Microsoft-YaHei"]::before {
  content: "微软雅黑";
  font-family: "Microsoft YaHei";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="KaiTi"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="KaiTi"]::before {
  content: "楷体";
  font-family: "KaiTi";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="FangSong"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="FangSong"]::before {
  content: "仿宋";
  font-family: "FangSong";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="Arial"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="Arial"]::before {
  content: "Arial";
  font-family: "Arial";
}

.ql-snow
  .ql-picker.ql-font
  .ql-picker-label[data-value="Times-New-Roman"]::before,
.ql-snow
  .ql-picker.ql-font
  .ql-picker-item[data-value="Times-New-Roman"]::before {
  content: "Times New Roman";
  font-family: "Times New Roman";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="sans-serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="sans-serif"]::before {
  content: "sans-serif";
  font-family: "sans-serif";
}

.ql-font-SimSun { font-family: "SimSun"; }
.ql-font-SimHei { font-family: "SimHei"; }
.ql-font-Microsoft-YaHei { font-family: "Microsoft YaHei"; }
.ql-font-KaiTi { font-family: "KaiTi"; }
.ql-font-FangSong { font-family: "FangSong"; }
.ql-font-Arial { font-family: "Arial"; }
.ql-font-Times-New-Roman { font-family: "Times New Roman"; }
.ql-font-sans-serif { font-family: "sans-serif"; }

/* 字体大小 */
.ql-snow .ql-picker.ql-size .ql-picker-label::before { content: "字体大小"; }
.ql-snow .ql-picker.ql-size .ql-picker-item::before { content: "常规"; }
.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";
  font-size: 14px;
}

.ql-size-14px { font-size: 14px; }

.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";
  font-size: 16px;
}

.ql-size-16px { font-size: 16px; }

.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";
  font-size: 18px;
}

.ql-size-18px { font-size: 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";
  font-size: 20px;
}

.ql-size-20px { font-size: 20px; }

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="22px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="22px"]::before {
  content: "22px";
  font-size: 22px;
}

.ql-size-22px { font-size: 22px; }

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="26px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="26px"]::before {
  content: "26px";
  font-size: 26px;
}

.ql-size-26px { font-size: 26px; }

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="28px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="28px"]::before {
  content: "28px";
  font-size: 28px;
}

.ql-size-28px { font-size: 28px; }

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="30px"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="30px"]::before {
  content: "30px";
  font-size: 30px;
}

.ql-size-30px { font-size: 30px; }

/* 段落大小 */
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "常规";
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before {
  content: "标题大小";
}

/* 默认设置 */
.ql-snow .ql-editor { font-size: 14px; }
/* 查看样式 */
.view-editor .ql-toolbar { display: none; }
.view-editor .ql-container.ql-snow { border: 0; }
.view-editor .ql-container.ql-snow .ql-editor { padding: 0; }
/* 编辑样式 */
.edit-editor .ql-toolbar { display: block; }
.edit-editor .ql-container.ql-snow {
  border: 1px solid #ccc;
  min-height: inherit;
}

/* 自定义toobar样式设计 --- 根据情况设计 */
/* 工作汇报弹窗 */
.ql-snow.ql-toolbar .ql-formats .ql-report {
  background: url("@/assets/logo.png") no-repeat;
  background-size: contain;
  display: inline-block;
  height: 18px;
  margin: 3px 5px;
  width: 28px;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
6、在页面中使用组件
  • 基本使用quill-editor
<quill-editor
    v-model="content"
    ref="myQuillEditor"
    :options="editorOption"
    @blur="onEditorBlur($event)"
    @focus="onEditorFocus($event)"
    @change="onEditorChange($event)"
    @ready="onEditorReady($event)">
</quill-editor>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
<script>
import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";

// 导入自定义样式 一定要在原插件css下面引入  (看上面修改字体字号)
import "@/assets/css/quillEditor.css";
// 导入修改字体及字号 工具栏相关配置 设置工具栏中文提示(详细内容看下边)
import { titleConfig, toolbarOptions } from "@/assets/js/quillEditor";

export default {
  components: {
    quillEditor,
  },
  data() {
    return {
      content: ``, //双向数据绑定数据
      editorOption: {
        modules: {
          toolbar: {
            container: toolbarOptions, //工具栏相关配置
            handlers: {
              image: function (value) {
                if (value) {
                  alert("上传图片");
                  // 调用element的图片上传组件
                  document.querySelector(".avatar-uploader input").click();
                } else {
                  this.quill.format("image", false);
                }
              },
            },
          },
        },
        placeholder: "请输入正文....",
        theme: "snow", //主题 snow:有工具栏的;bubble:只有文本域的
      },
    };
  },
  methods: {
    // 失去焦点事件
    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("内容改变事件", quill, html, text);
      this.content = html;
    },
    
    //设置工具栏中文提示
    setTitleConfig() {
      for (const item of titleConfig) {
        const tip = document.querySelector(".quill-editor " + item.Choice);
        if (!tip) continue;
        tip.setAttribute("title", item.title);
        // 更改提示信息的内容
      }
    },
  },
  mounted() {
    this.$nextTick(() => {
      this.setTitleConfig();
    });
  },
};
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 在assets/js文件夹下创建js文件quillEditor.js
import { Quill } from "vue-quill-editor";
// 自定义字体大小
const sizes = [false,"14px","16px","18px","20px","22px","26px","28px","30px",];
const Size = Quill.import("formats/size");
Size.whitelist = sizes;
// 自定义字体
const fonts = ["SimSun","SimHei","Microsoft-YaHei","KaiTi","FangSong","Arial","Times-New-Roman","sans-serif",];
var Font = Quill.import("formats/font");
Font.whitelist = fonts;
Quill.register(Font, true);

// 工具栏相关配置
export const toolbarOptions = [
  ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线 
  ["blockquote", "code-block", "formula"], // 引用  代码块
  [{ header: 1 }, { header: 2 }], // 1、2 级标题
  [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  [{ script: "sub" }, { script: "super" }], // 上标/下标
  [{ indent: "-1" }, { indent: "+1" }], // 缩进
  [{ direction: "rtl" }], // 文本方向
  [{ size: sizes }], // 字体大小
  [{ header: [1, 2, 3, 4, 5, false] }], // 标题
  [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  [{ font: fonts }], // 字体种类
  [{ align: [] }], // 对齐方式
  ["clean"], // 清除文本格式
  ["link", "image", "video", "report"], // 链接、图片、视频、自定义行为
];

// 设置工具栏中文提示
export const titleConfig = [
  { Choice: ".ql-insertMetric", title: "跳转配置" },
  { Choice: ".ql-bold", title: "加粗" },
  { Choice: ".ql-italic", title: "斜体" },
  { Choice: ".ql-underline", title: "下划线" },
  { Choice: ".ql-header", title: "段落格式" },
  { Choice: ".ql-strike", title: "删除线" },
  { Choice: ".ql-blockquote", title: "块引用" },
  { Choice: ".ql-code", title: "插入代码" },
  { Choice: ".ql-code-block", title: "插入代码段" },
  { Choice: ".ql-font", title: "字体" },
  { Choice: '.ql-list[value="ordered"]', title: "编号列表" },
  { Choice: '.ql-list[value="bullet"]', title: "项目列表" },
  { Choice: ".ql-direction", title: "文本方向" },
  { Choice: '.ql-header[value="1"]', title: "h1" },
  { Choice: '.ql-header[value="2"]', title: "h2" },
  { Choice: ".ql-align", title: "对齐方式" },
  { Choice: ".ql-color", title: "字体颜色" },
  { Choice: ".ql-background", title: "背景颜色" },
  { Choice: ".ql-image", title: "图像" },
  { Choice: ".ql-video", title: "视频" },
  { Choice: ".ql-link", title: "添加链接" },
  { Choice: ".ql-formula", title: "插入公式" },
  { Choice: ".ql-clean", title: "清除字体格式" },
  { Choice: '.ql-script[value="sub"]', title: "下标" },
  { Choice: '.ql-script[value="super"]', title: "上标" },
  { Choice: '.ql-indent[value="-1"]', title: "向左缩进" },
  { Choice: '.ql-indent[value="+1"]', title: "向右缩进" },
  { Choice: ".ql-size .ql-picker-item:nth-child(2)", title: "标准" },
  { Choice: ".ql-align .ql-picker-item:first-child", title: "居左对齐" },
  {Choice: '.ql-align .ql-picker-item[data-value="center"]',title: "居中对齐",},
  {Choice: '.ql-align .ql-picker-item[data-value="right"]',title: "居右对齐",},
  {Choice: '.ql-align .ql-picker-item[data-value="justify"]',title: "两端对齐",},
];

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

二、扩展使用

1、上传图片 - 支持图片拖拽和放大缩小
  • 安装依赖包,包含编辑器包,拖拽包,缩放包

    npm i quill-image-drop-module  -S // 拖拽插件
    npm i quill-image-resize-module -S // 放大缩小插件
    
    • 1
    • 2
  • 在组件里引入使用:

    import { Quill } from "vue-quill-editor";
    import resizeImage from 'quill-image-resize-module' // 图片缩放组件引用
    import { ImageDrop } from 'quill-image-drop-module'; // 图片拖动组件引用
    Quill.register('modules/imageDrop', ImageDrop); // 注册
    Quill.register('modules/resizeImage ', resizeImage ) // 注册
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 设置editorOption对象

     // 富文本编辑器配置
        editorOption: {
            modules: {
              imageDrop: true,      // 图片拖拽
              imageResize: {        // 放大缩小
                displayStyles: {
                  backgroundColor: "black",
                  border: "none",
                  color: "white"
                },
                modules: ["Resize", "DisplaySize", "Toolbar"]
              },
              toolbar: {
                container: toolbarOptions, //工具栏
                handlers: {
                }
              },
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
  • 当按照按照以上步骤正确的引入各种插件后,会显示以下报错:
    在这里插入图片描述

  • 出现这个错误的原因是:插件需要配置webpack支持。

  • 修改根目录下的vue.config.js文件(需要重新运行一下项目)

    const { defineConfig } = require("@vue/cli-service");
    const webpack = require("webpack");
    
    module.exports = defineConfig({
      transpileDependencies: true,
      configureWebpack: {
        plugins: [
          new webpack.ProvidePlugin({
            "window.Quill": "quill/dist/quill.js",
            Quill: "quill/dist/quill.js",
          }),
        ],
      },
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
2、上传图片 - 图片动态上传到服务器
  • 组件内调用element的upload组件和vue-quill-editor编辑器
    <template>
      <div class="home">
        <!-- 图片上传组件辅助-->
        <el-upload
          class="avatar-uploader"
          :action="uploadUrl"
          name="files"
          :show-file-list="false"
          :on-success="uploadSuccess"
        >
        </el-upload>
        <!--富文本编辑器组件-->
        <quill-editor
          v-model="content"
          ref="myQuillEditor"
          :options="editorOption"
          @change="onEditorChange($event)"
        >
        </quill-editor>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
  • 配置editorOption对象(定义富文本编辑器内的图片上传按钮点击事件,当点击上传图片图标时,触发 upoad 组件的图片上传事件)
        uploadUrl: "#######", // 服务器上传地址
        content: ``, //双向数据绑定数据
        editorOption: {
            modules: {
              toolbar: {
                container: toolbarOptions, //工具栏
                handlers: {
                    image: function (value) {
                        if (value) {
                            alert("上传图片");
                            // 调用element的图片上传组件
                            document.querySelector(".avatar-uploader input").click();
                        } else {
                            this.quill.format("image", false);
                        }
                    },
                }
              },
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  • methods中,完善 upload图片上传成功事件。图片上传成功后,把图片加载到富文本编辑器内
    methods: {
        // 内容改变事件
        onEditorChange({ quill, html, text }) {
          console.log("内容改变事件", quill, html, text);
          this.content = html;
        },
        uploadSuccess(res) {
          console.log(res, "上传图片");
          // 获取富文本组件实例
          let quill = this.$refs.myQuillEditor.quill;
          // 如果上传成功
          if (res) {
            // 获取光标所在位置
            let length = quill.getSelection().index;
            // 插入图片,res为服务器返回的图片链接地址
            quill.insertEmbed(length, "image", res.data[0].servicePath);
            // 调整光标到最后
            quill.setSelection(length + 1);
          } else {
            // 提示信息,需引入Message
            this.$message.error("图片插入失败!");
          }
        },
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
3、上传视频 - 视频动态上传到服务器
  • 组件内调用element的upload组件和vue-quill-editor编辑器
    <template>
      <div class="home">
        <!-- 视频上传组件辅助 -->
        <el-dialog
          :close-on-click-modal="false"
          width="50%"
          style="margin-top: 1px"
          title="视频上传"
          :visible.sync="videoForm.show"
          append-to-body
        >
          <el-tabs v-model="videoForm.activeName">
            <el-tab-pane label="添加视频链接" name="first">
              <el-input
                v-model="videoForm.videoLink"
                placeholder="请输入视频链接"
                clearable
              ></el-input>
              <el-button
                type="primary"
                size="small"
                style="margin: 20px 0px 0px 0px"
                @click="insertVideoLink(videoForm.videoLink)"
                >确认
              </el-button>
            </el-tab-pane>
            <el-tab-pane label="本地视频上传" name="second">
              <el-upload
                v-loading="loading"
                style="text-align: center"
                drag
                :action="uploadUrl"
                accept="video/*"
                name="files"
                :before-upload="onBeforeUploadVideo"
                :on-success="onSuccessVideo"
                :on-error="onErrorVideo"
                :multiple="false"
              >
                <i class="el-icon-upload"></i>
                <div class="el-upload__text">
                  将文件拖到此处,或<em>点击上传</em>
                </div>
                <div class="el-upload__tip" slot="tip">
                  只能上传MP4文件,且不超过10M
                </div>
              </el-upload>
            </el-tab-pane>
          </el-tabs>
        </el-dialog>
        <!--富文本编辑器组件-->
        <quill-editor
          v-model="content"
          ref="myQuillEditor"
          :options="editorOption"
          @change="onEditorChange($event)"
        >
        </quill-editor>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
  • 配置editorOption对象(定义富文本编辑器内的视频上传按钮点击事件,当点击上传视频图标时,触发 upoad 组件的视频上传事件)
    	loading: false, // 加载loading
    	// 视频上传变量
        videoForm: {
          show: false, // 显示插入视频链接弹框的标识
          videoLink: "",
          activeName: "first",
        },
        uploadUrl: "#######", // 服务器上传地址
        content: ``, //双向数据绑定数据
        editorOption: {
            modules: {
              toolbar: {
                container: toolbarOptions, //工具栏
                handlers: {
                    video: () => {
    	                // 覆盖默认的上传视频,点击视频图标,显示弹窗
    	                this.videoForm.show = true;
              		},
                }
              },
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • methods中,完善 upload视频上传成功事件。视频上传成功后,把视频加载到富文本编辑器内
    methods: {
        hideLoading() {
      	 this.loading = false;
    	},
        // 内容改变事件
        onEditorChange({ quill, html, text }) {
          console.log("内容改变事件", quill, html, text);
          this.content = html;
        },
        insertVideoLink(videoLink) {
          if (!videoLink) return this.$message.error("视频地址不能为空!");
          this.videoForm.show = false;
          let quill = this.$refs["myQuillEditor"].quill;
          // 获取富文本
          let range = quill.getSelection();
          // 获取光标位置:当编辑器中没有输入文本时,这里获取到的 range 为 null
          let index = range ? range.index : 0;
          // 在光标所在位置 插入视频
          quill.insertEmbed(index, "video", videoLink);
          // 调整光标到最后
          quill.setSelection(index + 1);
        },
        // el-文件上传组件
        onBeforeUploadVideo(file) {
          this.loading = true;
          let acceptArr = ["video/mp4"];
          const isVideo = acceptArr.includes(file.type);
          const isLt1M = file.size / 1024 / 1024 < 10;
          if (!isVideo) {
            this.hideLoading();
            this.$message.error("只能上传mp4格式文件!");
          }
          if (!isLt1M) {
            this.hideLoading();
            this.$message.error(`上传文件大小不能超过 10MB!`);
          }
          return isLt1M && isVideo;
        },
        // 文件上传成功时的钩子
        onSuccessVideo(res) {
          this.hideLoading();
          if (res.code === 200) {
            this.insertVideoLink(res.data[0].servicePath);
          } else {
            this.$message.error(res.message);
          }
        },
        // 文件上传失败时的钩子
        onErrorVideo() {
          this.hideLoading();
          this.$message.error("上传失败");
        },
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
4、上传视频 - 修改视频 <iframe> 标签为 <video>
  • vue-quill-editor 默认是以 iframe 保存的。在assets/js文件夹下创建js文件quillVideo.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));
        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);
      }
    
      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}">${video}</a>`;
      }
    }
    Video.blotName = "video"; // 这里不用改,楼主不用iframe,直接替换掉原来,如果需要也可以保留原来的,这里用个新的blot
    Video.className = "ql-video";
    Video.tagName = "video"; // 用video标签替换iframe
    
    export default Video;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
  • 在页面中引入并注册
    import { quillEditor, Quill } from "vue-quill-editor";
    import "quill/dist/quill.core.css";
    import "quill/dist/quill.snow.css";
    import "quill/dist/quill.bubble.css";
    
    // 这里引入修改的video模块并注册
    import Video from "../assets/js/quillVideo";
    Quill.register(Video, true);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/544371
推荐阅读