Administrator
2021-06-09 6e421c2b522e7e035161beaf00af06d950658fca
资讯页面,详情新增
26 files added
3017 ■■■■■ changed files
components/feng-parse/components/wxParseAudio.vue 28 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseImg.vue 94 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTable.vue 56 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate0.vue 116 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate1.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate10.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate11.vue 105 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate2.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate3.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate4.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate5.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate6.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate7.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate8.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseTemplate9.vue 107 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseVideo.vue 55 ●●●●● patch | view | raw | blame | history
components/feng-parse/components/wxParseVideo1.vue 25 ●●●●● patch | view | raw | blame | history
components/feng-parse/libs/html2json.js 308 ●●●●● patch | view | raw | blame | history
components/feng-parse/libs/htmlparser.js 156 ●●●●● patch | view | raw | blame | history
components/feng-parse/libs/wxDiscode.js 209 ●●●●● patch | view | raw | blame | history
components/feng-parse/parse.css 258 ●●●●● patch | view | raw | blame | history
components/feng-parse/parse.vue 237 ●●●●● patch | view | raw | blame | history
pages/article/article.vue 163 ●●●●● patch | view | raw | blame | history
pages/article/article_detail.vue 137 ●●●●● patch | view | raw | blame | history
static/img/index.png patch | view | raw | blame | history
static/img/indexH.png patch | view | raw | blame | history
components/feng-parse/components/wxParseAudio.vue
New file
@@ -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>
components/feng-parse/components/wxParseImg.vue
New file
@@ -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>
components/feng-parse/components/wxParseTable.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate0.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate1.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate10.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate11.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate2.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate3.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate4.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate5.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate6.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate7.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate8.vue
New file
@@ -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>
components/feng-parse/components/wxParseTemplate9.vue
New file
@@ -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>
components/feng-parse/components/wxParseVideo.vue
New file
@@ -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>
components/feng-parse/components/wxParseVideo1.vue
New file
@@ -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>
components/feng-parse/libs/html2json.js
New file
@@ -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;
components/feng-parse/libs/htmlparser.js
New file
@@ -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;
components/feng-parse/libs/wxDiscode.js
New file
@@ -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,
};
components/feng-parse/parse.css
New file
@@ -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;
}
components/feng-parse/parse.vue
New file
@@ -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>
pages/article/article.vue
New file
@@ -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>
pages/article/article_detail.vue
New file
@@ -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>
static/img/index.png
static/img/indexH.png