| | |
| | | <template> |
| | | <div> |
| | | <quill-editor |
| | | class="editor" |
| | | v-model="content" |
| | | ref="quillEditor" |
| | | :options="editorOptions" |
| | | ></quill-editor> |
| | | </div> |
| | | <div id='quillEditorQiniu'> |
| | | <!-- 基于elementUi的上传组件 el-upload begin--> |
| | | <el-upload |
| | | :accept="'image'" |
| | | :action="uploadImgUrl" |
| | | :before-upload="beforeEditorUpload" |
| | | :headers="headers" |
| | | :on-error="uploadEditorError" |
| | | :on-success="uploadEditorSuccess" |
| | | :show-file-list="false" |
| | | class="avatar-uploader"> |
| | | </el-upload> |
| | | <!-- 基于elementUi的上传组件 el-upload end--> |
| | | <quill-editor ref="customQuillEditor" v-model="content" :options="editorOption" class="editor"> |
| | | </quill-editor> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import {getToken} from "@/util/auth"; |
| | | |
| | | 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' }], // 缩进 |
| | | // [{'direction': 'rtl'}], // 文本方向 |
| | | [{ size: ['small', false, 'large', 'huge'] }], // 字体大小 |
| | | [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题 |
| | | [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色 |
| | | [{ font: [] }], // 字体种类 |
| | | [{ align: [] }], // 对齐方式 |
| | | ['clean'], // 清除文本格式 |
| | | // ['link', 'image', 'video'] // 链接、图片 |
| | | ['link', 'image'] // 链接、图片 |
| | | ] |
| | | ['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: []}], // 对齐方式 |
| | | ['link', 'image'], // 链接 图片 |
| | | ['clean'] // 清除文本格式 |
| | | ]; |
| | | export default { |
| | | name:'test', |
| | | data() { |
| | | return { |
| | | content: '', |
| | | editorOptions: { |
| | | // Quill编辑器的选项 |
| | | placeholder: '请输入内容!', |
| | | modules:{ |
| | | toolbar:{ |
| | | container:toolbarOptions |
| | | headers: { |
| | | Authorization: "Bearer " + getToken(), |
| | | }, |
| | | uploadImgUrl: "/v1/admin/common/upload", |
| | | uploadUrlPath: "没有文件上传", |
| | | quillUpdateImg: false, |
| | | content: '', //最终保存的内容 |
| | | editorOption: { |
| | | theme: 'snow', |
| | | placeholder: '请输入内容', |
| | | modules: { |
| | | toolbar: { |
| | | container: toolbarOptions, // 工具栏 |
| | | handlers: { |
| | | image: function (value) { |
| | | if (value) { |
| | | document.querySelector('#quillEditorQiniu .avatar-uploader input').click() |
| | | } else { |
| | | this.quill.format('image', false); |
| | | } |
| | | }, |
| | | link: function (value) { |
| | | if (value) { |
| | | const href = prompt('请输入链接地址:'); |
| | | this.quill.format('link', href) |
| | | } else { |
| | | this.quill.format('link', false) |
| | | } |
| | | }, |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | }; |
| | | }, |
| | | mounted() { |
| | | let self = this; |
| | | const editor = this.$refs.quillEditor.quill; |
| | | const toolbar = editor.getModule('toolbar'); |
| | | toolbar.addHandler('image', () => { |
| | | self.selectLocalImage(); |
| | | }); |
| | | }, |
| | | } |
| | | }, |
| | | methods: { |
| | | selectLocalImage() { |
| | | const input = document.createElement('input'); |
| | | input.setAttribute('type', 'file'); |
| | | input.click(); |
| | | input.onchange = () => { |
| | | const file = input.files[0]; |
| | | if (file) { |
| | | // 在这里调用你的图片上传逻辑,并获取图片的URL |
| | | // 假设你上传后得到了图片URL |
| | | const url = '你的图片URL'; |
| | | // 插入图片到编辑器 |
| | | this.insertToEditor(url); |
| | | } |
| | | }; |
| | | //上传图片之前async |
| | | beforeEditorUpload(file) { |
| | | const isJPG = file.type === 'image/jpeg' || file.type === 'image/png' || file.type === 'image/gif' |
| | | if (!isJPG) { |
| | | this.$message.error('上传图片只能是 JPG,PNG, GIF 格式!') |
| | | } else { |
| | | //显示上传动画 |
| | | this.quillUpdateImg = true; |
| | | } |
| | | }, |
| | | insertToEditor(url) { |
| | | const range = this.$refs.quillEditor.quill.getSelection(); |
| | | this.$refs.quillEditor.quill.insertEmbed(range.index, 'image', url); |
| | | // 上传图片成功 |
| | | uploadEditorSuccess(res, file) { |
| | | console.log("上传成功") |
| | | // this.$emit('upload',res, file) |
| | | console.log(res, file); |
| | | //拼接出上传的图片在服务器的完整地址 |
| | | let imgUrl = res.data.url; |
| | | let type = imgUrl.substring(imgUrl.lastIndexOf(".") + 1); |
| | | console.log(type); |
| | | // 获取富文本组件实例 |
| | | let quill = this.$refs.customQuillEditor.quill; |
| | | // 获取光标所在位置 |
| | | let length = quill.getSelection().index; |
| | | // 插入图片||视频 res.info为服务器返回的图片地址 |
| | | if (type == 'mp4' || type == 'MP4') { |
| | | quill.insertEmbed(length, 'video', imgUrl) |
| | | } else { |
| | | quill.insertEmbed(length, 'image', imgUrl) |
| | | } |
| | | // 调整光标到最后 |
| | | quill.setSelection(length + 1) |
| | | //取消上传动画 |
| | | this.quillUpdateImg = false; |
| | | }, |
| | | // 上传(文件)图片失败 |
| | | uploadEditorError(res, file) { |
| | | console.log(res); |
| | | console.log(file); |
| | | //页面提示 |
| | | this.$message.error('上传图片失败') |
| | | //取消上传动画 |
| | | this.quillUpdateImg = false; |
| | | }, |
| | | //上传组件返回的结果 |
| | | uploadResult: function (res) { |
| | | this.uploadUrlPath = res; |
| | | }, |
| | | openContent: function () { |
| | | console.log(this.content) |
| | | }, |
| | | |
| | | }, |
| | | created() { |
| | | |
| | | }, |
| | | //只执行一次,加载执行 |
| | | mounted() { |
| | | console.log("开始加载") |
| | | // 初始给编辑器设置title |
| | | }, |
| | | watch: { |
| | | content(newVal, oldVal) { |
| | | //this.$emit('input', newVal); |
| | | console.log(newVal) |
| | | console.log(oldVal) |
| | | } |
| | | } |
| | | }; |
| | | }, |
| | | |
| | | |
| | | } |
| | | </script> |
| | | <style lang="scss" scoped> |
| | | |
| | | <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="link"]::before { |
| | | content: "请输入链接地址:"; |
| | | } |
| | | |
| | | .ql-snow .ql-tooltip.ql-editing a.ql-action::after { |
| | | border-right: 0px; |
| | | content: "保存"; |
| | | padding-right: 0px; |
| | | } |
| | | |
| | | |
| | | .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> |