uni-app中使用towxml
步骤见: https://www.cnblogs.com/chuan2021/p/17223663.html
在微信小程序中的效果:
展示的css可自行调整
支持代码复制:
towxml先用mardown.js把mardown转换成html, 然后再解析html,最后渲染到towxml/decode.wxml页面中, 代码会渲染到
item.tag == "view" 一段中, 这里先在parse/index.js中增加一个参数, 好判断是不是代码块, 增加第18-27行, 为代码块和行内代码块增加raw_tag, 行内代码块不支持复制, 修改结果:
1 arr.forEach(item => {
2 if (item.type === 'comment') {
3 return;
4 };
5 let o = {
6 type: item.type === 'text' ? 'text' : isRichTextContent ? 'node' : item.type
7 },
8 e = {},
9 attrs = o.attrs = item.attribs || {};
10 if (item.type === 'text') {
11 o.text = e.text = item.data;
12 } else {
13 if (isRichTextContent) {
14 o.name = item.name;
15 } else {
16 o.tag = getWxmlTag(item.name); // 转换之后的标签
17 // o.tag = o.tag === 'text' ? 'view' : o.tag;
18 o.raw_tag = item.name
19
20 // code block has parent element with class "h2w__pre"
21 // inline block has parent element with class "h2w__p" or "h2w__li"
22 // inline block no support copy
23 if (item.name == "code" && item.parent && item.parent.attribs && item.parent.attribs.class) {
24 if (item.parent.attribs.class.indexOf('h2w__pre') === -1) {
25 o.raw_tag = "inline_code"
26 }
27 }
28
29 e.tag = item.name; // 原始
30 o.attrs = item.attribs;
31 e.attrs = JSON.parse(JSON.stringify(attrs));
32 };
33 attrs.class = attrs.class ? `h2w__${item.name} ${attrs.class}` : `h2w__${item.name}`;
34
35 // 处理资源相对路径
36 if (base && attrs.src) {
37 let src = attrs.src;
38 switch (src.indexOf('//')) {
39 case 0:
40 attrs.src = `https:${src}`;
41 break;
42 case -1:
43 attrs.src = `${base}${src}`;
44 break;
45 };
46 };
47 };
48
49 o.rely = relyList.indexOf(e.tag) > -1; // 判断是否不能嵌套其它标签
50
51 if (item.children) {
52 eachFn(item.children, o, e, isRichTextContent || item.name === 'rich-text');
53 };
54 child.push(o);
55 child_e.push(e);
56 });
然后在decode.wxml的h2w__viewParent一段下进行判断和增加复制按钮:
towxml/decode.wxml
1 <block wx:if="{{item.tag==='view'}}">
2 <block wx:if="{{item.rely}}">
3 <view data-data="{{item}}" class="{{item.attrs.class}}" data="{{item.attrs.data}}" id="{{item.attrs.id}}" style="{{item.attrs.style}}" catch:tap="_tap">
4 <decode wx:if="{{item.children}}" nodes="{{item}}"/>
5 </view>
6 </block>
7 <block wx:else>
8 <view class="h2w__viewParent">
9 <view data-data="{{item}}" class="{{item.attrs.class}}" data="{{item.attrs.data}}" id="{{item.attrs.id}}" style="{{item.attrs.style}}" catch:tap="_tap">
10 <block wx:if="{{item.raw_tag === 'code'}}">
11 <view style="float: right" catch:tap="_copy" data-data="{{item}}" data="{{item.attrs.data}}">复制</view>
12 </block>
13 <decode wx:if="{{item.children}}" nodes="{{item}}"/>
14 </view>
15 </view>
16 </block>
17 </block>
可以看到这里我们新增了一个copy函数, 专门支持复制代码块, 为了支持新event. 还需要改towxml/config.js中的events字段:
1 events:[
2 // 'touchstart',
3 // 'touchmove',
4 // 'touchcancel',
5 // 'touchend',
6 'tap', // 用于元素的点击事件
7 'change', // 用于todoList的change事件
8 'copy', // 代码复制事件
9 ],
然后就可以在uni-app中处理该点击事件:
1 let md = this.$towxml(src,
2 'markdown', {
3 // base: 'https://xxx.com', // 相对资源的base路径
4 theme: 'light', // 主题,默认`light`
5 events: { // 为元素绑定的事件方法
6 tap: (e) => {
7 console.log('tap', e);
8 },
9 copy: (e) => {
10 console.log(e.target.dataset.data)
11 let copyed_code = ""
12
13 const extract_code = (parsed_item) => {
14 if (!parsed_item.children) {
15 return
16 }
17 parsed_item.children.forEach(item => {
18 if (item.raw_tag == "ul" || (item.attrs.class && item.attrs.class
19 .indexOf("h2w__lineNum") != -1)) {
20 console.log('find number')
21 return
22 } else if (item.raw_tag == "p") {
23 copyed_code = copyed_code + "\n\n"
24 } else if (item.raw_tag == "br") {
25 copyed_code = copyed_code + "\n"
26 } else if (item.type == "text") {
27 copyed_code = copyed_code + item.text
28 } else {
29 extract_code(item)
30 }
31 })
32 }
33
34 extract_code(e.target.dataset.data)
35
36 uni.setClipboardData({
37 data: copyed_code,
38 showToast: true,
39 });
40 },
41 }
42 });
43 this.article = md;
因为事件中的dataset传过来的是解析好的数据, 这里重新组件了一下, 代码有些简陋, 可以自行修改.
来源:https://www.cnblogs.com/chuan2021/p/17223727.html |