富文本内容神秘消失事件 (Taro & wxParse)

2,028 阅读1分钟

背景

最近在使用 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 组件挂在时候,打印解析内容,可以看到是存在解析内容的。

image

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

image

答案也就呼之欲出了,wxParseData 中的 nodes 为空,模板遍历出来的内容也就为空 (消失) 了。

最后

还是感谢大佬抽空解答问题,同时也是自己学艺不精的表现,还需多多努力~