使用vue-quill-editor + element-ui +Django 重新修改图片的上传方式

比话不多说,上图:

vue element 图片回显_上传


vue element 图片回显_图片上传_02

由于原生的vue-quill-editor 在img标签上处理的不是很好
点击插入图片以后,会将图片改成base64或者字节流,插入文本当中,因此整个文本会显得很大,当进行上传的时候,mysql存储的text字段的最大长度是65535,可能会因为文本超过域值,而报错,因此需要改写vue-quill-editor 的上传文件方法。

前端的vue组件如下:
html部分

<template>
  <div class="wirte">
    <!-- # 标题 -->
    <div class="tabbar" style="{background: white; }">
        <span>小小笔记本</span>
        <div class="right_wrapper">
            <router-link class="selection" to="/"><i class="el-icon-s-promotion "></i>首页</router-link>
            <div class="selection img_wrapper">
                <img class="head_img selection" :src="imgUrl" alt="">
                 {{ name }}
            </div>
        </div>
    </div>
    <div class="drop">
        <!-- 文章标题 -->
        <div class="_title">
            <router-link style="margin-left: 20px;" to="">   文章标题:</router-link>
            <el-input
                style="width: 400px; margin-left: 5px;"
                type="text"
                placeholder="请输入内容"
                v-model="title"
                maxlength="30"
                show-word-limit
            >
            </el-input>
            <button class="commit_button" type="primary" @click="commit_it">提交文章</button>
            <span>     
                字数:{{ content.length }}</span>
        </div>
          <!-- 图片上传组件辅助-->
        <el-upload
            class="avatar-uploader"
            :action="serverUrl"
            name="img"
            :headers="header"
            :show-file-list="false"
            :on-success="uploadSuccess"
            :on-error="uploadError"
            :before-upload="beforeUpload">
        </el-upload>

        <quill-editor 
            class="editor"
            v-model="content"
            ref="myQuillEditor" 
            :options="editorOption" 
            @blur="onEditorBlur($event)" @focus="onEditorFocus($event)"
            @change="onEditorChange($event)">
        </quill-editor> 
    </div>
  </div>
</template>

script 部分:

<script>
import Cookies from 'js-cookie';
import ImageResizes from 'quill-image-resize-module'
Quill.register('modules/imageResize', ImageResizes)


export default {
    name: 'write',
    data() {
        return {
            title: '',
            imgUrl: '',
            name: '',

            serverUrl: "http://127.0.0.1:8000/artical/addimage.htm", // 这里写你要上传的图片服务器地址
            header: {},
            quillUpdateImg: false, // 根据图片上传状态来确定是否显示loading动画,刚开始是false,不显示
            content: "",
            editorOption: {
                theme: 'snow',
                placeholder: '说点什么吧...',
                modules: {
                    toolbar: {
                        handlers: {
                            image: function(value) {
                                if (value) {
                                // 触发input框选择图片文件
                                document.querySelector(".avatar-uploader input").click();
                                } else {
                                    this.quill.format("image", false);
                                }
                            },
                        },
                        container: [
                            ["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"] // 链接、图片、视频
                        ],
                    },
                    imageResize: {
                        displayStyles: {
                            backgroundColor: "black",
                            border: "none",
                            color: "white",
                        },
                        modules: ["Resize", "DisplaySize", "Toolbar"],
                    },
                },
            }
        }
    },
    created() {
        // 获取头像
        this.imgUrl= '';
        this.getImgUrl();
    },
    methods: {
        // 提交文章
        commit_it() {
            this.$message.error("提交了提交了");
        },
        onEditorBlur() {
        //失去焦点事件
        },
        onEditorFocus() {
        //获得焦点事件
        },
        onEditorChange() {
        //内容改变事件
            this.$emit("input", this.content);
        },

        // 富文本图片上传前
        beforeUpload() {
        // 显示loading动画
            this.quillUpdateImg = true;
        },

        uploadSuccess(res, file) {
            // res为图片服务器返回的数据
            // 获取富文本组件实例
            let quill = this.$refs.myQuillEditor.quill;
            // 如果上传成功
            if (res.code == 200) {
                // 获取光标所在位置
                let length = quill.getSelection().index;
                // 插入图片  res.url为服务器返回的图片地址
                quill.insertEmbed(length, "image", res.url);
                // 调整光标到最后
                quill.setSelection(length + 1);
            } else {
                this.$message.error("图片插入失败");
            }
            // loading动画消失
            this.quillUpdateImg = false;
        },
        // 富文本图片上传失败
        uploadError() {
            // loading动画消失
            this.quillUpdateImg = false;
            this.$message.error("图片插入失败");
        },
        // 获取头像的地址
        getImgUrl() {
            var a = Cookies.get();
            // 遍历cookie的值
            for(let key in a){
                // console.log(key);
                if( a[key] === '1' ) {
                this.not_Login = false;
                this.name = key;
                // console.log('name: ' + this.name);
                break;
                }
            }
            // 查找cookie中有没有url的链接
            if( Cookies.get('img_url') ) {
                this.imgUrl = Cookies.get('img_url');
                
                return ;
            }
        },
    }
};
</script>

