title: 渲染 HTML

请注意:本章节所有内容只在小程序端起效果。

Taro 可以直接通过 Element#innerHTML 或 Vue 的 v-html 或 React/Nerv 的 dangerouslySetInnerHTML 直接渲染 HTML:


  1. function helloWorld() {
  2. const html = `<h1 style="color: red">Wallace is way taller than other reporters.</h1>`
  3. return <View dangerouslySetInnerHTML={{ __html: html }}></View>
  4. }
  1. <template>
  2. <view v-html="html"></view>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. html: `<h1 style="color: red">Wallace is way taller than other reporters.</h1>`
  9. }
  10. }
  11. }
  12. </script>
  1. // Taro 更推荐使用框架自带的渲染 HTML 方式
  2. // 因为不管 React/Nerv/Vue 都会自带一个 diff 机制,可以避免不必要的渲染的开销
  3. // 重复调用 `innerHTML` 会使得应用的性能拖慢。
  4. import { document } from '@tarojs/runtime'
  5. class HelloWorld extends React.Component {
  6. componentDidMount () {
  7. const el = document.getElementById('html')
  8. el.innerHTML = `<h1 style="color: red">Wallace is way taller than other reporters.</h1>`
  9. }
  10. render () {
  11. return <View id="html" />
  12. }
  13. }

自定义 HTML 样式

直接设置 HTML 不会让 HTML 标签带上浏览器的默认样式,Taro 提供两种内置样式我们可以直接引入生效:

  • @tarojs/taro/html.css: W3C HTML4 的内置样式,只有 HTML4 标签样式,体积较小,兼容性强,能适应大多数情况。
  • @tarojs/taro/html5.css: Chrome(Blink) HTML5 的内置样式,内置样式丰富,包括了大多数 HTML5 标签,体积较大,不一定支持所有小程序容器。

为了让内置的标签样式起作用,我们还需要将 HTML 容器的 CSS 类设置为 .taro_html:

  1. import '@tarojs/taro/html.css'
  2. function helloWorld() {
  3. const html = `<h1 style="color: red">Wallace is way taller than other reporters.</h1>`
  4. return <View className="taro_html" dangerouslySetInnerHTML={{ __html: html }}></View>
  5. }
  1. <template>
  2. <view v-html="html" class="taro_html"></view>
  3. </template>
  4. <script>
  5. import '@tarojs/taro/html.css'
  6. export default {
  7. data () {
  8. return {
  9. html: `<h1 style="color: red">Wallace is way taller than other reporters.</h1>`
  10. }
  11. }
  12. }
  13. </script>

同样地,我们也可以自己编写 CSS 样式,Taro 最终渲染的 HTML 标签的类名都和 HTML 标签名保持一致,例如我们的容器 CSS 类名为 my_css,想要设置 h1 标签的样式,那就这样这样做:

  1. .my_css .h1 {
  2. font-size: 30px;
  3. }

你可能会倾向于其他浏览器的默认样式:

HTML 转义

由于进行 HTML 转义需要消耗较多的性能和较大的体积,默认而言 Taro 的 HTML 接口只接受转义后的 HTML 字符串,我们推荐直接在服务端返回转义后的 HTML。如果确实需要在客户端转义,开源社区有两个较好的选择:

  • he: 体积较大,但开源协议更为宽松
  • entities: 体积较小,但开源协议更为严格

你可能会需要高级选项transformText 配合 HTML 转义进行字符串渲染。

绑定事件

出于作用域和安全因素考虑,Taro 会把 HTML 字符串中的事件和 JavaScript 全部清除。但我们仍然有办法给 HTML 绑定事件:

  1. import '@tarojs/taro/html.css'
  2. import { document } from '@tarojs/runtime'
  3. function helloWorld() {
  4. const html = `<h1 id="test">Wallace is way taller than other reporters.</h1>`
  5. useEffect(() => {
  6. const el = document.getElementById('test')
  7. function testOnTap (event) {
  8. // do something
  9. ...
  10. }
  11. el.addEventListener('tap', testOnTap)
  12. return () => {
  13. el.removeEventListener('tap', testOnTap)
  14. }
  15. }, [])
  16. return <View className="taro_html" dangerouslySetInnerHTML={{ __html: html }}></View>
  17. }
  1. <template>
  2. <view v-html="html" class="taro_html"></view>
  3. </template>
  4. <script>
  5. import '@tarojs/taro/html.css'
  6. import { document } from '@tarojs/runtime'
  7. export default {
  8. data () {
  9. return {
  10. html: `<h1 id="test">Wallace is way taller than other reporters.</h1>`
  11. }
  12. },
  13. mounted () {
  14. const el = document.getElementById('test')
  15. el.addEventListener('tap', this.testOnTap)
  16. },
  17. testOnTap (event) {
  18. // do something
  19. ...
  20. },
  21. beforeDestroy () {
  22. const el = document.getElementById('test')
  23. el.removeEventListener('tap', this.testOnTap)
  24. }
  25. }
  26. </script>

如果需要动态绑定事件的元素没有 ID 的话,你可能需要使用高级选项transformElement

高级选项

如果内置的功能无法满足需求或渲染结果不如预期,Taro 还提供了 HTML 渲染的高级选项,高级选项可以通过 Taro.options.html 访问:

  1. import Taro from '@tarojs/taro'
  2. // 不解析 souce 标签中的内容
  3. Taro.options.html.skipElements.add('source')

skipElements

类型:Set<string>

默认值:new Set(['style', 'script'])

HashSet 中包含的 HTML 标签将不会被解析。

voidElements

类型:Set<string>

默认值:new Set([ '!doctype', 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr' ])

HashSet 中包含的 HTML 标签不需要闭合标签,例如 <img />

closingElements

类型:Set<string>

默认值:new Set([ 'html', 'head', 'body', 'p', 'dt', 'dd', 'li', 'option', 'thead', 'th', 'tbody', 'tr', 'td', 'tfoot', 'colgroup' ])

HashSet 中包含的 HTML 标签可以自动闭合,且不能被嵌套。

transformText

类型:(taroText: TaroText, text: Text) => TaroText

默认值:void

该函数第一个参数的值为 Taro 默认处理好的 TaroText,第二个参数是 HTML 解析器解析好的 Text,最后返回的 TaroText 对象参与 HTML 中的字符串渲染。

transformElement

类型:(taroText: TaroElement, text: Text) => TaroElement

默认值:void

该函数第一个参数的值为 Taro 默认处理好的 TaroElement,第二个参数是 HTML 解析器解析好的 Element,最后返回的 TaroElement 对象参与 HTML 元素渲染。