動態插入後臺返回代碼並設置指定樣式(插入組件)

如果你對Vue render的使用方法不是很瞭解,則你需要先大概瞭解一下render,相信你閱讀了解完之後,下面的內容將是很容易明白

一.首先先貼出整體代碼

// styleConfig.vue文件
<script>
import CodeEditor from '@/lesson/component/CodeEditor.vue';

export default {
  functional: true,
  render: function(createElement, context) {
    function _htmlToElement(html) { // 生成dom對象
      var template = document.createElement('template');
      html = html.trim();
      template.innerHTML = html;
      return template.content.childNodes;
    }
    function _styleConfiguration(elems) {
      const children = [];
      elems.forEach(ele => {
        const tagName = ele.nodeName.toLocaleLowerCase();
        const parentTagName = ele.parentNode.nodeName.toLocaleLowerCase();
        if (ele.childNodes.length) { // 判斷節點是否有子節點
          if (tagName === 'code' && parentTagName === 'pre') { // 將code節點替換成CodeEditor組件
            children.push(createElement(CodeEditor, {
              props: {
                code: ele.innerText
              },
              style: {
                margin: '10px 0px',
                borderRadius: '5px',
                overflow: 'hidden'
              }
            }));
          } else {
            const domProps = {};
            if (tagName === 'a') { // 處理a標籤可能包含圖片的類似情況
              domProps.href = ele.href;
            }
            children.push(createElement(`${tagName}`, { domProps }, _styleConfiguration(ele.childNodes)));
          }
        } else {
          if (tagName !== '#comment') { // 節點不是註釋
            if (tagName === '#text') { // 文本節點處理
              if (ele.nodeValue) {
                children.push(createElement('span', `${ele.nodeValue}`));
              }
            } else { // 普通節點
              const domProps = {};
              if (tagName === 'img') {
                domProps.src = ele.src;
              }
              children.push(createElement(`${tagName}`, { domProps }, `${ele.nodeValue || ''}`));
            }
          }
        }
      });
      return children;
    }
    return createElement('div', {
      style: {
        lineHight: '24px'
      }
    }, _styleConfiguration(_htmlToElement(context.props.html)));
  }
};
</script>

二.接下來簡單分析一下
我們所做的處理主要是面對後臺返回數據是一段代碼,我們需要動態的插入並配置樣式,當然有的地方需要用特殊的組件來顯示。
-------------------後臺返回字符串如下----------------------

const htmlStr = "<h1>第一課左側內容</h1>\n<h2>head2</h2>\n<h3>head3</h3>\n<h4>head4</h4>\n<h5>head5</h5>\n<h6>head6</h6>\n<p>中文的<em>斜體斜體</em> 和 <strong>粗體粗體</strong></p>\n<blockquote><p>引用</p>\n<blockquote><p>二級引用</p>\n<blockquote><p>三級引用</p>\n</blockquote>\n</blockquote>\n</blockquote>\n<p><code>inline code haahh</code> is not a code</p>\n<ul>\n<li>list item 1</li>\n<li>list item 2</li>\n<li>list item 3</li>\n</ul>\n<ol>\n<li>list item 1</li>\n<li>list item 2</li>\n<li>list item 3</li>\n</ol>\n<p>This is an <a href=\"http://example.com/\">example link</a>.</p>\n<p><img src=\"https://res.kaikeba.com/other/123/20200402095710-91462/Fl38h-qh66AihsAbIs7rMqlEH0hv.png\" alt=\"文字\" title=\"Title\"></p>\n\n<pre><code>a = 1\nb = 2\nc = 3\n\nprint('hello, world')</code></pre>\n"

1.將傳回的字符串轉成dom對象

function _htmlToElement(html) {
  var template = document.createElement('template');
  html = html.trim();
  template.innerHTML = html;
  return template.content.children;
}

2.遍歷dom對象處理需要特殊處理的節點替換成指定的組件

function _styleConfiguration(elems) {
  	...
  return children;
}

3.配置樣式,返回的字符串轉換成dom之後需要配置設計給定的樣式,這個根據設計樣式自行處理

a{}
h1,h2,h3,h4{}
p{}
...

4.引入使用

<styleConfig :html="htmlStr"></styleConfig>

5.效果實現
在這裏插入圖片描述
注意點

代碼中之所以要處理文本節點是因爲有如下的代碼

<p><code>inline code haahh</code> is not a code</p>

代碼inline code haahh部分是沒有標籤包含的文本節點

基本上就是以上處理,具體細節需看完整代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章