From 6e421c2b522e7e035161beaf00af06d950658fca Mon Sep 17 00:00:00 2001
From: Administrator <admin>
Date: Wed, 09 Jun 2021 15:05:29 +0800
Subject: [PATCH] 资讯页面,详情新增

---
 components/feng-parse/components/wxParseTemplate5.vue  |  107 ++
 components/feng-parse/components/wxParseTable.vue      |   56 +
 components/feng-parse/components/wxParseTemplate0.vue  |  116 ++
 components/feng-parse/components/wxParseVideo.vue      |   55 +
 components/feng-parse/components/wxParseTemplate6.vue  |  107 ++
 components/feng-parse/components/wxParseImg.vue        |   94 +
 static/img/indexH.png                                  |    0 
 components/feng-parse/components/wxParseAudio.vue      |   28 
 components/feng-parse/libs/html2json.js                |  308 ++++++
 components/feng-parse/components/wxParseTemplate10.vue |  107 ++
 components/feng-parse/components/wxParseTemplate7.vue  |  107 ++
 static/img/index.png                                   |    0 
 components/feng-parse/parse.vue                        |  237 ++++
 components/feng-parse/parse.css                        |  258 +++++
 components/feng-parse/components/wxParseTemplate11.vue |  105 ++
 components/feng-parse/libs/htmlparser.js               |  156 +++
 components/feng-parse/components/wxParseTemplate3.vue  |  107 ++
 components/feng-parse/components/wxParseTemplate2.vue  |  107 ++
 components/feng-parse/components/wxParseTemplate8.vue  |  107 ++
 components/feng-parse/components/wxParseTemplate4.vue  |  107 ++
 components/feng-parse/components/wxParseTemplate1.vue  |  107 ++
 components/feng-parse/components/wxParseVideo1.vue     |   25 
 pages/article/article.vue                              |  163 +++
 components/feng-parse/libs/wxDiscode.js                |  209 ++++
 pages/article/article_detail.vue                       |  137 ++
 components/feng-parse/components/wxParseTemplate9.vue  |  107 ++
 26 files changed, 3,017 insertions(+), 0 deletions(-)

