225 lines
4.8 KiB
Vue
225 lines
4.8 KiB
Vue
|
<template>
|
|||
|
<view class="view">
|
|||
|
<!--判断是否是标签节点-->
|
|||
|
<template v-if="node.node == 'element'">
|
|||
|
<template v-if="node.tag == 'button'">
|
|||
|
<button type="default" size="mini">
|
|||
|
<template v-for="(node, index) of node.nodes" :key="index">
|
|||
|
<parseTemplate :node="node" />
|
|||
|
</template>
|
|||
|
</button>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--li类型-->
|
|||
|
<template v-else-if="node.tag == 'li'">
|
|||
|
<view :class="node.classStr" :style="node.styleStr">
|
|||
|
<template v-for="(item, index) of node.nodes" :key="index">
|
|||
|
<template v-if="parentNode && parentNode.tag == 'ol'">
|
|||
|
<parseTemplate :node="item" :parentNode="node" :textBefore="parentIndex + 1 + '. '" />
|
|||
|
</template>
|
|||
|
<template v-if="parentNode && parentNode.tag == 'ul'">
|
|||
|
<parseTemplate :node="item" :parentNode="node" textBefore="·" />
|
|||
|
</template>
|
|||
|
</template>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--video类型-->
|
|||
|
<template v-else-if="node.tag == 'video'">
|
|||
|
<!-- <wx-parse-video :node="node" /> -->
|
|||
|
</template>
|
|||
|
|
|||
|
<!--audio类型-->
|
|||
|
<template v-else-if="node.tag == 'audio'">
|
|||
|
<!-- <wx-parse-audio :node="node" /> -->
|
|||
|
</template>
|
|||
|
|
|||
|
<!--img类型-->
|
|||
|
<template v-else-if="node.tag == 'img'">
|
|||
|
<wx-parse-img :node="node" />
|
|||
|
</template>
|
|||
|
|
|||
|
<!--a类型-->
|
|||
|
<template v-else-if="node.tag == 'a'">
|
|||
|
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
|
|||
|
<template v-for="(item, index) of node.nodes" :key="index">
|
|||
|
<parseTemplate :node="item" />
|
|||
|
</template>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--table类型-->
|
|||
|
<template v-else-if="node.tag == 'table'">
|
|||
|
<view :class="node.classStr" class="table" :style="node.styleStr">
|
|||
|
<template v-for="(item, index) of node.nodes" :key="index">
|
|||
|
<parseTemplate :node="item" />
|
|||
|
</template>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--br类型-->
|
|||
|
<template v-else-if="node.tag == 'br'">
|
|||
|
<text> </text>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--hr类型-->
|
|||
|
<template v-else-if="node.tag == 'hr'">
|
|||
|
<view class="hr"></view>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--其他标签-->
|
|||
|
<template v-else>
|
|||
|
<view :class="node.classStr" :style="node.styleStr">
|
|||
|
<!-- 用来控制是否往下嵌套 -->
|
|||
|
<template v-if="node.nodes">
|
|||
|
<template v-for="(item, index) of node.nodes" :key="index">
|
|||
|
<parseTemplate :node="item" :parentNode="node" :parentIndex="index" />
|
|||
|
</template>
|
|||
|
</template>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
</template>
|
|||
|
|
|||
|
<!--判断是否是文本节点-->
|
|||
|
<template v-else-if="node.node == 'text'">
|
|||
|
<!-- 用来处理父级居中样式的问题 -->
|
|||
|
<template v-if="parentNode && parentNode.styleStr">
|
|||
|
<text class="text" :class="node.classStr"
|
|||
|
:style="parentNode.styleStr">{{textBefore}}{{node.text}}</text>
|
|||
|
</template>
|
|||
|
<!-- 用来处理纯文本样式 -->
|
|||
|
<template v-else>
|
|||
|
<text class="text" :class="node.classStr">{{textBefore}}{{node.text}}</text>
|
|||
|
</template>
|
|||
|
</template>
|
|||
|
</view>
|
|||
|
</template>
|
|||
|
|
|||
|
<script>
|
|||
|
import wxParseImg from './wxParseImg';
|
|||
|
// import wxParseVideo from './wxParseVideo';
|
|||
|
// import wxParseAudio from './wxParseAudio';
|
|||
|
|
|||
|
export default {
|
|||
|
name: 'parseTemplate',
|
|||
|
props: {
|
|||
|
// 当前节点
|
|||
|
node: {},
|
|||
|
// 父节点信息 用来处理行样式
|
|||
|
parentNode: {},
|
|||
|
// 父下标 用来处理有序列表
|
|||
|
parentIndex: {},
|
|||
|
// 展示在文本前的内容
|
|||
|
textBefore: {},
|
|||
|
},
|
|||
|
components: {
|
|||
|
wxParseImg,
|
|||
|
// wxParseVideo,
|
|||
|
// wxParseAudio,
|
|||
|
},
|
|||
|
methods: {
|
|||
|
wxParseATap(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);
|
|||
|
},
|
|||
|
},
|
|||
|
};
|
|||
|
</script>
|
|||
|
|
|||
|
<style lang="scss">
|
|||
|
$fontSize: 34rpx;
|
|||
|
|
|||
|
// 富文本
|
|||
|
.parse {
|
|||
|
.text {
|
|||
|
font-size: $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h1 .text {
|
|||
|
font-size: 2 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h2 .text {
|
|||
|
font-size: 1.5 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h3 .text {
|
|||
|
font-size: 1.17 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h4 .text {
|
|||
|
font-size: 1 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h5 .text {
|
|||
|
font-size: 0.83 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h6 .text {
|
|||
|
font-size: 0.67 * $fontSize;
|
|||
|
}
|
|||
|
|
|||
|
.h1 .text,
|
|||
|
.h2 .text,
|
|||
|
.h3 .text,
|
|||
|
.h4 .text,
|
|||
|
.h5 .text,
|
|||
|
.h6 .text,
|
|||
|
.b,
|
|||
|
.strong {
|
|||
|
font-weight: bold;
|
|||
|
}
|
|||
|
|
|||
|
.u .text {
|
|||
|
text-decoration: underline,
|
|||
|
}
|
|||
|
|
|||
|
.s .text {
|
|||
|
text-decoration: line-through,
|
|||
|
}
|
|||
|
|
|||
|
.i,
|
|||
|
.cite,
|
|||
|
.em,
|
|||
|
.var,
|
|||
|
.address {
|
|||
|
font-style: italic;
|
|||
|
}
|
|||
|
|
|||
|
.big {
|
|||
|
font-size: 33rpx;
|
|||
|
}
|
|||
|
|
|||
|
.small,
|
|||
|
.sub,
|
|||
|
.sup {
|
|||
|
font-size: 23rpx;
|
|||
|
}
|
|||
|
|
|||
|
/* #ifndef APP-NVUE */
|
|||
|
.sub {
|
|||
|
vertical-align: sub;
|
|||
|
}
|
|||
|
|
|||
|
.sup {
|
|||
|
vertical-align: super;
|
|||
|
}
|
|||
|
/* #endif */
|
|||
|
|
|||
|
.a {
|
|||
|
color: deepskyblue;
|
|||
|
}
|
|||
|
|
|||
|
.hr {
|
|||
|
border-top: 2rpx solid #999;
|
|||
|
margin: 5rpx;
|
|||
|
}
|
|||
|
}
|
|||
|
</style>
|