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> |