diff --git a/components/feng-parse/components/wxParseAudio.vue b/components/feng-parse/components/wxParseAudio.vue
new file mode 100644
index 0000000..b277717
--- /dev/null
+++ b/components/feng-parse/components/wxParseAudio.vue
@@ -0,0 +1,28 @@
+<template>
+	<!-- '<audio/>' 组件不再维护,建议使用能力更强的 'uni.createInnerAudioContext' 接口 有时间再改-->
+  <!--增加audio标签支持-->
+  <audio
+    :id="node.attr.id"
+    :class="node.classStr"
+    :style="node.styleStr"
+    :src="node.attr.src"
+    :loop="node.attr.loop"
+    :poster="node.attr.poster"
+    :name="node.attr.name"
+    :author="node.attr.author"
+    controls></audio>
+</template>
+
+<script>
+export default {
+  name: 'wxParseAudio',
+  props: {
+    node: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+  },
+};
+</script>
diff --git a/components/feng-parse/components/wxParseImg.vue b/components/feng-parse/components/wxParseImg.vue
new file mode 100644
index 0000000..50893c1
--- /dev/null
+++ b/components/feng-parse/components/wxParseImg.vue
@@ -0,0 +1,94 @@
+<template>
+	<image
+		mode="widthFix"
+		:lazy-load="node.attr.lazyLoad"
+		:class="node.classStr"
+		:style="newStyleStr || node.styleStr"
+		:data-src="node.attr.src"
+		:src="node.attr.src"
+		@tap="wxParseImgTap"
+		@load="wxParseImgLoad"
+	/>
+</template>
+
+<script>
+export default {
+	name: 'wxParseImg',
+	data() {
+		return {
+			newStyleStr: '',
+			preview: true
+		};
+	},
+	inject: ['parseWidth'],
+	mounted() {},
+	props: {
+		node: {
+			type: Object,
+			default() {
+				return {};
+			}
+		}
+	},
+	
+	methods: {
+		wxParseImgTap(e) {
+			if (!this.preview) return;
+			const { src } = e.currentTarget.dataset;
+			if (!src) return;
+			let parent = this.$parent;
+			while (!parent.preview || typeof parent.preview !== 'function') {
+				// TODO 遍历获取父节点执行方法
+				parent = parent.$parent;
+			}
+			parent.preview(src, e);
+		},
+		// 图片视觉宽高计算函数区
+		wxParseImgLoad(e) {
+			const { src } = e.currentTarget.dataset;
+			if (!src) return;
+			let { width, height } = e.mp.detail;
+
+			const recal = this.wxAutoImageCal(width, height);
+
+			const { imageheight, imageWidth } = recal;
+			const { padding, mode } = this.node.attr;//删除padding
+			// const { mode } = this.node.attr;
+
+			const { styleStr } = this.node;
+			const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;
+
+			if(!styleStr) this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;//删除padding
+			// this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px;`;
+		},
+		// 计算视觉优先的图片宽高
+		wxAutoImageCal(originalWidth, originalHeight) {
+			// 获取图片的原始长宽
+			const windowWidth = this.parseWidth.value;
+			const results = {};
+
+			if (originalWidth < 60 || originalHeight < 60) {
+				const { src } = this.node.attr;
+				let parent = this.$parent;
+				while (!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.removeImageUrl(src);
+				this.preview = false;
+			}
+
+			// 判断按照那种方式进行缩放
+			if (originalWidth > windowWidth) {
+				// 在图片width大于手机屏幕width时候
+				results.imageWidth = windowWidth;
+				results.imageheight = windowWidth * (originalHeight / originalWidth);
+			} else {
+				// 否则展示原来的数据
+				results.imageWidth = originalWidth;
+				results.imageheight = originalHeight;
+			}
+			return results;
+		}
+	}
+};
+</script>
diff --git a/components/feng-parse/components/wxParseTable.vue b/components/feng-parse/components/wxParseTable.vue
new file mode 100644
index 0000000..18278c9
--- /dev/null
+++ b/components/feng-parse/components/wxParseTable.vue
@@ -0,0 +1,56 @@
+<template>
+	<div class='tablebox'>
+		<rich-text :nodes="nodes" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+	</div>
+</template>
+<script>
+export default {
+	name: 'wxParseTable',
+	props: {
+		node: {
+			type: Object,
+			default() {
+				return {};
+			},
+		},
+	},
+	inject: ['parseSelect'],
+	data() {
+		return {
+			nodes:[]
+		};
+	},
+	mounted() {
+		this.nodes=this.loadNode([this.node]);
+	},
+	methods: {
+		loadNode(node) {
+			console.log(node)
+			let obj = [];
+			for (let children of node) {
+				if (children.node=='element') {
+					let t = {
+						name:children.tag,
+						attrs: {
+							class: children.classStr,
+							style: children.styleStr,
+						},
+						children: children.nodes?this.loadNode(children.nodes):[]
+					}
+					
+					obj.push(t)
+				} else if(children.node=='text'){
+					obj.push({
+						type: 'text',
+						text: children.text
+					})
+				}
+			}
+			return obj
+		}
+	}
+};
+</script>
+<style>
+	@import url("../parse.css");
+</style>
\ No newline at end of file
diff --git a/components/feng-parse/components/wxParseTemplate0.vue b/components/feng-parse/components/wxParseTemplate0.vue
new file mode 100644
index 0000000..5cbe790
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate0.vue
@@ -0,0 +1,116 @@
+<template>
+	<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+	
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+	// #ifdef APP-PLUS | H5
+	import wxParseTemplate from './wxParseTemplate0';
+	// #endif
+	// #ifdef MP
+	import wxParseTemplate from './wxParseTemplate1';
+	// #endif
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+
+	export default {
+		// #ifdef APP-PLUS | H5
+		name: 'wxParseTemplate',
+		// #endif
+		// #ifdef MP
+		name: 'wxParseTemplate0',
+		// #endif
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;// TODO currentTarget才有dataset
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {// TODO 遍历获取父节点执行方法
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate1.vue b/components/feng-parse/components/wxParseTemplate1.vue
new file mode 100644
index 0000000..70779e3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate1.vue
@@ -0,0 +1,107 @@
+<template>
+	<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate2';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate1',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate10.vue b/components/feng-parse/components/wxParseTemplate10.vue
new file mode 100644
index 0000000..891c8c3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate10.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate11';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate10',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate11.vue b/components/feng-parse/components/wxParseTemplate11.vue
new file mode 100644
index 0000000..d38efbd
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate11.vue
@@ -0,0 +1,105 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<rich-text :nodes="node" :class="node.classStr" :style="'user-select:' + parseSelect"></rich-text>
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate11',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate2.vue b/components/feng-parse/components/wxParseTemplate2.vue
new file mode 100644
index 0000000..c68b226
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate2.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text'">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate3';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate2',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate3.vue b/components/feng-parse/components/wxParseTemplate3.vue
new file mode 100644
index 0000000..1a1bb29
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate3.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate4';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate3',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate4.vue b/components/feng-parse/components/wxParseTemplate4.vue
new file mode 100644
index 0000000..c3497b8
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate4.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate5';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate4',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate5.vue b/components/feng-parse/components/wxParseTemplate5.vue
new file mode 100644
index 0000000..5e66618
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate5.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate6';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate5',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate6.vue b/components/feng-parse/components/wxParseTemplate6.vue
new file mode 100644
index 0000000..dc44621
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate6.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate7';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate6',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate7.vue b/components/feng-parse/components/wxParseTemplate7.vue
new file mode 100644
index 0000000..71636dc
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate7.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate8';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate7',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate8.vue b/components/feng-parse/components/wxParseTemplate8.vue
new file mode 100644
index 0000000..326115d
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate8.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate9';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate8',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseTemplate9.vue b/components/feng-parse/components/wxParseTemplate9.vue
new file mode 100644
index 0000000..f1224a3
--- /dev/null
+++ b/components/feng-parse/components/wxParseTemplate9.vue
@@ -0,0 +1,107 @@
+<template>
+		<!--判断是否是标签节点-->
+	<block v-if="node.node == 'element'">
+		<!--button类型-->
+		<button v-if="node.tag == 'button'" type="default" size="mini" :class="node.classStr" :style="node.styleStr">
+			<wx-parse-template :node="node" />
+		</button>
+		
+		<!--a类型-->
+		<view v-else-if="node.tag == 'a'" @click="wxParseATap(node.attr,$event)" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr" style="display: inline; border-bottom: 1px solid #555555;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--li类型-->
+		<view v-else-if="node.tag == 'li'" :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+		
+		<!--table类型-->
+		<wx-parse-table v-else-if="node.tag == 'table'" :class="node.classStr" :style="node.styleStr" :node="node" />
+		
+		<!--br类型-->
+		<!-- #ifndef H5 -->
+			<text v-else-if="node.tag == 'br'">\n</text>
+		<!-- #endif -->
+		<!-- #ifdef H5 -->
+			<br v-else-if="node.tag == 'br'">
+		<!-- #endif -->
+		
+		<!--video类型-->
+		<wx-parse-video :node="node" v-else-if="node.tag == 'video'"/>
+	
+		<!--audio类型-->
+		<wx-parse-audio :node="node" v-else-if="node.tag == 'audio'"/>
+	
+		<!--img类型-->
+		<wx-parse-img :node="node" v-else-if="node.tag == 'img'" :style="node.styleStr"/>
+		
+		<!--strong标签-->
+		<view v-else-if="node.tag == 'strong'" :class="node.classStr" :style="node.styleStr" style="font-weight: 700;display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--span标签-->
+		<view v-else-if="node.tag == 'span'" :class="node.classStr"  :style="node.styleStr" style="display: inline;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+		<!--em标签-->
+		<view v-else-if="node.tag == 'em'" :class="node.classStr"  :style="node.styleStr" style="display: inline;font-style: italic;">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node"/>
+			</block>
+		</view>
+	
+		<!--其他标签-->
+		<view v-else :class="node.classStr" :style="node.styleStr">
+			<block v-for="(node, index) of node.nodes" :key="index">
+				<wx-parse-template :node="node" />
+			</block>
+		</view>
+	</block>
+	
+	<!--判断是否是文本节点-->
+	<block v-else-if="node.node == 'text' ">{{node.text}}</block>
+</template>
+
+<script>
+	import wxParseTemplate from './wxParseTemplate10';
+	import wxParseImg from './wxParseImg';
+	import wxParseVideo from './wxParseVideo';
+	import wxParseAudio from './wxParseAudio';
+	import wxParseTable from './wxParseTable';
+	
+	export default {
+		name: 'wxParseTemplate9',
+		props: {
+			node: {},
+		},
+		components: {
+			wxParseTemplate,
+			wxParseImg,
+			wxParseVideo,
+			wxParseAudio,
+			wxParseTable
+		},
+		methods: {
+			wxParseATap(attr,e) {
+				const {
+					href
+				} = e.currentTarget.dataset;
+				if (!href) return;
+				let parent = this.$parent;
+				while(!parent.preview || typeof parent.preview !== 'function') {
+					parent = parent.$parent;
+				}
+				parent.navigate(href, e, attr);
+			}
+		}
+	};
+</script>
diff --git a/components/feng-parse/components/wxParseVideo.vue b/components/feng-parse/components/wxParseVideo.vue
new file mode 100644
index 0000000..1cd9b70
--- /dev/null
+++ b/components/feng-parse/components/wxParseVideo.vue
@@ -0,0 +1,55 @@
+<template>
+	<!-- 这个模板用来解决原生video总是浮在最上层的问题,使用view替换video,播放是再替换回,监听一个事件,用来被遮盖时做替换video -->
+  <!--增加video标签支持,并循环添加-->
+  <view @click="play">
+	  <view v-if="!playState" :class="node.classStr" :style="node.styleStr" style="display: inline-block;margin: auto;max-width: 100%;" class="video-video">
+		  <view style="display: flex;width: 100%;height:100%;flex-direction: row; justify-content: center;align-items: center;">
+			  <image src="https://gwbj.tongwenkeji.com/html/static/play.png" style="width: 20%;" mode="widthFix"></image>
+		  </view>
+	  </view>
+	  <video
+	  :autoplay="false" 
+	  :class="node.classStr" 
+	  :style="node.styleStr" 
+	  class="video-video"
+	  v-if="playState"
+	  :src="node.attr.src"></video>
+	  
+  </view>
+  
+</template>
+
+<script>
+export default {
+  name: 'wxParseVideo',
+  props: {
+    node: {},
+  },
+  data(){
+	  return{
+		  playState:true,
+		  videoStyle:'width: 100%;'
+	  }
+  },
+  methods:{
+	  play(){
+		  console.log('点击了video 播放')
+		  //显示播放器并播放播放器
+		  this.playState = !this.playState
+	  }
+  },
+  mounted() {
+	  //捕获侧滑菜单的遮盖行为,隐藏video
+  	uni.$on('slideMenuShow',e=>{
+		console.log('捕获事件:'+e)
+		if(e == 'show' && this.playState){
+			//正在播放则停止
+			this.playState = false
+		}
+	})
+  }
+};
+</script>
+<style>
+	.video-video{background: #000000;}
+</style>
diff --git a/components/feng-parse/components/wxParseVideo1.vue b/components/feng-parse/components/wxParseVideo1.vue
new file mode 100644
index 0000000..0d37e10
--- /dev/null
+++ b/components/feng-parse/components/wxParseVideo1.vue
@@ -0,0 +1,25 @@
+<template>
+	<!-- 这个模板用来渲染原生video -->
+  <!--增加video标签支持,并循环添加-->
+  <view style="max-width: 100%;">
+	<video
+	:autoplay="playState" 
+	:class="node.classStr" 
+	:style="node.styleStr" 
+	class="video-video"
+	v-if="playState"
+	:src="node.attr.src"></video>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'wxParseVideo',
+  props: {
+    node: {},
+  }
+};
+</script>
+<style>
+	.video-video{z-index: 1;}
+</style>
diff --git a/components/feng-parse/libs/html2json.js b/components/feng-parse/libs/html2json.js
new file mode 100644
index 0000000..bf3082d
--- /dev/null
+++ b/components/feng-parse/libs/html2json.js
@@ -0,0 +1,308 @@
+/**
+ * html2Json 改造来自: https://github.com/Jxck/html2json
+ *
+ *
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ *               垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+
+import wxDiscode from './wxDiscode';
+import HTMLParser from './htmlparser';
+
+function makeMap(str) {
+	const obj = {};
+	const items = str.split(',');
+	for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
+	return obj;
+}
+
+// Block Elements - HTML 5
+const block = makeMap(
+	'br,code,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'
+);
+
+// Inline Elements - HTML 5
+const inline = makeMap(
+	'a,abbr,acronym,applet,b,basefont,bdo,big,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'
+);
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
+
+function removeDOCTYPE(html) {
+	const isDocument = /<body.*>([^]*)<\/body>/.test(html);
+	return isDocument ? RegExp.$1 : html;
+}
+
+function trimHtml(html) {
+	return html
+		.replace(/<!--.*?-->/gi, '')
+		.replace(/\/\*.*?\*\//gi, '')
+		// .replace(/[ ]+</gi, '<')
+		.replace(/<script[^]*<\/script>/gi, '')
+		.replace(/<style[^]*<\/style>/gi, '');
+}
+
+function getScreenInfo() {
+	const screen = {};
+	wx.getSystemInfo({
+		success: (res) => {
+			screen.width = res.windowWidth;
+			screen.height = res.windowHeight;
+		},
+	});
+	return screen;
+}
+
+function html2json(html, customHandler, imageProp, host) {
+	// 处理字符串
+	html = removeDOCTYPE(html);
+	html = trimHtml(html);
+	html = wxDiscode.strDiscode(html);
+	// 生成node节点
+	const bufArray = [];
+	const results = {
+		nodes: [],
+		imageUrls: [],
+	};
+
+	const screen = getScreenInfo();
+
+	function Node(tag) {
+		this.node = 'element';
+		this.tag = tag;
+
+		this.$screen = screen;
+	}
+
+	HTMLParser(html, {
+		start(tag, attrs, unary) {
+			// node for this element
+			const node = new Node(tag);
+
+			if (bufArray.length !== 0) {
+				const parent = bufArray[0];
+				if (parent.nodes === undefined) {
+					parent.nodes = [];
+				}
+			}
+
+			if (block[tag]) {
+				node.tagType = 'block';
+			} else if (inline[tag]) {
+				node.tagType = 'inline';
+			} else if (closeSelf[tag]) {
+				node.tagType = 'closeSelf';
+			}
+
+			node.attr = attrs.reduce((pre, attr) => {
+				const {
+					name
+				} = attr;
+				let {
+					value
+				} = attr;
+				if (name === 'class') {
+					node.classStr = value;
+				}
+				// has multi attibutes
+				// make it array of attribute
+				if (name === 'style') {
+					node.styleStr = value;
+				}
+				if (value.match(/ /)) {
+					value = value.split(' ');
+				}
+
+				// if attr already exists
+				// merge it
+				if (pre[name]) {
+					if (Array.isArray(pre[name])) {
+						// already array, push to last
+						pre[name].push(value);
+					} else {
+						// single value, make it array
+						pre[name] = [pre[name], value];
+					}
+				} else {
+					// not exist, put it
+					pre[name] = value;
+				}
+
+				return pre;
+			}, {});
+
+			// 优化样式相关属性
+			if (node.classStr) {
+				node.classStr += ` ${node.tag}`;
+			} else {
+				node.classStr = node.tag;
+			}
+			if (node.tagType === 'inline') {
+				node.classStr += ' inline';
+			}
+
+			// 对img添加额外数据
+			if (node.tag === 'img') {
+				let imgUrl = node.attr.src;
+				imgUrl = wxDiscode.urlToHttpUrl(imgUrl, imageProp.domain);
+				Object.assign(node.attr, imageProp, {
+					src: imgUrl || '',
+				});
+				if (imgUrl) {
+					results.imageUrls.push(imgUrl);
+				}
+			}
+
+			// 处理a标签属性
+			if (node.tag === 'a') {
+				node.attr.href = node.attr.href || '';
+			}
+
+			//处理table
+			if (node.tag === 'table' || node.tag === 'tr' || node.tag === 'td') {
+				node.styleStr = ""
+				if (node.attr.width) {
+					node.styleStr += "width:" + node.attr.width + 'px;'
+					if (node.attr.width > node.$screen.width) {
+						//等比缩放height
+						if (node.attr.height) {
+							node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width
+						}
+					}
+				}
+				if (node.attr.height) {
+					node.styleStr += "height:" + node.attr.height + 'px;'
+				}
+
+			}
+			//处理video
+			if (node.tag === 'video') {
+				node.styleStr = ""
+				if (node.attr.width) {
+					node.styleStr += "width:" + node.attr.width + 'px;'
+					if (node.attr.width > node.$screen.width) {
+						//等比缩放height
+						if (node.attr.height) {
+							node.attr.height = (node.$screen.width * node.attr.height) / node.attr.width
+						}
+					}
+				}
+				if (node.attr.height) {
+					node.styleStr += "height:" + node.attr.height + 'px;'
+				}
+
+			}
+
+			// 处理font标签样式属性
+			if (node.tag === 'font') {
+				const fontSize = [
+					'x-small',
+					'small',
+					'medium',
+					'large',
+					'x-large',
+					'xx-large',
+					'-webkit-xxx-large',
+				];
+				const styleAttrs = {
+					color: 'color',
+					face: 'font-family',
+					size: 'font-size',
+				};
+				if (!node.styleStr) node.styleStr = '';
+				Object.keys(styleAttrs).forEach((key) => {
+					if (node.attr[key]) {
+						const value = key === 'size' ? fontSize[node.attr[key] - 1] : node.attr[key];
+						node.styleStr += `${styleAttrs[key]}: ${value};`;
+					}
+				});
+			}
+
+			// 临时记录source资源
+			if (node.tag === 'source') {
+				results.source = node.attr.src;
+			}
+			//#ifndef MP-BAIDU
+			if (customHandler.start) {
+				customHandler.start(node, results);
+			}
+			//#endif
+
+			if (unary) {
+				// if this tag doesn't have end tag
+				// like <img src="hoge.png"/>
+				// add to parents
+				const parent = bufArray[0] || results;
+				if (parent.nodes === undefined) {
+					parent.nodes = [];
+				}
+				parent.nodes.push(node);
+			} else {
+				bufArray.unshift(node);
+			}
+		},
+		end(tag) {
+			// merge into parent tag
+			const node = bufArray.shift();
+			if (node.tag !== tag) {
+				console.error('invalid state: mismatch end tag');
+			}
+
+			// 当有缓存source资源时于于video补上src资源
+			if (node.tag === 'video' && results.source) {
+				node.attr.src = results.source;
+				delete results.source;
+			}
+			//#ifndef MP-BAIDU
+			if (customHandler && customHandler.end) {
+				customHandler.end(node, results);
+			}
+			//#endif
+
+			if (bufArray.length === 0) {
+				results.nodes.push(node);
+			} else {
+				const parent = bufArray[0];
+				if (!parent.nodes) {
+					parent.nodes = [];
+				}
+				parent.nodes.push(node);
+			}
+		},
+		chars(text) {
+			if (!text.trim()) return;
+
+			const node = {
+				node: 'text',
+				text,
+			};
+			//#ifndef MP-BAIDU
+			if (customHandler.chars) {
+				customHandler.chars(node, results);
+			}
+			//#endif
+
+			if (bufArray.length === 0) {
+				results.nodes.push(node);
+			} else {
+				const parent = bufArray[0];
+				if (parent.nodes === undefined) {
+					parent.nodes = [];
+				}
+				parent.nodes.push(node);
+			}
+		},
+	});
+
+	return results;
+}
+
+export default html2json;
diff --git a/components/feng-parse/libs/htmlparser.js b/components/feng-parse/libs/htmlparser.js
new file mode 100644
index 0000000..2939da3
--- /dev/null
+++ b/components/feng-parse/libs/htmlparser.js
@@ -0,0 +1,156 @@
+/**
+ *
+ * htmlParser改造自: https://github.com/blowsie/Pure-JavaScript-HTML5-Parser
+ *
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ *               垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+// Regular Expressions for parsing tags and attributes
+
+const startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z0-9_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
+const endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
+const attr = /([a-zA-Z0-9_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g;
+
+function makeMap(str) {
+  const obj = {};
+  const items = str.split(',');
+  for (let i = 0; i < items.length; i += 1) obj[items[i]] = true;
+  return obj;
+}
+
+// Empty Elements - HTML 5
+const empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr');
+
+// Block Elements - HTML 5
+const block = makeMap('address,code,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video');
+
+// Inline Elements - HTML 5
+const inline = makeMap('a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var');
+
+// Elements that you can, intentionally, leave open
+// (and which close themselves)
+const closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr');
+
+// Attributes that have their values filled in disabled="disabled"
+const fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected');
+
+function HTMLParser(html, handler) {
+  let index;
+  let chars;
+  let match;
+  let last = html;
+  const stack = [];
+
+  stack.last = () => stack[stack.length - 1];
+
+  function parseEndTag(tag, tagName) {
+    // If no tag name is provided, clean shop
+    let pos;
+    if (!tagName) {
+      pos = 0;
+    } else {
+      // Find the closest opened tag of the same type
+      tagName = tagName.toLowerCase();
+      for (pos = stack.length - 1; pos >= 0; pos -= 1) {
+        if (stack[pos] === tagName) break;
+      }
+    }
+    if (pos >= 0) {
+      // Close all the open elements, up the stack
+      for (let i = stack.length - 1; i >= pos; i -= 1) {
+        if (handler.end) handler.end(stack[i]);
+      }
+
+      // Remove the open elements from the stack
+      stack.length = pos;
+    }
+  }
+
+  function parseStartTag(tag, tagName, rest, unary) {
+    tagName = tagName.toLowerCase();
+
+    if (block[tagName]) {
+      while (stack.last() && inline[stack.last()]) {
+        parseEndTag('', stack.last());
+      }
+    }
+
+    if (closeSelf[tagName] && stack.last() === tagName) {
+      parseEndTag('', tagName);
+    }
+
+    unary = empty[tagName] || !!unary;
+
+    if (!unary) stack.push(tagName);
+
+    if (handler.start) {
+      const attrs = [];
+
+      rest.replace(attr, function genAttr(matches, name) {
+        const value = arguments[2] || arguments[3] || arguments[4] || (fillAttrs[name] ? name : '');
+
+        attrs.push({
+          name,
+          value,
+          escaped: value.replace(/(^|[^\\])"/g, '$1\\"'), // "
+        });
+      });
+
+      if (handler.start) {
+        handler.start(tagName, attrs, unary);
+      }
+    }
+  }
+
+  while (html) {
+    chars = true;
+
+    if (html.indexOf('</') === 0) {
+      match = html.match(endTag);
+
+      if (match) {
+        html = html.substring(match[0].length);
+        match[0].replace(endTag, parseEndTag);
+        chars = false;
+      }
+
+      // start tag
+    } else if (html.indexOf('<') === 0) {
+      match = html.match(startTag);
+
+      if (match) {
+        html = html.substring(match[0].length);
+        match[0].replace(startTag, parseStartTag);
+        chars = false;
+      }
+    }
+
+    if (chars) {
+      index = html.indexOf('<');
+      let text = '';
+      while (index === 0) {
+        text += '<';
+        html = html.substring(1);
+        index = html.indexOf('<');
+      }
+      text += index < 0 ? html : html.substring(0, index);
+      html = index < 0 ? '' : html.substring(index);
+
+      if (handler.chars) handler.chars(text);
+    }
+
+    if (html === last) throw new Error(`Parse Error: ${html}`);
+    last = html;
+  }
+
+  // Clean up any remaining tags
+  parseEndTag();
+}
+
+export default HTMLParser;
diff --git a/components/feng-parse/libs/wxDiscode.js b/components/feng-parse/libs/wxDiscode.js
new file mode 100644
index 0000000..15d9a95
--- /dev/null
+++ b/components/feng-parse/libs/wxDiscode.js
@@ -0,0 +1,209 @@
+// HTML 支持的数学符号
+function strNumDiscode(str) {
+str = str.replace(/&forall;|&#8704;|&#x2200;/g, '∀');
+str = str.replace(/&part;|&#8706;|&#x2202;/g, '∂');
+str = str.replace(/&exist;|&#8707;|&#x2203;/g, '∃');
+str = str.replace(/&empty;|&#8709;|&#x2205;/g, '∅');
+str = str.replace(/&nabla;|&#8711;|&#x2207;/g, '∇');
+str = str.replace(/&isin;|&#8712;|&#x2208;/g, '∈');
+str = str.replace(/&notin;|&#8713;|&#x2209;/g, '∉');
+str = str.replace(/&ni;|&#8715;|&#x220b;/g, '∋');
+str = str.replace(/&prod;|&#8719;|&#x220f;/g, '∏');
+str = str.replace(/&sum;|&#8721;|&#x2211;/g, '∑');
+str = str.replace(/&minus;|&#8722;|&#x2212;/g, '−');
+str = str.replace(/&lowast;|&#8727;|&#x2217;/g, '∗');
+str = str.replace(/&radic;|&#8730;|&#x221a;/g, '√');
+str = str.replace(/&prop;|&#8733;|&#x221d;/g, '∝');
+str = str.replace(/&infin;|&#8734;|&#x221e;/g, '∞');
+str = str.replace(/&ang;|&#8736;|&#x2220;/g, '∠');
+str = str.replace(/&and;|&#8743;|&#x2227;/g, '∧');
+str = str.replace(/&or;|&#8744;|&#x2228;/g, '∨');
+str = str.replace(/&cap;|&#8745;|&#x2229;/g, '∩');
+str = str.replace(/&cup;|&#8746;|&#x222a;/g, '∪');
+str = str.replace(/&int;|&#8747;|&#x222b;/g, '∫');
+str = str.replace(/&there4;|&#8756;|&#x2234;/g, '∴');
+str = str.replace(/&sim;|&#8764;|&#x223c;/g, '∼');
+str = str.replace(/&cong;|&#8773;|&#x2245;/g, '≅');
+str = str.replace(/&asymp;|&#8776;|&#x2248;/g, '≈');
+str = str.replace(/&ne;|&#8800;|&#x2260;/g, '≠');
+str = str.replace(/&le;|&#8804;|&#x2264;/g, '≤');
+str = str.replace(/&ge;|&#8805;|&#x2265;/g, '≥');
+str = str.replace(/&sub;|&#8834;|&#x2282;/g, '⊂');
+str = str.replace(/&sup;|&#8835;|&#x2283;/g, '⊃');
+str = str.replace(/&nsub;|&#8836;|&#x2284;/g, '⊄');
+str = str.replace(/&sube;|&#8838;|&#x2286;/g, '⊆');
+str = str.replace(/&supe;|&#8839;|&#x2287;/g, '⊇');
+str = str.replace(/&oplus;|&#8853;|&#x2295;/g, '⊕');
+str = str.replace(/&otimes;|&#8855;|&#x2297;/g, '⊗');
+str = str.replace(/&perp;|&#8869;|&#x22a5;/g, '⊥');
+str = str.replace(/&sdot;|&#8901;|&#x22c5;/g, '⋅');
+return str;
+}
+
+// HTML 支持的希腊字母
+function strGreeceDiscode(str) {
+str = str.replace(/&Alpha;|&#913;|&#x391;/g, 'Α');
+str = str.replace(/&Beta;|&#914;|&#x392;/g, 'Β');
+str = str.replace(/&Gamma;|&#915;|&#x393;/g, 'Γ');
+str = str.replace(/&Delta;|&#916;|&#x394;/g, 'Δ');
+str = str.replace(/&Epsilon;|&#917;|&#x395;/g, 'Ε');
+str = str.replace(/&Zeta;|&#918;|&#x396;/g, 'Ζ');
+str = str.replace(/&Eta;|&#919;|&#x397;/g, 'Η');
+str = str.replace(/&Theta;|&#920;|&#x398;/g, 'Θ');
+str = str.replace(/&Iota;|&#921;|&#x399;/g, 'Ι');
+str = str.replace(/&Kappa;|&#922;|&#x39a;/g, 'Κ');
+str = str.replace(/&Lambda;|&#923;|&#x39b;/g, 'Λ');
+str = str.replace(/&Mu;|&#924;|&#x39c;/g, 'Μ');
+str = str.replace(/&Nu;|&#925;|&#x39d;/g, 'Ν');
+str = str.replace(/&Xi;|&#925;|&#x39d;/g, 'Ν');
+str = str.replace(/&Omicron;|&#927;|&#x39f;/g, 'Ο');
+str = str.replace(/&Pi;|&#928;|&#x3a0;/g, 'Π');
+str = str.replace(/&Rho;|&#929;|&#x3a1;/g, 'Ρ');
+str = str.replace(/&Sigma;|&#931;|&#x3a3;/g, 'Σ');
+str = str.replace(/&Tau;|&#932;|&#x3a4;/g, 'Τ');
+str = str.replace(/&Upsilon;|&#933;|&#x3a5;/g, 'Υ');
+str = str.replace(/&Phi;|&#934;|&#x3a6;/g, 'Φ');
+str = str.replace(/&Chi;|&#935;|&#x3a7;/g, 'Χ');
+str = str.replace(/&Psi;|&#936;|&#x3a8;/g, 'Ψ');
+str = str.replace(/&Omega;|&#937;|&#x3a9;/g, 'Ω');
+
+str = str.replace(/&alpha;|&#945;|&#x3b1;/g, 'α');
+str = str.replace(/&beta;|&#946;|&#x3b2;/g, 'β');
+str = str.replace(/&gamma;|&#947;|&#x3b3;/g, 'γ');
+str = str.replace(/&delta;|&#948;|&#x3b4;/g, 'δ');
+str = str.replace(/&epsilon;|&#949;|&#x3b5;/g, 'ε');
+str = str.replace(/&zeta;|&#950;|&#x3b6;/g, 'ζ');
+str = str.replace(/&eta;|&#951;|&#x3b7;/g, 'η');
+str = str.replace(/&theta;|&#952;|&#x3b8;/g, 'θ');
+str = str.replace(/&iota;|&#953;|&#x3b9;/g, 'ι');
+str = str.replace(/&kappa;|&#954;|&#x3ba;/g, 'κ');
+str = str.replace(/&lambda;|&#955;|&#x3bb;/g, 'λ');
+str = str.replace(/&mu;|&#956;|&#x3bc;/g, 'μ');
+str = str.replace(/&nu;|&#957;|&#x3bd;/g, 'ν');
+str = str.replace(/&xi;|&#958;|&#x3be;/g, 'ξ');
+str = str.replace(/&omicron;|&#959;|&#x3bf;/g, 'ο');
+str = str.replace(/&pi;|&#960;|&#x3c0;/g, 'π');
+str = str.replace(/&rho;|&#961;|&#x3c1;/g, 'ρ');
+str = str.replace(/&sigmaf;|&#962;|&#x3c2;/g, 'ς');
+str = str.replace(/&sigma;|&#963;|&#x3c3;/g, 'σ');
+str = str.replace(/&tau;|&#964;|&#x3c4;/g, 'τ');
+str = str.replace(/&upsilon;|&#965;|&#x3c5;/g, 'υ');
+str = str.replace(/&phi;|&#966;|&#x3c6;/g, 'φ');
+str = str.replace(/&chi;|&#967;|&#x3c7;/g, 'χ');
+str = str.replace(/&psi;|&#968;|&#x3c8;/g, 'ψ');
+str = str.replace(/&omega;|&#969;|&#x3c9;/g, 'ω');
+str = str.replace(/&thetasym;|&#977;|&#x3d1;/g, 'ϑ');
+str = str.replace(/&upsih;|&#978;|&#x3d2;/g, 'ϒ');
+str = str.replace(/&piv;|&#982;|&#x3d6;/g, 'ϖ');
+str = str.replace(/&middot;|&#183;|&#xb7;/g, '·');
+return str;
+}
+
+function strcharacterDiscode(str) {
+// 加入常用解析
+
+str = str.replace(/&nbsp;|&#32;|&#x20;/g, "&nbsp;");
+str = str.replace(/&ensp;|&#8194;|&#x2002;/g, '&ensp;');
+str = str.replace(/&#12288;|&#x3000;/g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/&emsp;|&#8195;|&#x2003;/g, '&emsp;');
+str = str.replace(/&quot;|&#34;|&#x22;/g, "\"");
+str = str.replace(/&apos;|&#39;|&#x27;/g, "&apos;");
+str = str.replace(/&acute;|&#180;|&#xB4;/g, "´");
+str = str.replace(/&times;|&#215;|&#xD7;/g, "×");
+str = str.replace(/&divide;|&#247;|&#xF7;/g, "÷");
+str = str.replace(/&amp;|&#38;|&#x26;/g, '&amp;');
+str = str.replace(/&lt;|&#60;|&#x3c;/g, '&lt;');
+str = str.replace(/&gt;|&#62;|&#x3e;/g, '&gt;');
+
+
+
+
+str = str.replace(/&nbsp;|&#32;|&#x20;/g, "<span class='spaceshow'> </span>");
+str = str.replace(/&ensp;|&#8194;|&#x2002;/g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/&#12288;|&#x3000;/g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/&emsp;|&#8195;|&#x2003;/g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/&quot;|&#34;|&#x22;/g, "\"");
+str = str.replace(/&quot;|&#39;|&#x27;/g, "'");
+str = str.replace(/&acute;|&#180;|&#xB4;/g, "´");
+str = str.replace(/&times;|&#215;|&#xD7;/g, "×");
+str = str.replace(/&divide;|&#247;|&#xF7;/g, "÷");
+str = str.replace(/&amp;|&#38;|&#x26;/g, '&');
+str = str.replace(/&lt;|&#60;|&#x3c;/g, '<');
+str = str.replace(/&gt;|&#62;|&#x3e;/g, '>');
+return str;
+}
+
+// HTML 支持的其他实体
+function strOtherDiscode(str) {
+str = str.replace(/&OElig;|&#338;|&#x152;/g, 'Œ');
+str = str.replace(/&oelig;|&#339;|&#x153;/g, 'œ');
+str = str.replace(/&Scaron;|&#352;|&#x160;/g, 'Š');
+str = str.replace(/&scaron;|&#353;|&#x161;/g, 'š');
+str = str.replace(/&Yuml;|&#376;|&#x178;/g, 'Ÿ');
+str = str.replace(/&fnof;|&#402;|&#x192;/g, 'ƒ');
+str = str.replace(/&circ;|&#710;|&#x2c6;/g, 'ˆ');
+str = str.replace(/&tilde;|&#732;|&#x2dc;/g, '˜');
+str = str.replace(/&thinsp;|$#8201;|&#x2009;/g, '<span class=\'spaceshow\'> </span>');
+str = str.replace(/&zwnj;|&#8204;|&#x200C;/g, '<span class=\'spaceshow\'>‌</span>');
+str = str.replace(/&zwj;|$#8205;|&#x200D;/g, '<span class=\'spaceshow\'>‍</span>');
+str = str.replace(/&lrm;|$#8206;|&#x200E;/g, '<span class=\'spaceshow\'>‎</span>');
+str = str.replace(/&rlm;|&#8207;|&#x200F;/g, '<span class=\'spaceshow\'>‏</span>');
+str = str.replace(/&ndash;|&#8211;|&#x2013;/g, '–');
+str = str.replace(/&mdash;|&#8212;|&#x2014;/g, '—');
+str = str.replace(/&lsquo;|&#8216;|&#x2018;/g, '‘');
+str = str.replace(/&rsquo;|&#8217;|&#x2019;/g, '’');
+str = str.replace(/&sbquo;|&#8218;|&#x201a;/g, '‚');
+str = str.replace(/&ldquo;|&#8220;|&#x201c;/g, '“');
+str = str.replace(/&rdquo;|&#8221;|&#x201d;/g, '”');
+str = str.replace(/&bdquo;|&#8222;|&#x201e;/g, '„');
+str = str.replace(/&dagger;|&#8224;|&#x2020;/g, '†');
+str = str.replace(/&Dagger;|&#8225;|&#x2021;/g, '‡');
+str = str.replace(/&bull;|&#8226;|&#x2022;/g, '•');
+str = str.replace(/&hellip;|&#8230;|&#x2026;/g, '…');
+str = str.replace(/&permil;|&#8240;|&#x2030;/g, '‰');
+str = str.replace(/&prime;|&#8242;|&#x2032;/g, '′');
+str = str.replace(/&Prime;|&#8243;|&#x2033;/g, '″');
+str = str.replace(/&lsaquo;|&#8249;|&#x2039;/g, '‹');
+str = str.replace(/&rsaquo;|&#8250;|&#x203a;/g, '›');
+str = str.replace(/&oline;|&#8254;|&#x203e;/g, '‾');
+str = str.replace(/&euro;|&#8364;|&#x20ac;/g, '€');
+str = str.replace(/&trade;|&#8482;|&#x2122;/g, '™');
+str = str.replace(/&larr;|&#8592;|&#x2190;/g, '←');
+str = str.replace(/&uarr;|&#8593;|&#x2191;/g, '↑');
+str = str.replace(/&rarr;|&#8594;|&#x2192;/g, '→');
+str = str.replace(/&darr;|&#8595;|&#x2193;/g, '↓');
+str = str.replace(/&harr;|&#8596;|&#x2194;/g, '↔');
+str = str.replace(/&crarr;|&#8629;|&#x21b5;/g, '↵');
+str = str.replace(/&lceil;|&#8968;|&#x2308;/g, '⌈');
+str = str.replace(/&rceil;|&#8969;|&#x2309;/g, '⌉');
+str = str.replace(/&lfloor;|&#8970;|&#x230a;/g, '⌊');
+str = str.replace(/&rfloor;|&#8971;|&#x230b;/g, '⌋');
+str = str.replace(/&loz;|&#9674;|&#x25ca;/g, '◊');
+str = str.replace(/&spades;|&#9824;|&#x2660;/g, '♠');
+str = str.replace(/&clubs;|&#9827;|&#x2663;/g, '♣');
+str = str.replace(/&hearts;|&#9829;|&#x2665;/g, '♥');
+str = str.replace(/&diams;|&#9830;|&#x2666;/g, '♦');
+return str;
+}
+
+function strDiscode(str) {
+  str = strNumDiscode(str);
+  str = strGreeceDiscode(str);
+  str = strcharacterDiscode(str);
+  str = strOtherDiscode(str);
+  return str;
+}
+
+function urlToHttpUrl(url, domain) {
+  if (/^\/\//.test(url)) {
+    return `https:${url}`;
+  } else if (/^\//.test(url)) {
+    return `https://${domain}${url}`;
+  }
+  return url;
+}
+
+export default {
+  strDiscode,
+  urlToHttpUrl,
+};
diff --git a/components/feng-parse/parse.css b/components/feng-parse/parse.css
new file mode 100644
index 0000000..e7adce1
--- /dev/null
+++ b/components/feng-parse/parse.css
@@ -0,0 +1,258 @@
+/**
+ * author: Di (微信小程序开发工程师)
+ * organization: WeAppDev(微信小程序开发论坛)(http://weappdev.com)
+ *         垂直微信小程序开发交流社区
+ *
+ * github地址: https://github.com/icindy/wxParse
+ *
+ * for: 微信小程序富文本解析
+ * detail : http://weappdev.com/t/wxparse-alpha0-1-html-markdown/184
+ */
+/**
+ * 请在全局下引入该文件,@import '/static/wxParse.css';
+ */
+.wxParse {
+	user-select:none;
+	width: 100%;
+	font-family: Helvetica, "PingFangSC", 'Microsoft Yahei', '微软雅黑', Arial, sans-serif;
+	color: #333;
+	line-height: 1.5;
+	font-size: 1em;
+	text-align:justify;/* //左右两端对齐 */
+}
+.wxParse view ,.wxParse uni-view{
+	word-break: break-word;
+}
+.wxParse .p {
+	padding-bottom: 0.5em;
+	clear: both;
+	/* letter-spacing: 0;//字间距 */
+}
+.wxParse .inline {
+  display: inline;
+  margin: 0;
+  padding: 0;
+}
+
+.wxParse .div {
+  margin: 0;
+  padding: 0;
+  display: block;
+}
+
+.wxParse .h1{
+  font-size: 2em;
+  line-height: 1.2em;
+  margin: 0.67em 0;
+}
+.wxParse .h2{
+  font-size: 1.5em;
+  margin: 0.83em 0;
+}
+.wxParse .h3{
+  font-size: 1.17em;
+  margin: 1em 0;
+}
+.wxParse .h4{
+  margin: 1.33em 0;
+}
+.wxParse .h5{
+  font-size: 0.83em;
+  margin: 1.67em 0;
+}
+.wxParse .h6{
+  font-size: 0.83em;
+  margin: 1.67em 0;
+}
+
+.wxParse .h1,
+.wxParse .h2,
+.wxParse .h3,
+.wxParse .h4,
+.wxParse .h5,
+.wxParse .h6,
+.wxParse .b,
+.wxParse .strong{
+  font-weight: bolder;
+}
+
+.wxParse .i,
+.wxParse .cite,
+.wxParse .em,
+.wxParse .var,
+.wxParse .address {
+  font-style: italic;
+}
+.wxParse .spaceshow{
+	  white-space: pre;
+}
+.wxParse .pre,
+.wxParse .tt,
+.wxParse .code,
+.wxParse .kbd,
+.wxParse .samp {
+  font-family: monospace;
+}
+.wxParse .pre {
+  overflow: auto;
+  background: #f5f5f5;
+  padding: 16upx;
+  white-space: pre;
+  margin: 1em 0upx;
+  font-size: 24upx;
+}
+.wxParse .code {
+	overflow: auto;
+	padding: 16upx;
+	white-space: pre;
+	margin: 1em 0upx;
+	background: #f5f5f5;
+	font-size: 24upx;
+}
+
+.wxParse .big {
+  font-size: 1.17em;
+}
+
+.wxParse .small,
+.wxParse .sub,
+.wxParse .sup {
+  font-size: 0.83em;
+}
+
+.wxParse .sub {
+  vertical-align: sub;
+}
+.wxParse .sup {
+  vertical-align: super;
+}
+
+.wxParse .s,
+.wxParse .strike,
+.wxParse .del {
+  text-decoration: line-through;
+}
+
+.wxParse .strong,
+.wxParse .text,
+.wxParse .span,
+.wxParse .s {
+  display: inline;
+}
+
+.wxParse .a {
+  color: deepskyblue;
+}
+
+.wxParse .video {
+  text-align: center;
+  margin: 22upx 0;
+}
+
+.wxParse .video-video {
+  width: 100%;
+}
+.wxParse .uni-image{
+	max-width: 100%;
+}
+.wxParse .img {
+  display: block;
+  max-width: 100%;
+  margin-bottom: 0em;/* //与p标签底部padding同时修改 */
+  overflow: hidden;
+}
+
+.wxParse .blockquote {
+  margin: 10upx 0;
+  padding: 22upx 0 22upx 22upx;
+  font-family: Courier, Calibri, "宋体";
+  background: #f5f5f5;
+  border-left: 6upx solid #dbdbdb;
+}
+.wxParse .blockquote .p {
+  margin: 0;
+}
+.wxParse .ul, .wxParse .ol {
+  display: block;
+  margin: 1em 0;
+  padding-left: 2em;
+}
+.wxParse .ol {
+  list-style-type: disc;
+}
+.wxParse .ol {
+  list-style-type: decimal;
+}
+.wxParse .ol>weixin-parse-template,.wxParse .ul>weixin-parse-template {
+  display: list-item;
+  align-items: baseline;
+  text-align: match-parent;
+}
+
+.wxParse .ol>.li,.wxParse .ul>.li {
+  display: list-item;
+  align-items: baseline;
+  text-align: match-parent;
+}
+.wxParse .ul .ul, .wxParse .ol .ul {
+  list-style-type: circle;
+}
+.wxParse .ol .ol .ul, .wxParse .ol .ul .ul, .wxParse .ul .ol .ul, .wxParse .ul .ul .ul {
+    list-style-type: square;
+}
+
+.wxParse .u {
+  text-decoration: underline;
+}
+.wxParse .hide {
+  display: none;
+}
+.wxParse .del {
+  display: inline;
+}
+.wxParse .figure {
+  overflow: hidden;
+}
+.wxParse .tablebox{
+	overflow: auto;
+	background-color: #f5f5f5;
+	background: #f5f5f5;
+	font-size: 13px;
+	padding: 8px;
+}
+.wxParse .table .table,.wxParse .table{
+	border-collapse:collapse;
+	box-sizing: border-box;
+	/* 内边框 */
+	/* width: 100%; */
+	overflow: auto;
+	white-space: pre;
+}
+.wxParse .tbody{
+	border-collapse:collapse;
+	box-sizing: border-box;
+	/* 内边框 */
+	border: 1px solid #dadada;
+}
+.wxParse .table  .thead, .wxParse  .table .tfoot, .wxParse  .table .th{
+	border-collapse:collapse;
+	box-sizing: border-box;
+	background: #ececec;
+	font-weight: 40;
+}
+.wxParse  .table .tr {
+	border-collapse:collapse;
+	box-sizing: border-box;
+	/* border: 2px solid #F0AD4E; */
+	overflow:auto;
+}
+.wxParse  .table .th,
+.wxParse  .table .td{
+	border-collapse:collapse;
+	box-sizing: border-box;
+	border: 2upx solid #dadada;
+	overflow:auto;
+}
+.wxParse .audio, .wxParse .uni-audio-default{
+	display: block;
+}
\ No newline at end of file
diff --git a/components/feng-parse/parse.vue b/components/feng-parse/parse.vue
new file mode 100644
index 0000000..38adc4f
--- /dev/null
+++ b/components/feng-parse/parse.vue
@@ -0,0 +1,237 @@
+<!--**
+ * forked from:https://github.com/F-loat/mpvue-wxParse
+ *
+ * github地址: https://github.com/dcloudio/uParse
+ *
+ * for: uni-app框架下 富文本解析
+ * 
+ * 优化 by zhiqiang.feng@qq.com
+ */-->
+
+<template>
+	
+	<!--基础元素-->
+	<view class="wxParse" :class="className" :style="'user-select:' + userSelect">
+		<block v-for="(node, index) of nodes" :key="index" v-if="!loading">
+			<wxParseTemplate :node="node" />
+		</block>
+	</view>
+</template>
+
+<script>
+import HtmlToJson from './libs/html2json';
+import wxParseTemplate from './components/wxParseTemplate0';
+
+	export default {
+		name: 'wxParse',
+		props: {
+			// user-select:none;
+			userSelect: {
+				type: String,
+				default: 'text' //none |text| all | element
+			},
+			imgOptions: {
+				type: [Object, Boolean],
+				default: function() {
+					return {
+						loop: false,
+						indicator: 'number',
+						longPressActions: false
+						// longPressActions: {
+						// 	 itemList: ['发送给朋友', '保存图片', '收藏'],
+						// 		success: function (res) {
+						// 			console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+						// 		},
+						// 		fail: function (res) {
+						// 			console.log(res.errMsg);
+						// 		}    
+						// 	}
+						// }
+					}
+				}
+			},
+			loading: {
+				type: Boolean,
+				default: false
+			},
+			className: {
+				type: String,
+				default: ''
+			},
+			content: {
+				type: String,
+				default: ''
+			},
+			noData: {
+				type: String,
+				default: ''
+			},
+			startHandler: {
+				type: Function,
+				default () {
+					return node => {
+						node.attr.class = null;
+						node.attr.style = null;
+					};
+				}
+			},
+			endHandler: {
+				type: Function,
+				default() {
+					return node => {
+						node = node
+					};
+				}
+			},
+			charsHandler: {
+				type: Function,
+				default() {
+					return node => {
+						node = node
+					};
+				}
+			},
+			imageProp: {
+				type: Object,
+				default () {
+					return {
+						mode: 'aspectFit',
+						padding: 0,
+						lazyLoad: false,
+						domain: ''
+					};
+				}
+			}
+		},
+		components: {
+			wxParseTemplate
+		},
+		data() {
+			return {
+				nodes: {},
+				imageUrls: [],
+				wxParseWidth: {
+					value: 0
+				}
+			};
+		},
+		computed: {},
+		mounted() {
+			this.setHtml()
+		},
+		methods: {
+			setHtml() {
+				this.getWidth().then((data) => {
+					this.wxParseWidth.value = data;
+				})
+				let {
+					content,
+					noData,
+					imageProp,
+					startHandler,
+					endHandler,
+					charsHandler
+				} = this;
+				let parseData = content || noData;
+				let customHandler = {
+					start: startHandler,
+					end: endHandler,
+					chars: charsHandler
+				};
+				let results = HtmlToJson(parseData, customHandler, imageProp, this);
+
+				this.imageUrls = results.imageUrls;
+				// this.nodes = results.nodes;
+				
+				this.nodes = [];
+				results.nodes.forEach((item) => {
+					setTimeout(() => {
+						if(item.node){
+							this.nodes.push(item)
+						}
+					}, 0);
+				})
+				
+			},
+			getWidth() {
+				return new Promise((res, rej) => {
+					// #ifndef MP-ALIPAY || MP-BAIDU
+					uni.createSelectorQuery()
+						.in(this)
+						.select('.wxParse')
+						.fields({
+								size: true,
+								scrollOffset: true
+							},
+							data => {
+								res(data.width);
+							}
+						).exec();
+					// #endif
+					// #ifdef MP-BAIDU
+					const query = swan.createSelectorQuery();
+					query.select('.wxParse').boundingClientRect();
+					query.exec(obj => {
+						const rect = obj[0]
+						if (rect) {
+							res(rect.width);
+						}
+					});
+					// #endif
+					// #ifdef MP-ALIPAY
+					my.createSelectorQuery()
+						.select('.wxParse')
+						.boundingClientRect().exec((ret) => {
+							res(ret[0].width);
+						});
+					// #endif
+				});
+			},
+			navigate(href, $event, attr) {
+				console.log(href, attr);
+				this.$emit('navigate', href, $event);
+			},
+			preview(src, $event) {
+				if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
+
+				} else {
+					uni.previewImage({
+						current: src,
+						urls: this.imageUrls,
+						loop: this.imgOptions.loop,
+						indicator: this.imgOptions.indicator,
+						longPressActions: this.imgOptions.longPressActions
+					});
+				}
+				this.$emit('preview', src, $event);
+			},
+			removeImageUrl(src) {
+				const {
+					imageUrls
+				} = this;
+				imageUrls.splice(imageUrls.indexOf(src), 1);
+			}
+		},
+		// 父组件中提供
+		provide() {
+			return {
+				parseWidth: this.wxParseWidth,
+				parseSelect: this.userSelect
+				// 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
+			};
+		},
+		watch: {
+			content(val){
+				this.setHtml()
+			}
+			// content: {
+			// 	handler: function(newVal, oldVal) {
+			// 		if (newVal !== oldVal) {
+			// 			
+			// 		}
+			// 	},
+			// 	deep: true
+			// }
+		}
+	};
+</script>
diff --git a/pages/article/article.vue b/pages/article/article.vue
new file mode 100644
index 0000000..2ca8957
--- /dev/null
+++ b/pages/article/article.vue
@@ -0,0 +1,163 @@
+<template>
+	<view class="advisory-big">
+		
+		<view  v-for="i in data" class="advisory-model" @click="goDetail(i)">
+			<view class="advisory-left">
+				<view class="advisory-title-top">
+					<view class="advisory-title">{{i.title}}</view>
+				</view>
+				<view class="advisory-title-down">
+					<view class="advisory-title-name">{{i.sourceName}}</view>
+					<view class="advisory-title-time">{{i.createTime}}</view>
+				</view>
+			</view>
+			<view class="advisory-right">
+				<image :src="i.url"></image>
+			</view>
+		</view>
+		
+	</view>
+</template>
+
+<script>
+	export default{
+		data(){
+			return {
+				// pathUrl:"http://localhost:89/",
+				pathUrl:"http://s16s652780.51mypc.cn/api/blade-jfpts",
+				data:[]
+			}
+		},
+		mounted(){
+			this.getArtcilePageList();
+		},
+		methods:{
+			//去跳转详情页面
+			goDetail(e){
+				
+				//内容传值容易报错,所以直传id,然后调用接口去查询
+				// let detail = {
+				// 	title: e.title,
+				// 	content: e.content,
+				// 	id: e.id,
+				// 	createTime: e.createTime,
+				// 	sourceName: e.sourceName,
+				// 	imgUrl: e.url,
+				// 	videoUrl:e.videoUrl
+				// };
+				
+				let detail = {
+					id: e.id
+				};
+				//去跳转
+				uni.navigateTo({
+					url: './article_detail?detailData=' + encodeURIComponent(JSON.stringify(detail))
+				});
+			},
+			
+			//获取资讯信息
+			getArtcilePageList(){
+				var that = this;
+				uni.request({
+					url: that.pathUrl+'/article/article/page',
+					method:'GET',
+					success: (res) => {
+						that.data = res.data.data.records;
+					}
+				});
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.advisory-big{
+		width: 100%;
+		height: 70%;
+		position: absolute;
+		top: 2%;
+		// background-color: #0078A8;
+		
+		.advisory-model{
+			width: 100%;
+			height: 20%;
+			// background-color: #00FF00;
+			
+			
+			.advisory-left{
+				width: 61%;
+				height: 80%;
+				float: left;
+				position: relative;
+				// background-color: #00FFFF;
+				position: relative;
+				left: 4%;
+				top: 10%;
+				
+				
+				.advisory-title-top{
+					// background-color: #2692FD;
+					width: 100%;
+					height: 75%;
+					
+					.advisory-title{
+						width: 92%;
+						font-size: 15px;
+						font-weight: 550;
+					}
+					
+					
+				}
+				
+				.advisory-title-down{
+					// background-color: #0078A8;
+					width: 100%;
+					height: 25%;
+					font-size: 12px;
+					font-weight: 550;
+					color: #808080;
+					
+					.advisory-title-name{
+						float: left;
+						letter-spacing: 1px;
+					}
+					
+					.advisory-title-time{
+						position: relative;
+						left: 6%;
+					}
+				}
+				
+			}
+			
+			.advisory-right{
+				// background-color: #222222;
+				width: 32%;
+				height: 80%;
+				left: 63%;
+				position: relative;
+				top: 10%;
+				
+				image{
+					position: relative;
+					left: 0px;
+					top: -100%;
+					width: 100%;
+					height: 100%;
+					border-radius: 5px;
+				}
+			}
+			
+			
+		}
+		
+		
+		
+		
+		
+	}
+	
+	
+	
+	
+</style>
diff --git a/pages/article/article_detail.vue b/pages/article/article_detail.vue
new file mode 100644
index 0000000..7de69d5
--- /dev/null
+++ b/pages/article/article_detail.vue
@@ -0,0 +1,137 @@
+<template>
+	<view>
+		<view class="banner">
+			<image class="banner-img" :src="article.url"></image>
+			<view class="banner-title">{{article.title}}</view>
+		</view>
+		
+		
+		<view class="article-content">
+			<!-- <rich-text type="text" :nodes="demoHtml"></rich-text> -->
+			<video id="myVideo" v-if="video" :src="article.videoUrl"></video>
+			<view class="content-placeholder">&nbsp;&nbsp;</view>
+			<u-parse :content="content" @navigate="navigate"></u-parse>
+		</view>
+		
+		<view class="article-meta">
+			<text class="article-author">{{article.sourceName}}</text>
+			<text class="article-text">发表于</text>
+			<text class="article-time">{{article.createTime}}</text>
+		</view>
+	</view>
+</template>
+
+<script>
+	import uParse from "@/components/feng-parse/parse.vue"
+	// import uParse from '@/components/gaoyia-parse/parse.vue'
+	// var graceRichText = require("../../components/richText/richText.js");
+	
+	export default {
+			components:{
+		        uParse
+		    },
+	        data() {
+	            return {
+					content:"",
+					article:{},
+					video:false,
+					pathUrl:"http://s16s652780.51mypc.cn/api/blade-jfpts",
+				}
+	        },
+	        onLoad(event) {
+				var that = this;
+	            this.article = JSON.parse(decodeURIComponent(event.detailData));
+				uni.request({
+					url: that.pathUrl+'/article/article/detail?id='+this.article.id,
+					method:'GET',
+					success: (res) => {
+						that.article = res.data.data;
+						that.content = that.article.content;
+						if(that.article.videoUrl){
+							that.video = true;
+						}
+						//详情标题
+						uni.setNavigationBarTitle({
+						    title: that.article.title
+						});
+					}
+				});
+				
+	        },
+			onReady: function (res) {
+			    this.videoContext = uni.createVideoContext('myVideo')
+			},
+	        methods: {
+	        }
+	    }
+</script>
+
+<style lang="scss" scoped>
+	 .banner {
+	        height: 360upx;
+	        overflow: hidden;
+	        position: relative;
+	        background-color: #ccc;
+	    }
+	    .banner-img {
+	        width: 100%;
+	    }
+	    .banner-title {
+	        max-height: 84upx;
+	        overflow: hidden;
+	        position: absolute;
+	        left: 30upx;
+	        bottom: 30upx;
+	        width: 90%;
+	        font-size: 32upx;
+	        font-weight: 400;
+	        line-height: 42upx;
+	        color: white;
+	        z-index: 11;
+	    }
+		
+	.article-meta{
+		// background-color: #007AFF;
+		width: 100%;
+		height: 80rpx;
+		position: relative;
+		top: 40rpx;
+		font-size: 24rpx;
+		color: #808080;
+		// font-weight: 550;
+		
+		
+		.article-author{
+			position: relative;
+			left: 20rpx;
+			letter-spacing: 1px;
+		}
+		
+		.article-text{
+			position: relative;
+			left: 40rpx;
+		}
+		
+		.article-time{
+			position: relative;
+			left: 50rpx;
+		}
+	}
+	
+	.article-content{
+		position: relative;
+		top: 20rpx;
+		left: 3%;
+		width: 94%;
+		border-bottom: 1px solid rgba(128,128,128,0.1);
+		
+		.content-placeholder{
+			position: relative;
+			left: 30%;
+			background-color: #0078A8;
+			width: 30%;
+			height: 20%;
+			
+		}
+	}
+</style>
diff --git a/static/img/index.png b/static/img/index.png
new file mode 100644
index 0000000..f804009
--- /dev/null
+++ b/static/img/index.png
Binary files differ
diff --git a/static/img/indexH.png b/static/img/indexH.png
new file mode 100644
index 0000000..77b96ae
--- /dev/null
+++ b/static/img/indexH.png
Binary files differ

--
Gitblit v1.9.3