提交 7f0a2231 编写于 作者: H hulinNeil

增加标题栏按钮/问题反馈模版/关于页面/markdown示例

上级 0d33c37d
......@@ -21,7 +21,7 @@
let openUrl = plus.os.name === 'iOS' ? res.data.iOS : res.data.Android;
uni.showModal({ //提醒用户更新
title: '更新提示',
content: '是否选择更新',
content: res.data.note ? res.data.note : '是否选择更新',
success: (res) => {
if (res.confirm) {
plus.runtime.openURL(openUrl);
......@@ -265,4 +265,5 @@
background-color: #F1F1F1;
color: #353535;
}
</style>
module.exports = require('./lib/marked');
此差异已折叠。
<template>
<!--增加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>
<template>
<image
:mode="node.attr.mode"
: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,
};
},
props: {
node: {
type: Object,
default() {
return {};
},
},
},
methods: {
wxParseImgTap(e) {
if (!this.preview) return;
const { src } = e.target.dataset;
if (!src) return;
this.node.$host.preview(src, e);
},
// 图片视觉宽高计算函数区
wxParseImgLoad(e) {
const { src } = e.target.dataset;
if (!src) return;
const { width, height } = e.mp.detail;
const recal = this.wxAutoImageCal(width, height);
const { imageheight, imageWidth } = recal;
const { padding, mode } = this.node.attr;
const { styleStr } = this.node;
const imageHeightStyle = mode === 'widthFix' ? '' : `height: ${imageheight}px;`;
this.newStyleStr = `${styleStr}; ${imageHeightStyle}; width: ${imageWidth}px; padding: 0 ${+padding}px;`;
},
// 计算视觉优先的图片宽高
wxAutoImageCal(originalWidth, originalHeight) {
// 获取图片的原始长宽
const { padding } = this.node.attr;
const windowWidth = this.node.$screen.width - (2 * padding);
const results = {};
if (originalWidth < 60 || originalHeight < 60) {
const { src } = this.node.attr;
this.node.$host.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>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--table类型-->
<block v-else-if="node.tag == 'table'">
<view :class="node.classStr" class="table" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<block v-else-if="node.node == 'text'">{{node.text}}</block>
</template>
<script>
import wxParseTemplate from './wxParseTemplate1';
import wxParseImg from './wxParseImg';
import wxParseVideo from './wxParseVideo';
import wxParseAudio from './wxParseAudio';
export default {
name: 'wxParseTemplate0',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate1',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate10',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<!--button类型-->
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
{{node.text}}
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
{{node.text}}
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :class="node.classStr" :style="node.styleStr">
{{node.text}}
</view>
</block>
</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';
export default {
name: 'wxParseTemplate11',
props: {
node: {},
},
components: {
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate2',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate3',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate4',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
s<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate5',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate6',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate7',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate8',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--判断是否是标签节点-->
<block v-if="node.node == 'element'">
<block v-if="node.tag == 'button'">
<button type="default" size="mini">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</button>
</block>
<!--li类型-->
<block v-else-if="node.tag == 'li'">
<view :class="node.classStr" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--video类型-->
<block v-else-if="node.tag == 'video'">
<wx-parse-video :node="node" />
</block>
<!--audio类型-->
<block v-else-if="node.tag == 'audio'">
<wx-parse-audio :node="node" />
</block>
<!--img类型-->
<block v-else-if="node.tag == 'img'">
<wx-parse-img :node="node" />
</block>
<!--a类型-->
<block v-else-if="node.tag == 'a'">
<view @click="wxParseATap" :class="node.classStr" :data-href="node.attr.href" :style="node.styleStr">
<block v-for="(node, index) of node.nodes" :key="index">
<wx-parse-template :node="node" />
</block>
</view>
</block>
<!--br类型-->
<block v-else-if="node.tag == 'br'">
<text>\n</text>
</block>
<!--其他标签-->
<block v-else>
<view :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>
<!--判断是否是文本节点-->
<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';
export default {
name: 'wxParseTemplate9',
props: {
node: {},
},
components: {
wxParseTemplate,
wxParseImg,
wxParseVideo,
wxParseAudio,
},
methods: {
wxParseATap(e) {
const { href } = e.target.dataset;
if (!href) return;
this.node.$host.navigate(href, e);
},
},
};
</script>
<template>
<!--增加video标签支持,并循环添加-->
<view :class="node.classStr" :style="node.styleStr">
<video :class="node.classStr" class="video-video" :src="node.attr.src"></video>
</view>
</template>
<script>
export default {
name: 'wxParseVideo',
props: {
node: {},
},
};
</script>
/**
* 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: [],
};
function Node(tag) {
this.node = 'element';
this.tag = tag;
}
Node.prototype.$screen = getScreenInfo();
Node.prototype.$host = host;
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 || '';
}
// 处理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;
}
if (customHandler.start) {
customHandler.start(node, results);
}
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;
}
if (customHandler.end) {
customHandler.end(node, results);
}
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,
};
if (customHandler.chars) {
customHandler.chars(node, results);
}
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;
/**
*
* 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;
// HTML 支持的数学符号
function strNumDiscode(str) {
str = str.replace(/&forall;/g, '');
str = str.replace(/&part;/g, '');
str = str.replace(/&exist;/g, '');
str = str.replace(/&empty;/g, '');
str = str.replace(/&nabla;/g, '');
str = str.replace(/&isin;/g, '');
str = str.replace(/&notin;/g, '');
str = str.replace(/&ni;/g, '');
str = str.replace(/&prod;/g, '');
str = str.replace(/&sum;/g, '');
str = str.replace(/&minus;/g, '');
str = str.replace(/&lowast;/g, '');
str = str.replace(/&radic;/g, '');
str = str.replace(/&prop;/g, '');
str = str.replace(/&infin;/g, '');
str = str.replace(/&ang;/g, '');
str = str.replace(/&and;/g, '');
str = str.replace(/&or;/g, '');
str = str.replace(/&cap;/g, '');
str = str.replace(/&cup;/g, '');
str = str.replace(/&int;/g, '');
str = str.replace(/&there4;/g, '');
str = str.replace(/&sim;/g, '');
str = str.replace(/&cong;/g, '');
str = str.replace(/&asymp;/g, '');
str = str.replace(/&ne;/g, '');
str = str.replace(/&le;/g, '');
str = str.replace(/&ge;/g, '');
str = str.replace(/&sub;/g, '');
str = str.replace(/&sup;/g, '');
str = str.replace(/&nsub;/g, '');
str = str.replace(/&sube;/g, '');
str = str.replace(/&supe;/g, '');
str = str.replace(/&oplus;/g, '');
str = str.replace(/&otimes;/g, '');
str = str.replace(/&perp;/g, '');
str = str.replace(/&sdot;/g, '');
return str;
}
// HTML 支持的希腊字母
function strGreeceDiscode(str) {
str = str.replace(/&Alpha;/g, 'Α');
str = str.replace(/&Beta;/g, 'Β');
str = str.replace(/&Gamma;/g, 'Γ');
str = str.replace(/&Delta;/g, 'Δ');
str = str.replace(/&Epsilon;/g, 'Ε');
str = str.replace(/&Zeta;/g, 'Ζ');
str = str.replace(/&Eta;/g, 'Η');
str = str.replace(/&Theta;/g, 'Θ');
str = str.replace(/&Iota;/g, 'Ι');
str = str.replace(/&Kappa;/g, 'Κ');
str = str.replace(/&Lambda;/g, 'Λ');
str = str.replace(/&Mu;/g, 'Μ');
str = str.replace(/&Nu;/g, 'Ν');
str = str.replace(/&Xi;/g, 'Ν');
str = str.replace(/&Omicron;/g, 'Ο');
str = str.replace(/&Pi;/g, 'Π');
str = str.replace(/&Rho;/g, 'Ρ');
str = str.replace(/&Sigma;/g, 'Σ');
str = str.replace(/&Tau;/g, 'Τ');
str = str.replace(/&Upsilon;/g, 'Υ');
str = str.replace(/&Phi;/g, 'Φ');
str = str.replace(/&Chi;/g, 'Χ');
str = str.replace(/&Psi;/g, 'Ψ');
str = str.replace(/&Omega;/g, 'Ω');
str = str.replace(/&alpha;/g, 'α');
str = str.replace(/&beta;/g, 'β');
str = str.replace(/&gamma;/g, 'γ');
str = str.replace(/&delta;/g, 'δ');
str = str.replace(/&epsilon;/g, 'ε');
str = str.replace(/&zeta;/g, 'ζ');
str = str.replace(/&eta;/g, 'η');
str = str.replace(/&theta;/g, 'θ');
str = str.replace(/&iota;/g, 'ι');
str = str.replace(/&kappa;/g, 'κ');
str = str.replace(/&lambda;/g, 'λ');
str = str.replace(/&mu;/g, 'μ');
str = str.replace(/&nu;/g, 'ν');
str = str.replace(/&xi;/g, 'ξ');
str = str.replace(/&omicron;/g, 'ο');
str = str.replace(/&pi;/g, 'π');
str = str.replace(/&rho;/g, 'ρ');
str = str.replace(/&sigmaf;/g, 'ς');
str = str.replace(/&sigma;/g, 'σ');
str = str.replace(/&tau;/g, 'τ');
str = str.replace(/&upsilon;/g, 'υ');
str = str.replace(/&phi;/g, 'φ');
str = str.replace(/&chi;/g, 'χ');
str = str.replace(/&psi;/g, 'ψ');
str = str.replace(/&omega;/g, 'ω');
str = str.replace(/&thetasym;/g, 'ϑ');
str = str.replace(/&upsih;/g, 'ϒ');
str = str.replace(/&piv;/g, 'ϖ');
str = str.replace(/&middot;/g, '·');
return str;
}
function strcharacterDiscode(str) {
// 加入常用解析
str = str.replace(/&nbsp;/g, ' ');
str = str.replace(/&ensp;/g, '');
str = str.replace(/&emsp;/g, ' ');
str = str.replace(/&quot;/g, "'");
str = str.replace(/&amp;/g, '&');
str = str.replace(/&lt;/g, '<');
str = str.replace(/&gt;/g, '>');
str = str.replace(/&#8226;/g, '');
return str;
}
// HTML 支持的其他实体
function strOtherDiscode(str) {
str = str.replace(/&OElig;/g, 'Œ');
str = str.replace(/&oelig;/g, 'œ');
str = str.replace(/&Scaron;/g, 'Š');
str = str.replace(/&scaron;/g, 'š');
str = str.replace(/&Yuml;/g, 'Ÿ');
str = str.replace(/&fnof;/g, 'ƒ');
str = str.replace(/&circ;/g, 'ˆ');
str = str.replace(/&tilde;/g, '˜');
str = str.replace(/&ensp;/g, '');
str = str.replace(/&emsp;/g, '');
str = str.replace(/&thinsp;/g, '');
str = str.replace(/&zwnj;/g, '');
str = str.replace(/&zwj;/g, '');
str = str.replace(/&lrm;/g, '');
str = str.replace(/&rlm;/g, '');
str = str.replace(/&ndash;/g, '');
str = str.replace(/&mdash;/g, '');
str = str.replace(/&lsquo;/g, '');
str = str.replace(/&rsquo;/g, '');
str = str.replace(/&sbquo;/g, '');
str = str.replace(/&ldquo;/g, '');
str = str.replace(/&rdquo;/g, '');
str = str.replace(/&bdquo;/g, '');
str = str.replace(/&dagger;/g, '');
str = str.replace(/&Dagger;/g, '');
str = str.replace(/&bull;/g, '');
str = str.replace(/&hellip;/g, '');
str = str.replace(/&permil;/g, '');
str = str.replace(/&prime;/g, '');
str = str.replace(/&Prime;/g, '');
str = str.replace(/&lsaquo;/g, '');
str = str.replace(/&rsaquo;/g, '');
str = str.replace(/&oline;/g, '');
str = str.replace(/&euro;/g, '');
str = str.replace(/&trade;/g, '');
str = str.replace(/&larr;/g, '');
str = str.replace(/&uarr;/g, '');
str = str.replace(/&rarr;/g, '');
str = str.replace(/&darr;/g, '');
str = str.replace(/&harr;/g, '');
str = str.replace(/&crarr;/g, '');
str = str.replace(/&lceil;/g, '');
str = str.replace(/&rceil;/g, '');
str = str.replace(/&lfloor;/g, '');
str = str.replace(/&rfloor;/g, '');
str = str.replace(/&loz;/g, '');
str = str.replace(/&spades;/g, '');
str = str.replace(/&clubs;/g, '');
str = str.replace(/&hearts;/g, '');
str = str.replace(/&diams;/g, '');
str = str.replace(/&#39;/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,
};
/**
* 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
*/
.wxParse {
width: 100%;
font-family: Helvetica, sans-serif;
font-size: 30px;
color: #666;
line-height: 1.8;
}
.wxParse view {
word-break: hyphenate;
}
.wxParse .inline {
display: inline;
margin: 0;
padding: 0;
}
.wxParse .div {
margin: 0;
padding: 0;
}
.wxParse .h1 {
font-size: 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.67em;
margin: 2.33em 0;
}
.wxParse .h1,
.wxParse .h2,
.wxParse .h3,
.wxParse .h4,
.wxParse .h5,
.wxParse .h6,
.wxParse .b,
.wxParse .strong {
font-weight: bolder;
}
.wxParse .p {
margin: 1em 0;
}
.wxParse .i,
.wxParse .cite,
.wxParse .em,
.wxParse .var,
.wxParse .address {
font-style: italic;
}
.wxParse .pre,
.wxParse .tt,
.wxParse .code,
.wxParse .kbd,
.wxParse .samp {
font-family: monospace;
}
.wxParse .pre {
overflow: auto;
background: #f5f5f5;
padding: 16px;
white-space: pre;
margin: 1em 0px;
}
.wxParse .code {
display: inline;
background: #f5f5f5;
}
.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 .s {
display: inline;
}
.wxParse .a {
color: deepskyblue;
}
.wxParse .video {
text-align: center;
margin: 22px 0;
}
.wxParse .video-video {
width: 100%;
}
.wxParse .img {
display: inline-block;
width: 0;
height: 0;
max-width: 100%;
overflow: hidden;
}
.wxParse .blockquote {
margin: 10px 0;
padding: 22px 0 22px 22px;
font-family: Courier, Calibri, "宋体";
background: #f5f5f5;
border-left: 6px solid #dbdbdb;
}
.wxParse .blockquote .p {
margin: 0;
}
.wxParse .ul, .wxParse .ol {
display: block;
margin: 1em 0;
padding-left: 33px;
}
.wxParse .ol {
list-style-type: disc;
}
.wxParse .ol {
list-style-type: decimal;
}
.wxParse .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 .table {
width: 100%;
}
.wxParse .thead, .wxParse .tfoot, .wxParse .tr {
display: flex;
flex-direction: row;
}
.wxParse .tr {
width:100%;
display: flex;
border-right: 2px solid #e0e0e0;
border-bottom: 2px solid #e0e0e0;
}
.wxParse .th,
.wxParse .td {
display: flex;
width: 1276px;
overflow: auto;
flex: 1;
padding: 11px;
border-left: 2px solid #e0e0e0;
}
.wxParse .td:last {
border-top: 2px solid #e0e0e0;
}
.wxParse .th {
background: #f0f0f0;
border-top: 2px solid #e0e0e0;
}
<!--**
* author: F-loat <chaimaoyuan@foxmail.com>
*
* github地址: https://github.com/F-loat/mpvue-wxParse
*
* for: Mpvue框架下 微信小程序富文本解析
*/-->
<template>
<!--基础元素-->
<div class="wxParse" :class="className" v-if="!loading">
<block v-for="node of nodes" :key="node.index">
<wxParseTemplate :node="node" />
</block>
</div>
</template>
<script>
import HtmlToJson from './libs/html2json';
import wxParseTemplate from './components/wxParseTemplate0';
export default {
name: 'wxParse',
props: {
loading: {
type: Boolean,
default: false,
},
className: {
type: String,
default: '',
},
content: {
type: String,
default: '',
},
noData: {
type: String,
default: '<div style="color: red;">数据不能为空</div>',
},
startHandler: {
type: Function,
default() {
return (node) => {
node.attr.class = null;
node.attr.style = null;
};
},
},
endHandler: {
type: Function,
default: null,
},
charsHandler: {
type: Function,
default: null,
},
imageProp: {
type: Object,
default() {
return {
mode: 'aspectFit',
padding: 0,
lazyLoad: false,
domain: '',
};
},
},
},
components: {
wxParseTemplate,
},
data() {
return {
imageUrls: [],
};
},
computed: {
nodes() {
const {
content,
noData,
imageProp,
startHandler,
endHandler,
charsHandler,
} = this;
const parseData = content || noData;
const customHandler = {
start: startHandler,
end: endHandler,
chars: charsHandler,
};
const results = HtmlToJson(parseData, customHandler, imageProp, this);
this.imageUrls = results.imageUrls;
return results.nodes;
},
},
methods: {
navigate(href, $event) {
this.$emit('navigate', href, $event);
},
preview(src, $event) {
if (!this.imageUrls.length) return;
wx.previewImage({
current: src,
urls: this.imageUrls,
});
this.$emit('preview', src, $event);
},
removeImageUrl(src) {
const { imageUrls } = this;
imageUrls.splice(imageUrls.indexOf(src), 1);
},
},
};
</script>
{
"name" : "hello uni-app",
"appid" : "__UNI__123213213",
"description" : "应用描述",
"versionName" : "1.0.0",
"versionCode" : "100",
"app-plus" : {
/* 5+App特有相关 */
"modules" : {
"OAuth" : {},
"Payment" : {},
"Push" : {},
"Share" : {},
"Speech" : {},
"VideoPlayer" : {}
},
"distribute" : {
/* 应用发布信息 */
"android" : {
/* android打包配置 */
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
"ios" : {}, /* ios打包配置 */
"sdkConfigs" : {}, /* SDK配置 */
"orientation" : [ "portrait-primary" ]
}
},
"quickapp" : {}, /* 快应用特有相关 */
"mp-weixin" : {} /* 小程序特有相关 */
"name": "hello uni-app",
"appid": "__UNI__123213213",
"description": "应用描述",
"versionName": "1.0.0",
"versionCode": "100",
"app-plus": { /* 5+App特有相关 */
"modules": {
"OAuth": {},
"Payment": {},
"Push": {},
"Share": {},
"Speech": {},
"VideoPlayer": {}
},
"distribute": { /* 应用发布信息 */
"android": { /* android打包配置 */
"permissions": [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
]
},
"ios": { /* ios打包配置 */
},
"sdkConfigs": { /* SDK配置 */
},
"orientation": ["portrait-primary"]
}
},
"quickapp": { /* 快应用特有相关 */
},
"mp-weixin": { /* 小程序特有相关 */
"appid": ""
}
}
......@@ -3,17 +3,50 @@
{
"path": "pages/component/component",
"style": {
"navigationBarTitleText": "组件"
"navigationBarTitleText": "组件",
"app-plus":{
"titleNView":{
"titleText":"组件",
"buttons":[{
"text":"\ue534",
"fontSrc":"_www/static/uni.ttf",
"fontSize":"22px",
"color":"#999999"
}]
}
}
}
}, {
"path": "pages/API/API",
"style": {
"navigationBarTitleText": "接口"
"navigationBarTitleText": "接口",
"app-plus":{
"titleNView":{
"titleText":"接口",
"buttons":[{
"text":"\ue534",
"fontSrc":"_www/static/uni.ttf",
"fontSize":"22px",
"color":"#999999"
}]
}
}
}
}, {
"path": "pages/template/template",
"style": {
"navigationBarTitleText": "模版"
"navigationBarTitleText": "模版",
"app-plus":{
"titleNView":{
"titleText":"模版",
"buttons":[{
"text":"\ue534",
"fontSrc":"_www/static/uni.ttf",
"fontSize":"22px",
"color":"#999999"
}]
}
}
}
}, {
"path": "pages/component/view/view",
......@@ -439,6 +472,16 @@
"enablePullDownRefresh": true,
"onReachBottomDistance": 20
}
}, {
"path": "pages/template/mdparse/mdparse",
"style": {
"navigationBarTitleText": "markdown富文本渲染"
}
}, {
"path": "platforms/app-plus/about/about",
"style": {
"navigationBarTitleText": "关于"
}
}
],
"globalStyle": {
......
......@@ -208,6 +208,11 @@
path: '/pages/API/API'
}
},
onNavigationBarButtonTap(e){
uni.navigateTo({
url: '/platforms/app-plus/about/about'
})
},
methods: {
trigerCollapse(e) {
for (let i = 0, len = this.lists.length; i < len; ++i) {
......
<template>
<view>
<page-head :title="title"></page-head>
<view class="page-body">
<view class="page-section">
<view class="page-body-info">
<block v-if="tempFilePath != ''">
<image :src="tempFilePath" class="image" mode="aspectFit"></image>
</block>
<block v-if="tempFilePath === '' && savedFilePath != ''">
<image :src="savedFilePath" class="image" mode="aspectFit"></image>
</block>
<block v-if="tempFilePath === '' && savedFilePath === ''">
<view class="image-plus image-plus-nb" @tap="chooseImage">
<view class="image-plus-horizontal"></view>
<view class="image-plus-vertical"></view>
</view>
<view class="image-plus-text">请选择文件</view>
</block>
</view>
<view>
<page-head :title="title"></page-head>
<view class="page-body">
<view class="page-section">
<view class="page-body-info">
<block v-if="tempFilePath != ''">
<image :src="tempFilePath" class="image" mode="aspectFit"></image>
</block>
<block v-if="tempFilePath === '' && savedFilePath != ''">
<image :src="savedFilePath" class="image" mode="aspectFit"></image>
</block>
<block v-if="tempFilePath === '' && savedFilePath === ''">
<view class="image-plus image-plus-nb" @tap="chooseImage">
<view class="image-plus-horizontal"></view>
<view class="image-plus-vertical"></view>
</view>
<view class="image-plus-text">请选择文件</view>
</block>
</view>
<view class="btn-area">
<button class="btn-savefile" @tap="saveFile">保存文件</button>
<button @tap="clear">删除文件</button>
</view>
<view class="btn-area">
<button class="btn-savefile" @tap="saveFile">保存文件</button>
<button @tap="clear">删除文件</button>
<button @tap="openDocument">打开文件</button>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import pageHead from '../../../components/page-head.vue'
import pageHead from '../../../components/page-head.vue'
export default {
data() {
return {
title: 'saveFile',
tempFilePath: '',
savedFilePath: ''
}
},
onLoad() {
this.savedFilePath = uni.getStorageSync('savedFilePath')
},
onUnload() {
this.tempFilePath = "",
this.savedFilePath = ""
},
methods: {
chooseImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.tempFilePath = res.tempFilePaths[0]
}
})
},
saveFile() {
if (this.tempFilePath.length > 0) {
uni.saveFile({
tempFilePath: this.tempFilePath,
success: (res) => {
this.savedFilePath = res.savedFilePath
uni.setStorageSync('savedFilePath', res.savedFilePath)
uni.showModal({
title: '保存成功',
content: '下次进入页面时,此文件仍可用',
showCancel:false
})
},
fail: (res) => {
uni.showModal({
title: '保存失败',
content: '失败原因: ' + JSON.stringify(res),
showCancel:false
})
}
})
}else{
uni.showModal({
content:"请选择文件",
showCancel:false
})
}
},
clear() {
uni.setStorageSync('savedFilePath', '')
this.tempFilePath = '',
this.savedFilePath = ''
}
},
components: {
pageHead
}
}
export default {
data() {
return {
title: 'saveFile',
tempFilePath: '',
savedFilePath: ''
}
},
onLoad() {
this.savedFilePath = uni.getStorageSync('savedFilePath')
},
onUnload() {
this.tempFilePath = "",
this.savedFilePath = ""
},
methods: {
chooseImage() {
uni.chooseImage({
count: 1,
success: (res) => {
this.tempFilePath = res.tempFilePaths[0]
}
})
},
saveFile() {
if (this.tempFilePath.length > 0) {
uni.saveFile({
tempFilePath: this.tempFilePath,
success: (res) => {
this.savedFilePath = res.savedFilePath
uni.setStorageSync('savedFilePath', res.savedFilePath)
uni.showModal({
title: '保存成功',
content: '下次进入页面时,此文件仍可用',
showCancel: false
})
},
fail: (res) => {
uni.showModal({
title: '保存失败',
content: '失败原因: ' + JSON.stringify(res),
showCancel: false
})
}
})
} else {
uni.showModal({
content: "请选择文件",
showCancel: false
})
}
},
clear() {
uni.setStorageSync('savedFilePath', '')
this.tempFilePath = '',
this.savedFilePath = ''
},
openDocument() {
uni.downloadFile({
url: 'https://raw.githubusercontent.com/mozilla/pdf.js/master/examples/learning/helloworld.pdf',
success: function (res) {
var filePath = res.tempFilePath
uni.openDocument({
filePath: filePath,
success: function (res) {
console.log('打开文档成功')
}
})
}
})
}
},
components: {
pageHead
}
}
</script>
<style>
.image {
width: 100%;
height: 360px;
}
.image {
width: 100%;
height: 360px;
}
.page-body-info {
display: flex;
box-sizing: border-box;
padding: 30px;
height: 420px;
border-top: 1px solid #D9D9D9;
border-bottom: 1px solid #D9D9D9;
align-items: center;
justify-content: center;
}
.page-body-info {
display: flex;
box-sizing: border-box;
padding: 30px;
height: 420px;
border-top: 1px solid #D9D9D9;
border-bottom: 1px solid #D9D9D9;
align-items: center;
justify-content: center;
}
.btn-savefile {
background-color: #007aff;
color: #ffffff;
}
.btn-savefile {
background-color: #007aff;
color: #ffffff;
}
</style>
......@@ -73,6 +73,11 @@
path: '/pages/component/component'
}
},
onNavigationBarButtonTap(e){
uni.navigateTo({
url: '/platforms/app-plus/about/about'
})
},
methods: {
trigerCollapse(e) {
for (let i = 0, len = this.lists.length; i < len; ++i) {
......
<template>
<view style="margin-left: 15px;margin-right: 15px;">
<wxParse :content="article" @preview="preview" @navigate="navigate" />
</view>
</template>
<script>
//本示例引用组件为三方的mpvue-wxparse,该组件为开源mit协议,如有新需求可自行改动完成或联系原作者
import marked from '../../../components/marked'
import wxParse from '../../../components/mpvue-wxparse/src/wxParse.vue'
//真实业务开发时mdcontend应改为从网络获取,本演示写死在本地
var mdcontend = "很多资讯内容都是markdown格式,使用本模板可直接解析markdown为符合uni-app规范的富文本界面。下文为示例:\r\n" +
"\r\n" +
"HBuilderX堪称markdown书写编辑的最佳工具,本文简单介绍HBuilderX里markdown的使用技巧。更多详情请在HBuilderX里点菜单帮助-markdown语法帮助。\r\n" +
"\r\n" +
"markdown的标题是行首以#号开头,空格分割的,不同级别的标题,在HX里着色也不同。如下:\r\n" +
"# 标题1\r\n" +
"## 标题2\r\n" +
"### 标题3\r\n" +
"#### 标题4\r\n" +
"##### 标题5\r\n" +
"\r\n" +
"HBuilderX标题编辑技巧:\r\n" +
"1. Emmet快速输入:敲h2+Tab即可生成二级标题【同HTML里的emmet写法,不止标题,HX里所有可对应tag的markdown语法均支持emmet写法】。仅行首生效\r\n" +
"2. 智能双击:双击#号可选中整个标题段落\r\n" +
"3. 智能回车:行尾回车或行中Ctrl+Enter强制换行后会自动在下一行补#\r\n" +
"4. 回车后再次按Tab可递进一层标题,再按Tab切换列表符\r\n" +
"5. 在# 后回车,可上插一个空标题行【同word】,任意位置按Ctrl+Shift+Enter也可以\r\n" +
"\r\n" +
"\r\n" +
"- 折叠:点标题前的-号可折叠该标题段落,快捷键是Alt+-(展开折叠是Alt+=)\r\n" +
"- 折叠:多层折叠时折叠或展开子节点,快捷键是Alt+Shift+-或=\r\n" +
"\r\n" +
"\r\n" +
"**加粗** 【快捷键:Ctrl+B,支持多光标;Emmet:b后敲Tab】\r\n" +
"\r\n" +
"_倾斜_【Emmet:i后敲Tab;前后包围:选中文字按Ctrl+\\是在选区两侧添加光标,可以继续输入_】\r\n" +
"\r\n" +
"~~删除线~~【前后包围:选中文字按Ctrl+\\是在选区两侧添加光标,可以继续输入~~,会在2侧同时输入】\r\n" +
"\r\n" +
"> 引用\r\n" +
"\r\n" +
"\r\n" +
"[超链接](https://dcloud.io)\r\n" +
"\r\n" +
"![logo](https://img-cdn-qiniu.dcloud.net.cn/newpage/images/logo4.png)\r\n" +
"\r\n" +
"\r\n" +
"=======================\r\n" +
"\r\n" +
"\r\n" +
"``` javascript\r\n" +
" var a = document; //代码\r\n" +
"```\r\n"
export default {
components: {
wxParse
},
data() {
return {
article: marked(mdcontend)
}
},
methods: {
preview(src, e) {
// do something
console.log("src: " + src);
},
navigate(href, e) {
// 如允许点击超链接跳转,则应该打开一个新页面,并传入href,由新页面内嵌webview组件负责显示该链接内容
console.log("href: " + href);
uni.showModal({
content : "点击链接为:" + href,
showCancel:false
})
}
}
}
</script>
<style>
@import url("../../../components/mpvue-wxparse/src/wxParse.css");
</style>
......@@ -65,13 +65,18 @@
name: '选项卡',
url: 'tabbar'
},
// {
// name: '问题反馈',
// url: '/platforms/app-plus/feedback/feedback'
// },
// #ifdef APP-PLUS
{
name: '问题反馈',
url: '/platforms/app-plus/feedback/feedback'
},
// #endif
{
name: '数字选择框',
url: 'number-box'
}, {
name: 'markdown富文本渲染',
url: 'mdparse'
}, {
name: '列表到详情示例',
url: 'list2detail-list'
......@@ -85,6 +90,11 @@
path: '/pages/template/template'
}
},
onNavigationBarButtonTap(e){
uni.navigateTo({
url: '/platforms/app-plus/about/about'
})
},
methods: {
trigerCollapse(e) {
for (var i = 0, len = this.lists.length; i < len; ++i) {
......
<template>
<view class="about">
<view class="content">
<view style="display:flex;align-items: center;flex-direction: column;">
<image src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/app_download.png" @longtap="save"></image>
<text>扫码体验uni-app</text>
</view>
<view class="desc">
<text class="code">uni-app</text>
是一个使用 <text class="code">Vue.js</text> 开发跨平台应用的前端框架 。
</view>
<button type="primary" @tap="share">分享</button>
</view>
<view class="version">
当前版本:{{version}}
</view>
</view>
</template>
<script>
export default {
data(){
return {
providerList:[],
version:''
}
},
onLoad() {
this.version = plus.runtime.version;
uni.getProvider({
service: 'share',
success: (e) => {
let data = [];
for (let i = 0; i < e.provider.length; i++) {
switch (e.provider[i]) {
case 'weixin':
data.push({
name: '分享到微信好友',
id: 'weixin'
})
data.push({
name: '分享到微信朋友圈',
id: 'weixin',
type: 'WXSenceTimeline'
})
break;
case 'qq':
data.push({
name: '分享到QQ',
id: 'qq'
})
break;
default:
break;
}
}
this.providerList = data;
},
fail: (e) => {
console.log('获取登录通道失败'+ JSON.stringify(e));
}
});
},
methods:{
save(){
uni.showActionSheet({
itemList:['保存图片到相册'],
success: () => {
plus.gallery.save('https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/app_download.png', function() {
uni.showToast({
title:'保存成功',
icon:'none'
})
}, function() {
uni.showToast({
title:'保存失败,请重试!',
icon:'none'
})
});
}
})
},
share(e) {
if (this.providerList.length === 0) {
uni.showModal({
title: '当前环境无分享渠道!',
showCancel: false
})
return;
}
let itemList = this.providerList.map(function (value) {
return value.name
})
uni.showActionSheet({
itemList: itemList,
success: (res) => {
uni.share({
provider: this.providerList[res.tapIndex].id,
scene: this.providerList[res.tapIndex].type && this.providerList[res.tapIndex].type === 'WXSenceTimeline' ? 'WXSenceTimeline' : "WXSceneSession",
type: 0,
title:'欢迎体验uni-app',
summary: 'uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架',
imageUrl:'https://img-cdn-qiniu.dcloud.net.cn/uploads/nav_menu/8.jpg',
href:"https://m3w.cn/uniapp",
success: (res) => {
console.log("success:" + JSON.stringify(res));
},
fail: (e) => {
uni.showModal({
content: e.errMsg,
showCancel:false
})
}
});
}
})
}
}
}
</script>
<style>
page,
view {
display: flex;
}
page {
min-height: 100%;
background-color: #FFFFFF;
}
image{
max-width: 400px;
height: 400px;
}
.about{
flex-direction: column;
flex: 1;
}
.content{
flex: 1;
padding: 30px;
flex-direction: column;
}
.desc{
margin-top: 30px;
display: block;
}
.code{
color: #e96900;
background-color: #f8f8f8;
}
button{
width: 100%;
margin-top: 40px;
}
.version{
height: 80px;
line-height: 80px;
justify-content: center;
color: #ccc;
}
</style>
......@@ -5,7 +5,7 @@
<text class="feedback-quick" @tap="chooseMsg">快速键入</text>
</view>
<view class="feedback-body">
<textarea auto-focus="true" placeholder="请详细描述你的问题和意见..." v-model="sendDate.content" class="feedback-textare" />
<textarea placeholder="请详细描述你的问题和意见..." v-model="sendDate.content" class="feedback-textare" />
</view>
<view class='feedback-title'>
<text>图片(选填,提供问题截图,总大小10M以下)</text>
......@@ -73,12 +73,12 @@
let deviceInfo = {
appid: plus.runtime.appid,
imei: plus.device.imei, //设备标识
p: plus.os.name === 'Android' ? 'a' : 'i', //平台类型,i表示iOS平台,a表示Android平台。
p: plus.os.name === "Android" ? "a" : "i", //平台类型,i表示iOS平台,a表示Android平台。
md: plus.device.model, //设备型号
app_version: plus.runtime.version,
plus_version: plus.runtime.innerVersion, //基座版本号
os: plus.os.version,
net: '' + plus.networkinfo.getCurrentType()
net: "" + plus.networkinfo.getCurrentType()
}
this.sendDate = Object.assign(deviceInfo, this.sendDate);
},
......@@ -93,7 +93,7 @@
},
chooseImg() { //选择图片
uni.chooseImage({
sourceType: ['camera', 'album'],
sourceType: ["camera", "album"],
sizeType: "compressed",
count: 9,
success: (res) => {
......@@ -119,7 +119,7 @@
})
console.log(imgs)
uni.uploadFile({
url: 'https://service.dcloud.net.cn/feedback',
url: "https://service.dcloud.net.cn/feedback",
files: imgs,
formData: this.sendDate,
success: (res) => {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册