首页 h5开发 正文内容

uni-app 编译到 H5 input 、 canvas 等原生 HTML 组件无法使用的问题如何解决?

2023年12月29日 , 606

uni-app 发布到 h5 时,部分内置组件和html 原生组件冲突了,这篇文章分享我的解决方法。

问题描述

除了小程序App,现在很多 uni-app 项目也要发布为 h5 了,这是因为后端用 uniCloud 真的很方便,完全不需要像传统开发那样去搭建服务器,而且 uni-app 对 web 的支持也越来越完善了。

但一直以来我都发现,像 input 这样的组件,无法像 html 原生 input 那样来使用,这会产生一些问题。

问题原因分析

这个问题一直困扰我,但没有专门去深入研究解决,就是如果我在 uni-app 项目中编写 <input></input> 或者是 canvas 这样的组件时,运行到浏览器里都会被解析成 uni-app 内置的组件,通过浏览器开发者工具看运行时的代码,发现套了好几层。

<uni-input data-v-1a3822d0="" class="uni-input">
  <div class="uni-input-wrapper">
    <div class="uni-input-placeholder input-placeholder" data-v-1a3822d0="">自动获得焦点</div>
    <input maxlength="140" step="" enterkeyhint="done" autocomplete="off" type="" class="uni-input-input">
  </div>
</uni-input>

这不是 html 原生的 input 组件,会导致某些事件无法获取到默认值,非常麻烦。

最近我的 uni-app 项目中引入了 for web 的 canvas 库,传入的初始化参数是 canvas 的 id 属性,但 canvas 同样是 uni-app 的基础组件,会被解析成 <uni-canvas></uni-canvas> ,内层的 canvas 节点没有 id 属性。

canvas 被解析成 uni-app 内置组件
canvas 被解析成 uni-app 内置组件

解决方法

我尝试在组件渲染完成后获取到最里面的 canvas 节点,然后设置 id 属性,虽然也能解决问题,但非常不优雅。后来我发现了一种很简单的方式,就是在 <template></template> 编写代码时,用大写的 CANVAS,这样 uni-app 就不会把这个组件识别为内置组件,但 html 会正常解析为 canvas 元素:

<template>
...
  <CANVAS id="viewer" ref="viewer" :width="width" :height="height"></CANVAS>
...
</template>

好了,这样就可以在浏览器中为所欲为了。同理,input 组件以及那些和 html 原生组件同名的组件都可以用这种方法解决。