微信小程序通过uni-app实现v-html渲染视图

v-html介绍

如果不使用v-html而是直接将html标签加入视图层会出现html标签不解析的情况,如果我们想实现解析的效果。vue中提供了v-html指令。使用 v-html 指令,你可以将html标签解析渲染到视图层。

微信小程序如何使用?

由于微信小程序只是类vue的,与vue存在着很多不同点。但是为了秉承将vue进行到底的宗旨,很多微信小程序开发框架如雨后春笋。在我使用的过程中,感觉uni-app与vue最为贴近,而且适配了很多vue的特性,如:v-model,filters,v-html等。官网是这样介绍的。

uni-app支持的vue特性

其中,他们是通过微信小程序rich-text的属性来实现v-html的效果的。所以,我们想知道支持什么标签,就得移步至rich-text | 微信开发文档

开始实现 Demo

demo 中的需求是一个赛事报名 list,其中赛事状态有:预报名、报名成功、正在进行、已结束等。

下面的代码只展示渲染链路,真正接入时还要根据项目的数据结构调整字段名。文章记录的是当时的 uni-app / 微信小程序实践,组件支持范围应以当前官方文档为准。

<template>
  <view class="event-status">
    <rich-text :nodes="renderStatus(event.status)"></rich-text>
  </view>
</template>

<script>
export default {
  data() {
    return {
      event: { status: 'pending' }
    }
  },
  methods: {
    renderStatus(status) {
      const labels = {
        pending: '预报名',
        registered: '报名成功',
        running: '正在进行',
        finished: '已结束'
      }

      const label = labels[status] || '状态未知'
      return `<span>${label}</span>`
    }
  }
}
</script>

这里的关键不是把 HTML 原样塞进模板,而是让 methods 根据业务状态返回最终节点。状态值不在白名单时给出兜底文本,避免接口返回异常时页面出现空白。

在把后台内容交给 rich-text 之前,应该只允许业务确实需要的标签,并过滤危险 URL、超宽图片和不必要的内联样式。不要把用户提交的任意 HTML 直接渲染到页面。

预实现方法:由于微信小程序的rich-text组件会禁用所有的节点事件,所以想通过@click绑定v-html节点事件,filter渲染界面。但是在实现过程中发现不支持在v-html中使用filter, 故后来采用methods的返回值来实现视图层的渲染。

methods实现v-html渲染

效果如下:至此效果,v-html解析成功

v-html 渲染效果

添加状态判断

最终效果

动态 HTML 还要考虑安全和样式

这种做法适合渲染自己后台生成、经过清洗的富文本,不要把用户提交的任意 HTML 直接交给页面。即使小程序不完全等同浏览器 DOM,危险链接、超宽图片、内联样式和不支持的标签仍会破坏页面。渲染前应做标签白名单和 URL 过滤,并给图片、代码块和表格准备统一的容错样式。

测试时至少要覆盖空内容、超长段落、多图片和嵌套列表。

可用性说明:本文发布于 2019 年 7 月,距今已超过五年。文中涉及的软件版本、接口、下载地址、命令参数和操作界面可能已经发生变化,部分方案在当前环境下可能失效。请结合官方最新文档核对后再操作,生产环境使用前务必先行验证。

版权声明: 本文首发于 指尖魔法屋-微信小程序通过uni-app实现v-html渲染视图(https://blog.thinkmoon.cn/post/314-wechat-miniprogram-practice-wechat-uni/) 转载或引用必须申明原指尖魔法屋来源及源地址!