统计
  • 建站日期:2019-12-01
  • 文章总数:2033 篇
  • 评论总数:2128 条
  • 分类总数:21 个
  • 最后更新:12月3日
文章 未分类

vue使用WangEdit富文本

程序员阿鑫
首页 未分类 正文

前言

在本文中笔者使用的是wangEditor,wangEditor是比较轻量级 web 富文本编辑器,配置方便,使用简单。 话不多说先看示例图

vue使用WangEdit富文本
-程序员阿鑫-带你一起秃头
-第1
张图片

一、vue引入富文本

npm install --save wangeditor

版本:3.1.1

二、使用步骤

1.自定义组件
代码如下(示例):

<template>
  <div>
    <div id="editor" ref="myEditor"></div>
    <slot></slot>
  </div>
</template>
<script>
  import WangEditor from 'wangeditor'
  export default {
    name: 'ComponentWangeditor',
    data () {
      return {
        edit: ''
      }
    },
    props: {
      value: {
        type: String,
        default: ''
      },
      config: {
        type: Array,
        default: () => {
          return {}
        }
      },
      uploadConfig: {
        type: Array,
        default: () => {
          return {
            method: 'http', // 支持custom(objurl)和http(服务器)和base64
            url: '/'
          }
        }
      }
    },
    computed: {
      customConfig () {
        return {
          pasteFilterStyle: false, // 关闭掉粘贴样式的过滤
          pasteIgnoreImg: false, // 粘贴时不忽略图片
          showLinkImg: false,
          menus:[          // 菜单配置
            'head',  // 标题
            'bold',  // 粗体
            'fontSize',  // 字号
            'fontName',  // 字体
            'italic',  // 斜体
            'underline',  // 下划线
            'strikeThrough',  // 删除线
            //'foreColor',  // 文字颜色
            //'backColor',  // 背景颜色
            //'link',  // 插入链接
            'list',  // 列表
            'justify',  // 对齐方式
            //'quote',  // 引用
            'emoticon',  // 表情
            'image',  // 插入图片
            // 'table',  // 表格
            // 'code',  // 插入代码
            'undo',  // 撤销
            'redo'  // 重复
          ],
          ...this.config
        }
      }
    },
    watch: {
      value: {
        deep: true,
        handler(val){
          this.editor.txt.html(val)// 生成编辑器
        }
      }

    },
    components: {},
    methods: {
      readBlobAsDataURL (blob, callback) {
        var a = new FileReader()
        a.onload = function (e) { callback(e.target.result) }
        a.readAsDataURL(blob)
      },
      initEditor () {
        var self = this
        this.editor = new WangEditor(this.$refs.myEditor)
        // 配置 onchange 事件
        this.editor.customConfig = this.customConfig
        // 将图片大小限制为 1M  2M的话就写2*1024*1024
        this.editor.customConfig.uploadImgMaxSize = 1 * 1024 * 1024
        //限制一次最多上传 1 张图片
        this.editor.customConfig.uploadImgMaxLength = 1
        this.editor.change = function () { // 编辑区域内容变化时
          self.$emit('input', this.txt.html())
          self.$emit('onchange', this.txt.html(), this.txt)
          // editor.txt.html('.....') //设置编辑器内容
          // editor.txt.clear() //清空编辑器内容
          // editor.txt.append('<p>追加的内容</p>')//继续追加内容。
          // editor.txt.text()  // 读取 text
          // editor.txt.getJSON()  // 获取 JSON 格式的内容
        }
        this.editor.customConfig.customUploadImg = function (files, insert) {
          if (self.uploadConfig.method === 'custom') {
            if (self.uploadConfig.callback) {
              self.uploadConfig.callback(files, insert)
            }
          }
          if (self.uploadConfig.method === 'base64') {
            files.forEach(file => {
              self.readBlobAsDataURL(file, function (dataurl) {
                insert(dataurl)
              })
            })
          }
          if (self.uploadConfig.method === 'http') {
            if (self.uploadConfig.callback) {
              self.uploadConfig.callback(files, insert)
            } else {
              var formData = new FormData()
              files.forEach(file => {
                formData.append('file', file)
              })
              self.$axios.post(self.uploadConfig.url, formData).then(({ data }) => {
                if (data.status === 'success') {
                  insert(data.url)
                }
              })
            }
          }
        }

        this.editor.create() // 生成编辑器
        this.editor.txt.text(this.value) // 生成编辑器
        this.$emit('oninit', this.editor)
      }
    },
    beforeCreate () {
    },
    created () {
    },
    beforeMount () {
    },
    mounted () {
      this.initEditor()
    }
  }
