nvue页面

限制

1.uni.scss

nvue文件存在的情况下,使用nvue不支持的样式会警报。采用条件编译不生效

/* #ifndef APP-PLUS-NVUE */
uni-button[plain]{
    border: none;
}
/* #endif */

2.App.vue中引用的全局样式,需要使用条件编译,因为编译nvue页面时,也会对app.vue进行编译 

3.宽高不支持百分比、vw、vh,一般使用position:absolute撑满页面

4.文字一般使用<text>

5.只能使用 class 选择器

6.只支持flex布局,且默认 flex-direction: column;

7.很多样式不支持......

优点

1.组件

在页面中某个区域做长列表滚动,需要高性能的区域长列表或瀑布流滚动。listrecycle-listwaterfall,性能好于scroll-view。webview 的页面级长列表滚动是没有性能问题

原因在于list在不可见部分的渲染资源回收有特殊的优化处理

方法一:使用offset-accuracy属性和scroll方法

缺点:无法控制离底部多久会触发,当滑动到最底部才触发

  • offset-accuracy: 触发scroll事件的频率,单位px,默认10;数字越小触发频率越大  
  • scroll事件:滚动出发
<list ref="list"  :offset-accuracy="100" :scrollable="true" @scroll="handleLoadmore">
    <refresh :display="data.refreshing ? 'show' : 'hide'" @pullingdown="onpullingdown" @refresh="onRefresh" class="refresh">
        <text>加载中...</text>
    </refresh>
    <cell class="box">
        <view v-for="(item, index) in data.imgList" :key="index" class="list_item">
            <image class="item_img" :class="[`${item.checked ? 'is_select' : ''}`]" :src="item.icon_url" />
            <text>{{ index+1 }}</text>
        </view>
        <text>{{ data.finished ? "加载完成了" : "加载中" }}</text>
    </cell>
</list>

 方法二:使用loadmore事件

  • loadmoreoffset:触发loadmore事件时距离底部的距离,单位px 
  • loadmore事件:要在该事件中重置loadmore,否则只触发一次
<!-- nvue页面 -->
<template>
    <view class="picture_list">
        <list ref="listRef" :loadmoreoffset="data.offsetDistance" :scrollable="true" @loadmore="handleLoadmore">
            <refresh :display="data.refreshing ? 'show' : 'hide'" @pullingdown="onpullingdown" @refresh="onRefresh" class="refresh">
                <text>加载中...</text>
            </refresh>
            <cell class="box">
                <view v-for="(item, index) in data.imgList" :key="index" class="list_item">
                    <image class="item_img" :class="[`${item.checked ? 'is_select' : ''}`]" :src="item.icon_url" />
                    <text>{{ index + 1 }}</text>
                </view>
                <text>{{ data.finished ? "加载完成了" : "加载中" }}</text>
            </cell>
        </list>
    </view>
</template>

<script setup>
import { ref, reactive, onMounted } from "vue"
import { getPhotoAlbum } from "@/api/index"

onMounted(() => {
    getPersonalPic()
})

let data = reactive({
    imgList: [], //所有图片列表
    page: 1,
    total: 0,
    offsetDistance: 2000, //距离底部的高度,会触发loadmore事件
    loading: false,
    finished: false,
    refreshing: false //是否正在下拉刷新
})

// 滚动,分页加载
async function getPersonalPic(page) {
    data.loading = true
    let params = { page: data.page, size: 40 }
    page && Object.assign(params, { page: page })
    try {
        if (data.refreshing) data.imgList = []

        const res = await getPhotoAlbum(params)
        data.total = res.data.count
        let imgIdList = data.imgList.map((item) => item.id)
        res?.data.results.forEach((item) => {
            if (!imgIdList.includes(item.id)) {
                // 可以查找下每页的index,然后插入新数据
                data.imgList.push({
                    ...item,
                    checked: false,
                    load: false,
                    page: params.page
                })
            }
        })

        if (!data.imgList.length) {
            uni.showToast({ title: "暂无数据", icon: "none" })
        }
        if (data.imgList.length >= data.total) {
            data.finished = true
        }
        // console.log(res?.data.results)
        data.refreshing = false
        data.loading = false
    } catch (error) {
        if (data.refreshing) data.imgList = []
        data.refreshing = false
        data.loading = false
        uni.showToast({ title: error.message, icon: "none" })
    }
}

let timeId = null
let listRef = ref(null)
function handleLoadmore(e) {
    if (data.loading || data.finished) return
    // 可能会连续触发
    timeId && clearTimeout(timeId)
    timeId = setTimeout(() => {
        if (data.loading || data.finished) return
        listRef.value?.resetLoadmore()
        data.page += 1
        getPersonalPic()
    }, 100)
}

function onRefresh() {
    if (data.refreshing) return
    data.refreshing = true
    data.finished = false
    data.page = 1
    data.total = 0
    // 500ms, 模拟加载时间
    setTimeout(() => {
        getPersonalPic()
    }, 500)
}
</script>

<style lang="scss" scoped>
.picture_list {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #3b4e5d;

    .back_icon {
        margin-top: 20rpx;
        width: 40rpx;
        height: 40rpx;
    }

    .box {
        position: absolute;
        left: 0;
        right: 0;

        @extend .flex_row;
        align-items: flex-start;
        flex-wrap: wrap;
        padding: 3rpx 0rpx 124rpx 40rpx;
        .list_item {
            margin-bottom: 28rpx;
            margin-right: 25rpx;
        }
        .item_img {
            width: 147rpx;
            height: 147rpx;
            border-radius: 16rpx;
        }
    }
}

.flex_row {
    display: flex;
    flex-direction: row;
}
</style>

2.编译速度

nvue页面:使用原生渲染引擎,无论是本地调试还是打包之后,渲染加快。(实测有效)

vue页面:使用webview渲染

3.subnvue

vue 页面的原生子窗体,可以覆盖一些原生组件,类如vedio、map等

使用教程:uni-app subNVue 原生子窗体开发指南 - DCloud问答

nvue介绍:nvue介绍 | uni-app官网

层架问题的处理方式,还有以下两种

  1. app-vue的cover-view 不支持嵌套、只能在 videomap 上使用、样式和控件少;
  2. plus.nativeObj.view 虽然更灵活,但易用性比较差、没有动画、不支持内部内容滚动。

遇到web-view组件时,优先级不确定,谁创建的晚谁的优先级高

(来源:原生组件说明 | uni-app官网

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值