盘点uni-app项目nvue开发常见踩坑注意点

lxf2023-04-05 22:33:01

uni-app支持vue和nvue两种页面开发模式。简而言之,vue页面是调用设备的浏览器webview来渲染,nvue是调用Weex模式编译原生模式来渲染(Weex是阿里发布的一款用WEB方式开发原生app的开源产品)。

性能上,nvue要强于vue,如这些场景:长列表、区域滚动、瀑布流、map、video等。一般来说,项目可以nvue和vue组合式开发,比如首屏主页面使用nvue,会大大提高App打开速度。在开发上,nvue和vue的template和script开发模式几乎一样(略有区别),区别比较大的在于CSS样式,因为nvue的CSS是vue的CSS的一个子集,所以有些特性不支持,下面简单盘点一下需要注意的地方:

盘点uni-app项目nvue开发常见踩坑注意点

1 template部分

可使用nvue专用组件

nvue专用组件目前有Barcode扫码组件、list列表组件、cell单元格组件、 recycle-list强化列表组件、waterfall瀑布流组件和refresh下拉刷新组件,这些组件在渲染、交互方面上性能要优于vue。

<template>
  <list>
    <!-- 注意事项: 不能使用 index 作为 key 的唯一标识 -->
    <cell v-for="(item, index) in dataList" :key="item.id">
      <text>{{item.name}}</text>
    </cell>
  </list>
</template><script>
  export default {
    data () {
      return {
        dataList: [{id: "1", name: 'A'}, {id: "2", name: 'B'}, {id: "3", name: 'C'}]
      }
    }
  }
</script>

文本要放在中

nvue显示文字,要用text标签套起来,并且只有text标签才可以通过CSS设置字体大小、字体颜色等属性,同时注意:text标签不会继承父标签的样式。文本换行写内容,会出现无法去除的周边空白。

<view>
    <text>Hello</text>
</view>

不支持v-show,仅支持v-if

v-show是通过CSS的display的none和block进行动态切换显示状态,所以nvue会失效,可以通过v-if来实现,或者通过

image标签不支持SVG图片格式

image标签支持jpg、png常见图片类型,也支持base64编码图片,但不支持SVG图片

2 script部分

不支持onLoad生命周期函数

可使用mounted()

nvue 向 vue 传值通讯

nvue使用uni.postMessage(data)发送数据,data参数只能是json,json数值必须是字符串

vue使用onUniNViewMessage进行接收:

<script>
    // nvue 发送
    export default {
        methods: {
            postMessage(item){
                uni.postMessage({
                    name:'你好,新世界',
                    data:item
                })
            }
        }
    }
</script><script>
    // vue 接收
    export default {
        onUniNViewMessage:(e) => {
            const data = e.data
            uni.$emit(‘data’,data)
        }
    }
</script>

vue 向 nvue 传值通讯

可以使用两种方法,一是使用缓存数据的方式:vue通过uni.setStorageSync存数据,nvue通过uni.getStorage来读取接收;二是使用globalData 全局数据方式:

// vue 设置全局数据
globalData: {
    name: '你好,新世界'
}
// nvue 读取该数据
let name = getApp().globalData.name

3 CSS部分

不支持CSS编译器

nvue只能使用CSS,不支持任何CSS预编译器(Sass、Less、Stylus)

不支持import引入全局样式

App.vue中使用import引入的全局样式,在nvue中不可使用,需要使用style src属性来引入。

<style src="@/static/public.css">
    …………
</style>

只支持CSS单类选择器

不支持id选择器、相邻兄弟选择器、普通兄弟选择器、子选择器、后代选择器等,支持并集选择器。

只支持Flex弹性布局

默认是flex-direction: column;这一点和vue页面设置flex默认行排列不一样,如果需要按行排列,需要我们在样式里,添加flex-direction: row;也可以使用manifest.json的全局配置:flex-direction属性。

.calculate {
    display: flex;
    flex-direction: row;
}

不支持百分比布局、不支持rem、vw、vh单位

width:100%、font-size:2rem、height:50vh,这样的CSS单位均在nvue里不支持,nvue仅支持px(绝对像素)和rpx(相对像素),建议开发使用rpx单位,750rpx为设备宽度。

最外层view高度需占满屏时,由于100%、100vh不支持,解决方案是,横向设置宽度为750rpx,纵向添加flex:1的属性。

不支持background-image

nvue,不支持在CSS中设置background-image,如全屏背景图需通过image组件与定位来设置,如下:

<view class="content">
    <image src="../../static/bg.png" mode="scaleToFill"
           style="position: absolute; left: 0; top: 0; right: 0; bottom: 0; "></image>
    <!-- 页面其他内容 -->
</view>
<style>
    .content {
        /** 设置高度100% **/
        flex: 1; 
    }
</style>

按钮添加背景图:

<button class="keyBtn" @tap="key(4)">
    <image src="../../static/keyimages/4.png" mode="aspectFit" style="width: 100rpx;"></image>
</button>

fixed定位不支持Z-index

fixed不支持z-index层级属性,后面的元素始终会比前面的层级高。

fixed上下左右四个偏移量中,如果只想用bottom或者right来定位,需要一并设置top:auto或left:auto

:class :style 仅支持绑定数组模式

4 其他

使用nvue项目开发中,uni-app项目中必须有一个vue页面,否则报错Uncaught Error

同一个页面路由下,如有同名vue和nvue文件,App端会渲染nvue页面,非App端会使用vue页面。