</script>

<style >
  .w-e-toolbar{
    flex-wrap:wrap;
  }

</style>

2.注册以及使用组件

代码如下(示例):

<template>
    <div>
        <antd-editor :uploadConfig="editorUploadConfig" v-model="editorContent" @onchange="changeEditor" @oninit="getEditor" />
    </div>
</template>

引入组件

import { AntdEditor } from '@/components'
<script>
  import { sysConsultiveEdit } from '@/api/modular/edu/consultiveManage'
  import { AntdEditor } from '@/components'
  import { imgUpload } from '@/api/modular/system/fileManage'
  export default {
    components: {
      AntdEditor
    },
    data() {
      return {
        editorContentText: '',
        editorUploadConfig: {
          method: 'custom',
          callback: this.editorUploadImage
        },
        editorContent: '',
        labelCol: {
          xs: {
            span: 24
          },
          sm: {
            span: 5
          }
        },
        wrapperCol: {
          xs: {
            span: 24
          },
          sm: {
            span: 15
          }
        },
        visible: false,
        confirmLoading: false,
        form: this.$form.createForm(this),
        loading: false,
        pic: ''
      }
    },
    methods: {
      /**
       * 编辑器回调上传及回传图片url
       */
      editorUploadImage (files, insert) {
        const formData = new FormData()
        files.forEach(file => {
          formData.append('file', file)
          formData.append('tag',"wangEdit")
        })
        imgUpload(formData).then((res) => {
          if (res.success) {
            insert(res.data)
          } else {
            this.$message.error('编辑器上传图片失败:' + res.message)
          }
        })
      },
      getEditor (editor) {
        this.editor = editor
      },
      changeEditor (html, ele) {
        this.editorContent = html
        this.editorContentText = ele.text()
      },
      selfUpload(data) {
        const formData = new FormData()
        formData.append('file', data.file)
        formData.append('tag', 'article')
        imgUpload(formData).then((res) => {
          if (res.success) {
            console.log(res.data)
            this.pic=res.data
            this.$message.success('上传成功')
          } else {
            this.$message.error('上传失败:' + res.message)
          }
        })
      },
      beforeUpload(file) {
        const isJPG = file.type === 'image/jpeg' || file.type === 'image/jpg' || file.type === 'image/png' || file.type ===
          'image/bmp'
        if (!isJPG) {
          this.$message.error('请上传图片文件');
        }
        const isLt2M = file.size / 1024 / 1024 < 1;
        if (!isLt2M) {
          this.$message.error('文件大小应小于 1M');
        }
        return isJPG && isLt2M
      },
      edit(record) {
        this.visible = true
        this.pic= record.pic
        this.test = decodeURIComponent(record.content)
        setTimeout(() => {
          this.form.setFieldsValue({
            aid: record.aid,
            catid: record.catid,
            title: record.title,
            summary: record.summary,
            pic: record.pic,
            content: decode(record.content),
            status: record.status,
            createTime: record.createTime,
            readNum: record.readNum,
            shareNum: record.shareNum,
            sortId: record.sortId,
            location: record.location,
          });
        }, 100)
      },
      handleSubmit() {
        const {
          form: {
            validateFields
          }
        } = this
        this.confirmLoading = true

        validateFields((errors, values) => {
          if (!errors) {
            values.content = this.editorContent
            sysConsultiveEdit(values).then((res) => {
              console.log(values)
              values.pic=this.pic
              this.confirmLoading = false
              if (res.code === 200) {
                this.$message.success('编辑成功')
                this.visible = false
                this.confirmLoading = false
                this.handleCancel()
                this.$emit('ok', values)
              } else {
                this.$message.info('编辑失败:' + res.message)
              }
            }).finally((res) => {
              this.confirmLoading = false
            })
          } else {
            this.confirmLoading = false
          }
        })
      },
      handleCancel() {
        this.form.resetFields()
        this.visible = false
      }
    }
  }
