vue + quill富文本编辑器 实现自定义图片上传功能

2023-09-05 16:05:25 浏览数 (2)

前言

好久没更新博客了,主要最近一直在忙,一是工作比较多,二是在忙着写自己的‘墨客’项目。该项目前后端分离,后端使用laravel5.5 passport提供接口,前端使用vue2.5 axios vuex。最近在写到‘发布文章’的功能时候,遇到选择编辑器和定制编辑器问题,对比了之后选择quill。但是quill在上传图片时使用的是base64编码后的图片,这与我们的需求不符,于是决定自己定制化一下,ok,接下来开始正文。

代码实现

网上好多方法,但是没一个能用的,有的就算能用也根本不规范。

首先我需要定制化导航栏,其次我要定制化图片上传功能:

代码语言:javascript复制
<template>
    <div>
        <header-bar :title="title" :pre-page="prePage"></header-bar>
        <div>
            <input type="text" v-model="postTitle">
            <quill-editor
                v-model="postContent"
                ref="myQuillEditor"
                :options="editorOption"
                @blur="onEditorBlur($event)"
                @focus="onEditorFocus($event)"
                @change="onEditorChange($event)">
            </quill-editor>
            <button @click="submitPost">提交</button>
        </div>
        <tab-bar></tab-bar>
    </div>
</template>

<script>
    import HeaderBar from '../components/HeaderBar'
    import TabBar from '../components/TabBar'
    import Common from '../assets/js/common'
    import { Toast } from 'mint-ui';
    import  '../plugins/editor/vue-quill-editor'

    export default {
        name: 'Index',
        data () {
            return {
                title: '发布文章',
                prePage: '/',
                postTitle: '',
                postContent: '',
                editorOption: {
                    modules: {
                        toolbar: {
                            container:[
                                [{ 'header': [1, 2, 3, false] }],
                                ['bold', 'italic', 'underline', 'strike',],
                                ['blockquote', 'code-block', 'link', 'image',],
                                [{ 'color': [] }, { 'background': [] }],
                                [{ 'list': 'ordered'}, { 'list': 'bullet' }, { 'align': [] }],
                            ],
                            handlers: {'image': this.imageHandler}
                        }
                    },
                    placeholder: 'Compose an epic...',
                    readOnly: false,
                    theme: 'snow'
                },
            }
        },
        components: {
            HeaderBar,
            TabBar,
        },
        computed: {
            editor() {
                return this.$refs.myQuillEditor.quill
            }
        },
        mounted() {
            Common.checkLogin();
            // console.log('this is current quill instddddance object', this.editor)
        },
        methods: {
            onEditorBlur: function (quill) {
                // console.log('editor blur!', quill)
            },
            onEditorFocus: function (quill) {
                // console.log('editor focus!', quill)
            },
            onEditorChange: function ({ quill, html, text }) {
                // console.log('editor change!', quill, html, text)
                // this.postContent = html
            },
            submitPost: function () {
                console.log(this.postTitle);
                console.log(this.postContent);
            },
            imageHandler: function () {
                let input = document.createElement('input');
                input.setAttribute('type', 'file');
                input.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
                input.click();
                // 监听上传
                input.onchange = () => {
                    let file = input.files[0];
                    if (/^image//.test(file.type)) {
                        this.saveImage(file);
                    } else {
                        Toast('只能上传图片哦');
                    }
                };
            },
            saveImage: function (file) {
                let fd = new FormData();
                fd.append('image', file);

                let url = 'file/image';
                this.$http.post(url, fd).then(res => {
                    if (res.status === 201) {
                        this.insertImage(res.body.data)
                    }
                }, res => {
                    if (res.status !== 0) {
                        Toast(res.status   res.body.message)
                    }
                })
            },
            insertImage: function (url) {
                let range = this.editor.getSelection();
                this.editor.insertEmbed(range.index, 'image', url)
            }
        }
    }
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

首先我传入一个toolbar和一个handlers,toolbar可以自定义需要的功能,handlers可以‘重构’已有功能,根本不需要写什么html。

之后的逻辑是首先:调用imageHandler方法,进行初始化与文件验证;接着调用saveImage,请求接口,我的接口返回完整的图片链接;最后是使用quill的api进行插入。

OJBK!

0 人点赞