css 部分:

<style scoped>
.editor {
  line-height: normal !important;
  height: 500px;
}
._title {
    font-size: 16px;
    display: flex;
    /* justify-content: space-between; */
    width: 100%;
    height: 45px;
    line-height: 45px;
    background: #F2F2F2;
}
.commit_button {
    height: 35px;
    line-height: 35px;
    width: 80px;
    text-align: center;
    background: #2E9AFE;
    color: white;
    border-radius: 5px;
    border: 0px;
    margin-top: 5px;
    margin-left: 30px;
}
.right_wrapper {
    display: flex;
    width: 20%;
    justify-content: space-evenly;
}
.img_wrapper {
    margin-right: 20px;
}
*{
    margin: 0;
    padding: 0;
}
html{
    width: 100%;
    height: 100%;
}
.space_box {
    width: 35%;
    height: 550px;;
    margin: 70px auto;
}
.index {
    font-family:  -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";
    width:100%;
    height: 100%;
    position: absolute;
}
.drop {
  padding-top: 50px;
}
.editor {
  line-height: normal !important;
  height: 800px;
}
.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>

此时vue-quill-editor 的上传文件功能已经被改写了,将img文件的内容改成 了服务器里的 url ,这样大大节省了文本的长度

此时写后端的接口,文件服务器使用fastdfs,将request文件中包含的 FIle文件接收,然后,改成字节流,进行存储。
接口如下:

import os
from PIL import Image
from io import BytesIO

from django.http import HttpResponse, JsonResponse
from django.views import View
from Blog_Server.settings.dev import FDFS_URL
from Blog_Server.utils.fdfs.fastdfs_client import FDFSStorage

class addImage(View):

    def get(self, request):
        return HttpResponse("this is the addImage")

    def post(self, request):
        # 接收参数
        img = request.FILES.get('img')  # 获取到的是file类型的文件
        img_s = Image.open(img)
        img_s = img_s.resize((2140, 1080))
        img_byte = BytesIO()
        img_s.save(img_byte, format='PNG')  # format: PNG or JPEG
        binary_content = img_byte.getvalue()  # bytes
        # 图片存入fdfs服务器
        image_url = FDFSStorage()._save(binary_content, 'img')
        print(FDFS_URL+image_url)
        # 返回图片的存储地址
        # return JsonResponse({'code': 200, 'url': 'http://192.168.231.129:8888/group1/M00/00/00/wKjngWEBWIqASLhnAACBldwVS0g.v2-04e'})
        return JsonResponse({'code': 200, 'url': FDFS_URL+image_url})

这样就能将图片内容转成url存在富文本中了.
示例如下:

在这里插入图片描述:看字体数!!!

vue element 图片回显_python_03

解决报错

vue element 图片回显_上传_04


在build文件夹下的webpack.base.conf.js新增如下代码:

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