</script>

后端

1.controller ResponseData 是自己封装的请求响应实体

@Data
public class ResponseData {

    public static final String DEFAULT_SUCCESS_MESSAGE = "请求成功";

    public static final String DEFAULT_ERROR_MESSAGE = "网络异常";

    public static final String DEFAULT_ERROR_DATA_DUPLICATION="数据重复";

    public static final String REPEAT_SUBMIT="重复提交";

    public static final String DATA_EXCEPTION_ERROR="数据异常";

    public static final Integer DEFAULT_SUCCESS_CODE = 200;

    public static final Integer DEFAULT_ERROR_CODE = 500;

    /**
     * 请求是否成功
     */
    private Boolean success;

    /**
     * 响应状态码
     */
    private Integer code;

    /**
     * 响应信息
     */
    private String message;

    /**
     * 响应对象
     */
    private Object data;

    public ResponseData() {
    }

    public ResponseData(Boolean success, Integer code, String message, Object data) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public static SuccessResponseData success() {
        return new SuccessResponseData();
    }

    public static SuccessResponseData success(Object object) {
        return new SuccessResponseData(object);
    }

    public static SuccessResponseData success(Integer code, String message, Object object) {
        return new SuccessResponseData(code, message, object);
    }

    public static ErrorResponseData error(String message) {
        return new ErrorResponseData(message);
    }

    public static ErrorResponseData error(Integer code, String message) {
        return new ErrorResponseData(code, message);
    }

