如果你對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部分是沒有標籤包含的文本節點
基本上就是以上處理,具體細節需看完整代碼