tencent cloud

腾讯云超级应用服务

动态与公告
【2025年1月2日】关于腾讯云小程序平台更名为腾讯云超级应用服务的公告
控制台更新动态
Android SDK 更新动态
iOS SDK 更新动态
Flutter 更新动态
IDE 更新动态
基础库更新动态
产品简介
产品概述
产品优势
应用场景
购买指南
计费概述
按量计费(后付费)
续费指引
停服说明
快速入门
套餐管理
概述
控制台账号管理
存储配置
加速配置
品牌化配置
平台功能
控制台登录
用户和权限体系
小程序管理
小游戏管理
应用管理
商业化
平台管理
用户管理
团队管理
运营管理
安全中心
代码接入指引
Demo 及 SDK 获取
Android
iOS
Flutter
App 服务端接入指南
GUID 生成规则
小程序开发指南
小程序介绍与开发环境
小程序代码组成
指南
框架
组件
API
服务端
JS SDK
基础库
IDE 使用指南
小游戏开发指南
指南
API
服务端
实践教程
小程序登录实践教程
小程序订阅消息实践教程
支付相关实践教程
广告接入实践教程
小游戏订阅消息实践教程
相关协议
数据处理和安全协议

原生组件

PDF
聚焦模式
字号
最后更新时间: 2025-04-22 18:11:25

原生组件

我们部分组件是由客户端创建的原生组件。这些原生组件是由小程序客户端实现的,具有更高的性能和更丰富的功能。
原生组件包括:
camera:相机组件,用于调用摄像头拍照或录像;
Canvas:画布组件,用于绘制图形、动画等;
input:仅在 focus 时表现为原生组件;
textarea:多行输入框组件,用于输入多行文本;
video:视频组件,用于播放视频;
liver-player:实时音视频播放组件,用于播放直播流;
live-pusher:实时音视频录制组件,用于推送直播流;
map:地图组件,用于显示地图和地图上的标记、路线等;
ad:Banner 广告;
web-view:承载网页的容器。

原生组件的使用限制

由于原生组件脱离在 WebView 渲染流程外,因此在使用时有以下限制:
原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。后插入的原生组件可以覆盖之前的原生组件。
原生组件无法在<picker-view>中使用。
部分 CSS 样式无法应用于原生组件,例如:
无法对原生组件设置 CSS 动画。
无法定义原生组件为position: fixed
不能在父级节点使用overflow: hidden来裁剪原生组件的显示区域。
原生组件的事件监听不能使用bind:eventname的写法,只支持bindeventname。原生组件也不支持catchcapture的事件绑定方式。
原生组件会遮挡 vConsole 弹出的调试面板。
说明:
在工具上,原生组件是用 web 组件模拟的,因此很多情况并不能很好的还原真机的表现,建议开发者在使用到原生组件时尽量在真机上进行调试。

安卓平台非同层渲染限制

原生组件在 ​iOS 上采用同层渲染​,而安卓均为非同层渲染,所以安卓平台下存在以下特有限制:

​1. 层级绝对优先

安卓原生组件始终处于视图最顶层,即使后插入的普通组件也无法覆盖。

解决方案:

使用专为覆盖原生组件设计的组件 cover-viewcover-image
示例代码
<video>
<cover-view class="controls">自定义播放控件按钮</cover-view>
</video>
注意:
仅支持嵌套在指定原生组件内
样式属性受限(仅支持opacity\\padding\\border-radius\\rotate\\scaleX\\scaleY\\width\\height\\left\\top\\background-color等简单样式)
无法包含其他普通子组件

​2. 动态位置调整受限

动态调整原生组件位置时可能出现闪烁、残影,尤其在快速移动、缩放时,原生渲染层与WebView视图层异步渲染机制易导致画面撕裂。

解决方案:

通过 wxs 响应触摸事件,实时计算坐标,动态调整原生组件位置。由于 wxs 能够直接处理视图层的事件,减少了与逻辑层的通信开销。例如对于频繁触发的触摸事件,使用 wxs 可以获得更好的性能表现。
示例代码
WXML
WXS
WXSS
<wxs src="./index.wxs" module="touch" />