    public static ErrorResponseData error(Integer code, String message, Object object) {
        return new ErrorResponseData(code, message, object);
    }
}
@PostMapping("/sysFileInfo/uploadMsg")
@BusinessLog(title = "文件信息表_上传文件", opType = LogAnnotionOpTypeEnum.OTHER)
public ResponseData uploadMsg(@RequestPart("file") MultipartFile file, @RequestParam String tag) {
        re

Impl

 @Override
    public ResponseData uploadMsgFile(MultipartFile file, String tag) {
        // 获取文件后缀
        String fileSuffix = null;

        if (ObjectUtil.isNotEmpty(file.getOriginalFilename())) {
            fileSuffix = StrUtil.subAfter(file.getOriginalFilename(), SymbolConstant.PERIOD, true);
        }
        // 生成文件的最终名称
        String finalName = UUID.randomUUID().toString().replace("-","") + SymbolConstant.PERIOD + fileSuffix;

        // 存储文件
        byte[] bytes;
        try {
            bytes = file.getBytes();
            String s = OSSUtil.uploadBytes(bytes, tag + "/" + finalName);
            if(ObjectUtil.isNotNull(s)){
                return new SuccessResponseData(s);
            }
        } catch (IOException e) {
            throw new ServiceException(SysFileInfoExceptionEnum.ERROR_FILE);
        }
        return new SuccessResponseData(ResponseData.DEFAULT_ERROR_CODE, ResponseData.DEFAULT_ERROR_MESSAGE, SysFileInfoExceptionEnum.ERROR_FILE);
    }

3.文件上传OOS工具类

package com.zyedu.sys.core.aliyun;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.PutObjectRequest;
import com.zyedu.sys.config.AliyunConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

@Slf4j
@Component
public class OSSUtil {
    @Autowired
    private AliyunConfig ossConfig;

    public static OSSUtil ossUtil;

    @PostConstruct
    public void init() {
        ossUtil = this;
    }

    //获取OSSClient实例
    private static OSS getOSSClient() {
        OSS ossClient = new OSSClientBuilder().build(ossUtil.ossConfig.getEndpoint(), ossUtil.ossConfig.getAccessKeyId(), ossUtil.ossConfig.getAccessKeySecret());
        return ossClient;
    }

    /**
     * 本地文件方式上传
     *
     * @param file 文件
     * @param key  路径/名称
     */
    public static void uploadFile(File file, String key) {
        OSS ossClient = getOSSClient();
        // 上传文件流
        ossClient.putObject(ossUtil.ossConfig.getBucket(), key, file);
        // 关闭client
        ossClient.shutdown();
    }

    /**
     * MultipartFile方式上传
     *
     * @param file
     * @param key
     * @return
     * @throws IOException
     */
    public static String uploadPic(MultipartFile file, String key) throws IOException {
        OSS ossClient = getOSSClient();
        ossClient.putObject(ossUtil.ossConfig.getBucket(), key, file.getInputStream());
        ossClient.shutdown();
        return key;
    }

    /**
     * 字符串方式上传
     *
     * @param ctx
     * @param key
     */
    public static void uploadString(String ctx, String key) {
        OSS ossClient = getOSSClient();
        PutObjectRequest putObjectRequest = new PutObjectRequest(ossUtil.ossConfig.getBucket(), key, new ByteArrayInputStream(ctx.getBytes()));
        // 上传字符串。
        ossClient.putObject(putObjectRequest);
        // 关闭OSSClient。
        ossClient.shutdown();
    }

    /**
     * Byte数组方式上传
     *
     * @param content
     * @param key
     */
    public static String uploadBytes(byte[] content, String key) {
        OSS ossClient = getOSSClient();
        ossClient.putObject(ossUtil.ossConfig.getBucket(), key, new ByteArrayInputStream(content));
        // 关闭OSSClient
        ossClient.shutdown();
        return  ossUtil.ossConfig.getUrl()+key;
    }

    /**
     * 网络流方式上传
     *
     * @param uri
     * @param key
     * @throws IOException
     */
    public static void uploadInputUri(String uri, String key) throws IOException {
        OSS ossClient = getOSSClient();
        InputStream inputStream = new URL(uri).openStream();
        ossClient.putObject(ossUtil.ossConfig.getBucket(), key, inputStream);
        // 关闭OSSClient
        ossClient.shutdown();
    }

    // 删除文件
    public static void deleteFile(String key) {

        // 创建OSSClient实例
        OSS ossClient = getOSSClient();
        // 删除Object
        ossClient.deleteObject(ossUtil.ossConfig.getBucket(), key);
        // 关闭client
        ossClient.shutdown();

    }

    //获取存储对象的名字
    public static void listObject() {
        OSS ossClient = getOSSClient();
        // 获取指定bucket下的所有Object信息
        ObjectListing listing = ossClient.listObjects(ossUtil.ossConfig.getBucket());

        // 遍历所有Object
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            log.info(objectSummary.getKey());
        }
    }

}

4.AliyunConfig配置实体类

@Data
@Component
@ConfigurationProperties(prefix = "aliyun")
public class AliyunConfig {
    private String accessKeyId;
    private String accessKeySecret;
    private String endpoint;
    private String bucket;
    private String url;
}

5.application.yml配置文件

aliyun:
  accessKeyId:你的accessKeyId
  accessKeySecret: 你的accessKeySecret
  endpoint: https://oss-cn-shanghai.aliyuncs.com  //这个是示例
  bucket: 你的bucket

版权说明
文章采用: 《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权。
版权声明:未标注转载均为本站原创,转载时请以链接形式注明文章出处。如有侵权、不妥之处,请联系站长删除。敬请谅解!

-- 展开阅读全文 --
这篇文章最后更新于2021-12-21,已超过 1 年没有更新,如果文章内容或图片资源失效,请留言反馈,我们会及时处理,谢谢!
百度网盘青春版|速度起飞~【附下载】
« 上一篇
Android 查看app当前运行的线程
下一篇 »

发表评论

HI ! 请登录
注册会员,享受下载全站资源特权。
登陆
上号,带你一起秃头!

热门文章

最新文章

标签