Skip to content

UniApp nvue 原生渲染 ​

概述 ​

uni-app App 端内置基于 weex 改进的原生渲染引擎。vue 页面使用 webview 渲染,nvue 页面(native vue)使用原生渲染。一个 App 中可以同时使用两种页面。

nvue 也可多端编译输出 H5 和小程序,但 css 写法受限,不开发 App 时不需要使用 nvue。

适用场景 ​

  1. 高性能区域长列表或瀑布流滚动
  2. 复杂自定义下拉刷新
  3. 左右拖动长列表
  4. 区域滚动长列表 + 左右拖动 + 吸顶
  5. 软键盘右下角按钮改为"发送"
  6. 解决原生控件层级问题
  7. 深度使用 map 组件
  8. 深度使用 video 组件
  9. 直播推流
  10. 对 App 启动速度要求极致化

纯原生渲染模式 ​

manifest.json 中配置 renderer: "native" 启用纯原生渲染,可减少包体积和内存占用。此时 vue 页面将被忽略。

编译模式 ​

weex 编译模式uni-app 编译模式
平台仅 App所有端
组件weex 组件如 divuni-app 组件如 view
生命周期weex 生命周期所有 uni-app 生命周期
JS APIweex API、uni API、Plus API同左
单位750px 是屏幕宽度750rpx 是屏幕宽度
全局样式手动引入app.vue 即可
页面滚动必须套组件默认支持

在 manifest.json 中配置:

json
{
  "app-plus": {
    "nvueCompiler": "uni-app"
  }
}
{
  "app-plus": {
    "nvueCompiler": "uni-app"
  }
}

nvue vs vue 开发区别 ​

  1. 显隐只可用 v-if,不可用 v-show
  2. 只能使用 flex 布局,默认排列方向为 column
  3. 文字内容必须在 <text> 组件下
  4. 只有 text 标签可设置字体大小、颜色
  5. 不能使用百分比、媒体查询
  6. 不支持 background-image 背景图
  7. css 选择器只支持 class 选择器
  8. class 绑定只支持数组语法
  9. Android 端各组件默认透明,需设置 background-color
  10. Android 端大量圆角边框会造成性能问题
  11. 没有 bounce 回弹效果(list/waterfall 等组件除外)
  12. App.vue 中定义的全局 js 变量在 nvue 不生效,globalData 和 vuex 生效
  13. style 中不能引入字体文件
  14. 不支持 TypeScript

样式 ​

盒模型 ​

nvue 盒模型 box-sizing 默认为 border-box。Android 仅支持 overflow:hidden,iOS 支持 hidden 和 visible。

Flexbox ​

Flexbox 是默认且唯一的布局模型,不需要手动设置 display: flex。不支持 flex-shrink、flex-basis、align-content 以及 flex 简写。

定位 ​

Android 下定位元素超过容器边界将不可见(overflow 默认 hidden)。

伪类 ​

参数支持组件
active所有组件
focusinput、textarea
disabledinput、textarea
enabledinput、textarea

线性渐变 ​

css
background-image: linear-gradient(to bottom right, #AD18F9, #05DFC7);
background-image: linear-gradient(to bottom right, #AD18F9, #05DFC7);

只支持两种颜色渐变,不支持 radial-gradient(径向渐变)。background-image 优先级高于 background-color。

阴影 ​

Android 平台设置 box-shadow 时需要让出阴影渲染位置(使用 margin)。

文本样式 ​

  • 只有 text 标签可设置 color、font-size
  • font-weight 支持:normal、bold 以及 100-900
  • iOS 支持 9 种,Android 仅支持 400 和 700
  • text-overflow 支持 clip 和 ellipsis

API ​

DOM - addRule(加载自定义字体) ​

js
const domModule = uni.requireNativePlugin('dom')
domModule.addRule('fontFace', {
  fontFamily: 'myIconfont',
  src: "url('http://at.alicdn.com/t/font_xxx.ttf')",
})
const domModule = uni.requireNativePlugin('dom')
domModule.addRule('fontFace', {
  fontFamily: 'myIconfont',
  src: "url('http://at.alicdn.com/t/font_xxx.ttf')",
})

DOM - scrollToElement ​

js
const dom = uni.requireNativePlugin('dom')
dom.scrollToElement(this.$refs.item10, { offset: 0, animated: true })
const dom = uni.requireNativePlugin('dom')
dom.scrollToElement(this.$refs.item10, { offset: 0, animated: true })

DOM - getComponentRect ​

获取元素外框:

js
dom.getComponentRect(this.$refs.test, (res) => { console.log(res.size) })
dom.getComponentRect(this.$refs.test, (res) => { console.log(res.size) })

animation 动画 ​

js
const animation = uni.requireNativePlugin('animation')
animation.transition(this.$refs.test, {
  styles: { backgroundColor: '#007AFF', transform: 'translate(100px, 80px)' },
  duration: 800,
  timingFunction: 'ease',
  delay: 0,
}, () => { /* 完成回调 */ })
const animation = uni.requireNativePlugin('animation')
animation.transition(this.$refs.test, {
  styles: { backgroundColor: '#007AFF', transform: 'translate(100px, 80px)' },
  duration: 800,
  timingFunction: 'ease',
  delay: 0,
}, () => { /* 完成回调 */ })

BindingX ​

BindingX 是原生解析的预描述交互语法,由原生处理视图层交互和动效,减少通信损耗:

js
const Binding = uni.requireNativePlugin('bindingx')
Binding.bind({
  eventType: 'timing',
  exitExpression: 't>800',
  props: [{
    element: main_image,
    property: 'transform.rotateZ',
    expression: 'easeOutQuint(t,45,0-45,800)',
  }],
}, (res) => { if (res.state === 'exit') Binding.unbind({ token: main_binding.token }) })
const Binding = uni.requireNativePlugin('bindingx')
Binding.bind({
  eventType: 'timing',
  exitExpression: 't>800',
  props: [{
    element: main_image,
    property: 'transform.rotateZ',
    expression: 'easeOutQuint(t,45,0-45,800)',
  }],
}, (res) => { if (res.state === 'exit') Binding.unbind({ token: main_binding.token }) })

nvue 和 vue 通信 ​

推荐使用 uni.$on / uni.$emit 进行页面通讯:

js
// 发送方
uni.$emit('page-popup', { title: 'title', content: 'content' })
// 接收方
uni.$on('page-popup', (data) => { console.log(data.title) })
// 发送方
uni.$emit('page-popup', { title: 'title', content: 'content' })
// 接收方
uni.$on('page-popup', (data) => { console.log(data.title) })

共享变量方案:

  • vuex:自 HBuilderX 2.2.5 起 nvue 支持
  • uni.storage:nvue 和 vue 共享
  • globalData:全端通用

nvue 不支持的 uni-app API ​

API说明替代方案
uni.createAnimation()创建动画实例animation 模块
uni.pageScrollTo()页面滚动scrollToElement
uni.createIntersectionObserver()节点布局交互—

iOS 平台注意 ​

list、waterfall 组件内容不足时无法触发下拉刷新,可通过配置 alwaysScrollableVertical="true" 解决。