<view class="container">
<view class="videoBox"
bind:touchstart="{{touch.touchstart}}"
bind:touchmove="{{touch.touchmove}}"
bind:touchend="{{touch.touchend}}">
<video class="video-item" src="视频地址1" controls />
<video class="video-item" src="视频地址2" controls />
<video class="video-item" src="视频地址3" controls />
</view>
</view>
// index.wxs
let startY = 0; // 起始Y坐标
let isStart = false; // 是否开始滑动
let moveDistance = 0; // 移动距离
let currentOffset = 0; // 保存累计偏移量


// 触摸开始事件
function touchstart(event, ins) {
if (!isStart) {
isStart = true;
const touch = event.touches[0];
startY = touch.pageY;
}
}


// 触摸移动事件
function touchmove(event, ins) {
const { pageY } = event.touches[0];
moveDistance = currentOffset + (pageY - startY);
// 更新元素位置
ins.selectComponent('.videoBox').setStyle({
transform: `translateY(${moveDistance}px)`
});
}


// 触摸结束事件
function touchend(event, ins) {
isStart = false;
currentOffset = moveDistance;
}


module.exports = {
touchstart,
touchmove,
touchend
};
.container {
width: 100vw;
height: 100%;
position: relative;
overflow: hidden;
top: 0;
position: absolute;
background: #000;
}

.videoBox {
width: 100vw;
height: 100%;
position: absolute;
}

.video-item {
width: 100vw;
height: 100%;
display: block;
}

3. 动态内容更新受限

覆盖在原生组件上的 cover-view 内容更新延迟或闪烁(如实时文本更新)。

解决方案:

减少高频更新(如用防抖函数控制渲染频率),或改用静态内容。
示例代码
WXML
JAVASCRIPT
<live-pusher>
<cover-view class="danmu">{{danmuText}}</cover-view>
</live-pusher>
// utils/debounce.js
function debounce(fn, delay = 300, immediate = false) {
let timer = null;
return function (...args) {
if (timer) clearTimeout(timer);
if (immediate && !timer) {
fn.apply(this, args); // 立即执行一次
}
timer = setTimeout(() => {
if (!immediate) {
fn.apply(this, args);
}
timer = null;
}, delay);
};
}
module.exports = debounce;



// pages/live.js
const debounce = require('../../utils/debounce');

Page({
data: { danmuText: '' },
onLoad() {
// 创建防抖后的更新函数,并绑定当前 Page 的 this
this.debouncedUpdateDanmu = debounce(this.updateDanmu.bind(this), 300);
},

updateDanmu(text) {
this.setData({ danmuText: text });
}

// 接收WebSocket实时消息
onSocketMessage(msg) {
this.debouncedUpdateDanmu(msg.content); // 高频调用会自动合并
}
});

4. 底部弹出层受限

当需要覆盖全屏原生组件(如videolive-player)实现底部弹出层时,虽然可以通过 cover-view 实现,但会存在以下限制:
交互能力受限cover-view仅支持嵌套cover-viewcover-image,所以弹出层中无法包含复杂交互,例如表单提交。
性能瓶颈:弹出层内如果需要插入大量cover-viewcover-image时易引发渲染卡顿。

解决方案:

通过动态调整原生组件容器高度,使弹出层与原生组件在布局上无重叠,从而使用普通组件(如 view)实现弹出层。
示例代码
WXML
JAVASCRIPT
WXSS
<view class="container">
<live-pusher class="liver-pusher" url="{{pusherUrl}}" autopush="{{true}}" mode="RTC">
<cover-view class="action-button" catchtap="handleOpen">打开弹出层</cover-view>
<cover-view class="action-button close" catchtap="handleClose">关闭弹出层</cover-view>
</live-pusher>
<view class="comments-modal" wx:if="{{open}}">
<input placeholder="这是一个输入框"/>
</view>
</view>
Page({
data: {
open: false,
},
handleOpen: function () {
this.setData({
open: true
})
},
handleClose: function () {
this.setData({
open: false
})
},
})
.container {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
background-color: #000;
}
.liver-pusher {
width: 100%;
flex: 1;
}
.action-button {
position: absolute;
height: 50px;
line-height: 50px;
text-align: center;
background-color: white;
}

.close {
left: 100px;
}

.comments-modal {
width: 100%;
background-color: #fff;
height: 40vh;
}


帮助和支持

本页内容是否解决了您的问题?

填写满意度调查问卷,共创更好文档体验。

文档反馈