富文本编辑器:图片和文件可上传至服务器

1、需求:商家可上传平台规则(规则内容包含图片且可以放大伸缩、文件上传至服务器、可插入表格、插入代码等数据、数据不保存时可以直接预览、预览后直接发布也可以保存富文本编辑器中的内容,保存后数据展示在列表中再进行发布)

2、难点:

(1)因为上传图片时是base64位的,这样会导致数据量大,上传图片超过5张并且W数过大的话会导致服务器承受不住压力从而造成页面卡顿。

(2)插入表格后富文本编辑器中表格样式显示正常,但是预览时表格样式会失效。此时需要自定义表格样式。

(3)因为预览时数据还没有保存,此时需要先把富文本中输入的数据本地保存缓存下来。在预览页面再去取。

3、解决方式

(1)将图片上传至服务器,拿到图片的oss返回给后端,这样上传的数据量会小很多从而减轻服务器的压力。

(2)预览时表格的样式丢失,此时需要用深度选择器去修改。具体可以看以下代码。

(3)将富文本中的数据在点击预览按钮时用localStorage缓存下来,然后在预览的页面去取。

4、完整代码

!!! 力荐wangEditor 5编辑器

轻量级框架,容易修改,附上链接   wangEditor

编辑富文本页面

<template>
  <div class="rolseList">
    <div class="rules-content">
        <el-form-item label="规则内容" prop="content" required>
          <div style="border: 1px solid #ccc;">
                      <Toolbar style="border-bottom: 1px solid #ccc" :editor="editor" :defaultConfig="toolbarConfig" :mode="mode"/>
              <Editor style="height: 460px; overflow-y: hidden;" v-model="formData.content" :defaultConfig="editorConfig" :mode="mode"  
              @onCreated="onCreated" @onChange="onChange"/>
          </div>
        </el-form-item>
        <el-form-item class="oprition-btn">
          <el-button type="primary" @click="submitForm(formData)">保存</el-button>
          <el-button @click="preview(formData.content)">预览</el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>
<script>
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import '@wangeditor/editor/dist/css/style.css'
export default {
  components: {
    Editor, Toolbar
  },
  data() {
    return {
      //富文本编辑器相关配置
      editor: null,
      toolbarConfig: { 
         excludeKeys : [ 
            'group-video', //禁止上传视频,此时将上传视频的图标隐藏掉
            'fullScreen',//隐藏全屏
            // 'group-indent', //隐藏缩进按钮
            // 'indent',//向前缩进
            'codeBlock',//隐藏代码块
            // 'viewImageLink',//隐藏上传网图
            'delIndent' //减少缩进
        ]
      },
      editorConfig: { 
        placeholder: '请输入内容...',
         // 所有的菜单配置,都要在 MENU_CONF 属性下
          MENU_CONF: {
            // 配置上传图片
            uploadImage: {
               timeout: 5 * 1000, // 5s
                maxFileSize: 3 * 1024 * 1024, // 3M
                // base64LimitSize: 5 * 1024, // 5kb 以下插入 base64
                onBeforeUpload(files) {
                  return files; // 返回哪些文件可以上传
                  // return false 会阻止上传
                },
                // 用户自定义上传图片
                customUpload(file, insertFn) {
                  requestServer(file, "rules").then((res) => {
                    insertFn(res); //插入图片
                  });
                }
            }
          }
      },
      mode: 'default', // or 'simple'
    };
  },
  created() {
    this.getPlanList();
  },
   beforeDestroy() {
      const editor = this.editor
      if (editor == null) return
      editor.destroy() // 组件销毁时,及时销毁编辑器
  },
  methods: {
    onCreated(editor) {
      this.editor = Object.seal(editor) // 一定要用 Object.seal() ,否则会报错
    },
    onChange(editor) {
      this.$emit('change', JSON.stringify(editor.children), editor.getHtml())
    },
   
    submitForm(formData) {
      if (this.formData.content.length <= 11) {
        this.$message.info('请输入规则内容')
        return
      }
    },
    preview(formData) {
      if (this.formData.content.length <= 11) {
        this.$message.info('请输入规则内容')
        return
      }
      localStorage.setItem('quillContent',formData)
       const { href } = this.$router.resolve({
        //path是要跳转到的页面路径
        path: "preview",
        query: {
          type:4
        },
      });
       window.open(href, "_blank");
    },
  },
};
</script>
<style scoped lang='scss'>
.rolseList {
  padding: 10px 20px;
}
.rules-content{
  margin-top: 16px;
}

.span_type_detail {
  font-size: 14px;
  font-family: PingFangSC-Regular, PingFang SC;
  font-weight: 400;
  color: #1692FF;
  margin-left: 16px;
  cursor:pointer;
}
.oprition-btn{
  margin-top: 40px;
}
</style>

 预览富文本页面

<template>
  <div class="release">
    <div class="release-top" v-if="isRelease == 0 || isRelease == 2">
      <el-button type="primary" @click="release">一键发布</el-button>
    </div>
    <div
      style="margin-left: 76px; margin-right: 76px"
      class="ql-editor"
      v-html="quillContent"
    ></div>
  </div>
</template>
<script>

export default {
  data() {
    return {
      quillContent: "", //接收的富文本框的预览内容
      isRelease:null,
      type:null,//接收的规则内容 列表跳转过来的编辑为 3   ,新增时的编辑为 4
    };
  },
  created() {
    this.type = this.$route.query.type
    if (this.type == 3) {
      this.quillContent = this.$route.query.content
      this.isRelease = this.$route.query.isRelease
    }else if (this.type == 4) {
      this.quillContent = localStorage.getItem("quillContent");
      this.isRelease = 2
    }
  },
  methods: {
    release(){
      console.log('一键发布');
      //判断是新增发布,还是预览并发布,需要添加一个入参判断是在列表中发布还是预览时发布,列表需要+id,预览不需要
      // let msg = {
      //     rulesId:''
      // }
      // releaseRules(msg).then((res) => {
      //   if (res.status == 200) {
      //     this.$message({
      //       type: "success",
      //       message: "发布成功!",
      //     });
      //     this.$router.push('platformList')
      //   }
      // });
    }
  },
};
</script>
<style scoped lang='scss'>
.release-top{
  padding: 16px 80px;
  border-bottom: 1px solid #ccc;
  text-align: right;
}
.ql-editor{
 ::v-deep table {
  border: none;
  border-collapse: collapse;
}
::v-deep table td,
::v-deep table th {
  border: 1px solid #ccc;
  padding: 3px 5px;
  min-width: 50px;
  height: 20px;
}
::v-deep table th {
  border-right: 1px solid #ccc;
  border-bottom: 2px solid #ccc;
  text-align: center;
  background-color: #f1f1f1;
}
::v-deep ul,
ol {
  margin: 10px 0 10px 20px;
}
::v-deep pre {
  border: 1px solid #ccc;
  background-color: #f8f8f8;
  padding: 10px;
  margin: 5px 0px;
  font-size: 0.8em;
  border-radius: 3px;
}
::v-deep .ql-editor ul li {
  list-style-type: disc; // 解决序列li前面的.不展示问题
}
::v-deep .ql-editor ol li {
  list-style-type: decimal; // 解决序列li前面的数字不展示问题
}
}
</style>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值