背景
最近在使用 Taro
做微信小程序,其中免不了富文本的需求,而富文本里面,基本上都是用到了 wxParse
。而我在用两者相结合的时候,遇到了问题。
问题
具体看 github.com/NervJS/taro…,总的来说就是 wxParse
解析富文本后,在某些情况下 (什么情况下呢?),节点内容会丢失。
// 组件 wxParse.tsx,接收传入的 props:{content: string}
export default class ParseComponent extends Component<IProps> {
componentDidMount() {
const { content } = this.props;
WxParse.wxParse('content', 'html', content, this.$scope, 5);
}
render() {
return (
<View>
<import src='../../components/wxParse/wxParse.wxml' />
<template is='wxParse' data='{{wxParseData:content.nodes}}' />
</View>
);
}
}
后来大佬给出了解决方法,在 componentDidUpdate
时再解析一次,并让我去看 wxParse
的实现。
// wxParse.tsx
export default class ParseComponent extends Component<IProps> {
...
componentDidUpdate() {
const { content } = this.props;
WxParse.wxParse('content', 'html', content, this.$scope, 5);
}
...
}
理解 wxParse 的实现
在 wxParse
的模板中,找到关键实现,wxParse.wxml
41行
<!--入口模版-->
<template name="wxParse">
<block wx:for="{{wxParseData}}" wx:key="">
<template is="wxParse0" data="{{item}}" />
</block>
</template>
可以看到解析是是从遍历 wxParseData
开始,这个 wxParseData
是从哪里来呢?就是从我们编写的 wxParse.tsx
中的 WxParse.wxParse(...)
中得到,这个方法在内部中会使用 setData
,将解析后的数据写入组件中。关键代码如下:
// wxParse.js 31行
var transData = {};//存放转化后的数据
var bindData = {};
bindData[bindName] = transData; // bindName 为 key 值,按我写的内容对应为 `content`
that.setData(bindData) // that 为组件对象
具体原因
在 wxParse.tsx
组件挂在时候,打印解析内容,可以看到是存在解析内容的。

当我们的父组件更新时,引起了子组件 wxParse.tsx
的更新,然后我们并没有做特殊的处理 (重新解析 props
传过来的内容),于是数据变成了这样

答案也就呼之欲出了,wxParseData
中的 nodes
为空,模板遍历出来的内容也就为空 (消失) 了。
最后
还是感谢大佬抽空解答问题,同时也是自己学艺不精的表现,还需多多努力~