当前位置 博文首页 > weixin_33711647的博客:富文本上传七牛,如何把html转换为json

    weixin_33711647的博客:富文本上传七牛,如何把html转换为json

    作者:[db:作者] 时间:2021-08-08 13:15

    富文本

    vue-quill-editor

      需要下载vue-quill-editor模块,引入css和js
      npm i vue-quill-editor
      import "quill/dist/quill.core.css";
      import "quill/dist/quill.snow.css";
      import "quill/dist/quill.bubble.css";
      import {quillEditor} from "vue-quill-editor";
      
       <quill-editor
                  v-model="detailContent"
                  ref="myQuillEditor"
                  :options="editorOption"
                  @blur="onEditorBlur($event)"
                  @focus="onEditorFocus($event)"
                  @ready="onEditorReady($event)"
                ></quill-editor>
                //绑定的富文本内容
                
        <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>
              //elmentui 的插件
             /因为input file类型的特殊原因这里用elmentui 的插件来唤起上传图片 在beforeUpload钩子函数里传递file
             
         
        
    复制代码

    ###上传回调

        beforeUpload(e) {
                 this.fileChanges(e);
            }
    复制代码

    上传七牛代码

    //qiniu 此对象需要 <script src="https://unpkg.com/qiniu-js@2.5.3/dist/qiniu.min.js"></script> 引入七牛
    
     fileChanges(e) {
          var _t = this;
          let url = 'uploadxxx'
            var ext = e.type.split("/")[1];
            var formData = new FormData();
            formData.append("ext", ext);
            $.ajax({
              type: "get",
              async: false,
              url: url,
              data: {
                ext: ext,
              },
              dataType: "json",
              xhrFields: {
                withCredentials: true
              },
              success: function(data) {
                if (data.code === 0) {
                  var config = {
                    useCdnDomain: true,
                    region: qiniu.region.z1
                  };
    
                  var observable = qiniu.upload(
                    e,
                    data.info.keys[0],
                    data.info.token,
                    null,
                    config
                  );
                  _t.subscription = observable.subscribe({
                    next(res) {},
                    error(err) {
                      // ...
                    },
                    complete(res) {
                      // ...
                      let quill = _t.editor;
                      // 如果上传成功
    
                      // 获取光标所在位置
                      let length = quill.getSelection().index;
                      // 插入图片  res.info为服务器返回的图片地址
                      let str = quill.insertEmbed(
                        length,
                        "image",
                        data.info.bucketUrl + data.info.keys
                      );
                      // 调整光标到最后
                      quill.setSelection(length + 1);
    
                    }
                  });
                
                }
              },
              error: function(e) {
              }
            });
        
        }
        
    复制代码

    数据格式整理

    上传完了富文本结构可能是这样,图片地址显示base64 是预览,等到上传完成返回就会替换成服务器地址,因为最近接口有问题,所以显示的地址有问题,可以忽略。 这时候移动端没有富文本,移动端和pc都要显示这段内容,这时候就要统一格式了。要把上面的html解构转换为json格式,这里就要用到html2json了,他可以吧dom节点转换为父子级节点的json,使用起来很方便,如果自己去转换会有很多问题。至于转换的原理我想应该是递归查询节点,在生成树结构。没有认真去看码哈哈。

    移动端需要的格式
    newsRichText: "[{"state":"textasdasd"},{"state":"imaghttp://style.iis7.com/uploads/2021/08/12585618602.jpeg"}]"
    复制代码

    转码列子

    npm install html2json
    var html2json = require('html2json').html2json;
    var json2html = require('html2json').json2html;
    API
    json === html2json(document.body.innerHTML);
    html === json2html(json);
    
    console.assert(json === html);
    复制代码

    html

    
    <div id="1" class="foo">
    <h2>sample text with <code>inline tag</code></h2>
    <pre id="demo" class="foo bar">foo</pre>
    <pre id="output" class="goo">goo</pre>
    <input id="execute" type="button" value="execute"/>
    </div>
    复制代码

    json

    {
      node: 'root',
      child: [
        {
          node: 'element',
          tag: 'div',
          attr: { id: '1', class: 'foo' },
          child: [
            {
              node: 'element',
              tag: 'h2',
              child: [
                { node: 'text', text: 'sample text with ' },
                { node: 'element', tag: 'code', child: [{ node: 'text', text: 'inline tag' }] }
              ]
            },
            {
              node: 'element',
              tag: 'pre',
              attr: { id: 'demo', class: ['foo', 'bar'] },
              child: [{ node: 'text', text: 'foo' }]
            },
            {
              node: 'element',
              tag: 'pre',
              attr: { id: 'output', class: 'goo' },
              child: [{ node: 'text', text: 'goo' }]
            },
            {
              node: 'element',
              tag: 'input',
              attr: { id: 'execute', type: 'button', value: 'execute' }
            }
          ]
        }
      ]
    }
    复制代码

    转换

    //对插件生成的数据进行处理,处理成自己想要的格式  "[{"state":"textasdasd"},{"state":"imaghttp://style.iis7.com/uploads/2021/08/12590918603.jpeg"}]"
     release(types, bol = true) {
          let json = html2json(this.detailContent);
          let arr = [];
          for (let i of json.child) {
            for (let j of i.child) {
              if (j.node == "text") {
                let obj = {};
                let tex = "text" + j.text;
                obj.state = tex;
                arr.push(obj);
              } else if (j.tag == "img") {
                let obj = {};
                let tex = "imag" + j.attr.src;
                obj.state = tex;
                arr.push(obj);
              }
            }
          }
    复制代码
     var html2json = require("html2json").html2json;
    复制代码

    这样就完成了用elmentui在富文本中上传图片,并且将富文本转换为移动端可显示的内容,理论上后台应该保存两份格式的代码,一份是转换后的用于移动端读取,一份用来pc端显示,这样才能保证富文本的格式不变,样式不会出问题。所以需要两个字段,一个用于pc端读取,一个用于移动端读取。 感觉都是很棒的插件省了很多力气,尤其是这个富文本组件和转换格式插件,都很棒用起来,富文本是我用过最简单省力的富文本编辑器,强烈推荐。

    cs