uni-app

Uni 开发常见问题

2021-01-28  本文已影响0人  沉江小鱼

使用 uni 开发一段时间了,一份代码提交了AppStore + 安卓各市场 + 百度小程序 + 微信小程序,记录下常用的知识点和问题,比较杂,但是效果好。

1. 布局相关

1.1 控制文本行数显示

控制显示指定行数文本:

.content{
    overflow: hidden;
    text-overflow: ellipsis; // 文本溢出显示省略号
    display: -webkit-box;
    -webkit-line-clamp: 2;   // 指定控制的行数
    -webkit-box-orient: vertical;
}

控制显示单行文本:

.content{
    overflow: hidden;
    text-overflow: ellipsis;    // 文本溢出显示省略号
    white-space: nowrap;    // 文本不会换行(单行文本溢出)
    background-color: red;
}
1.2 指定元素填满父元素剩余空间
image.png
.parent{
    padding: 20rpx;
    display: flex;
    flex-direction: row;
    align-items: center;
    background-color: #EDEDED;
}
    
.title{
    flex: 1; // 控制占据剩余所有空间
    // 控制单行显示
    overflow: hidden;   
    white-space: nowrap; 
    text-overflow: ellipsis;
}
    
.status{
    // 这个正常写就行,
    background-color: #007AFF;
    color: #FFFFFF;
    padding: 10rpx;
    font-size: 24rpx;
}
1.3 文本中有长数字/字母时换行
image-2.png
设置word-break: break-all;
.p2{
    word-break: break-all;
}
1.4 显示html文本

v-html在小程序中不显示,可以使用rich-text组件:

<template>
    <view class="content">
        <!-- APP & H5中可以显示,小程序中不会显示 -->
        <text v-html="msg"></text>

        <!-- 推荐使用rich-text -->
        <rich-text :nodes="msg"></rich-text>
    </view>
</template>

...
data() {
    return {
        msg : "<h1>这是一个h1元素内容</h1>"
    }
}
...
1.5 顶部有fixed元素时的布局

顶部筛选元素为fixed,底部list布局仍然从·顶部·开始:

  1. 设置list的padding-top为筛选元素的高度
  2. list顶部设置一个和筛选元素同高度的占位视图
1.6 View底部添加分割线

可以只设置view的底部边框,不用再去写一个view当做分割线:

.item{
    padding: 20rpx 0rpx;
    border-bottom: solid 1rpx #ededed;
}
1.7 导航栏添加按钮(小程序不支持)

自定义性较差,不支持自定义图片按钮,可以通过自定义导航栏实现。
官方文档:https://uniapp.dcloud.io/collocation/pages?id=app-titlenview-buttons

/* pages.json中对页面增加导航栏按钮 */
{
    "path": "pages/tabbar/found/index",
    "style": {
        "navigationBarTitleText": "页面标题",
        /* 关键代码,添加右上角按钮 */
        "titleNView": {
            "buttons": [{
                "text": "收藏",
                "float": "right", // 控制左右
                "width": "auto",
                "fontSize": 14,
                "color": "#333333"
            }]
        }
    }
}

/* 页面中监听按钮点击事件 */
onNavigationBarButtonTap(val) {
    if (val.index == 0) {
        console.log("第1个按钮");
    }
}

/* 页面中动态改变按钮 --> !!!前提是pages.json中已经添加按钮,只能动态修改,如果想要隐藏,可以设置width=0,text="" !!! */
// #ifdef APP-PLUS
let webView = this.$mp.page.$getAppWebview();
// 0 是指定修改的按钮的下标
webView.setTitleNViewButtonStyle(0, {
    "float": "right",
    "text": '已收藏',
    "fontSize": "16",
    "width": "0",
    "color": "#313c5d"
});
// #endif

页面中动态改变按钮的前提是pages.json中已经添加按钮,只能动态修改,如果想要隐藏,可以设置width=0,text=""

1.8 设置rpx最大支持设备宽度

比如Pad,使用rpx单位时对元素按设备宽度比例放大,元素显示会非常大,此时可以设置rpxCalcMaxDeviceWidth,按照基准宽度计算:

/* pages.json中设置 */
"globalStyle": {
    "navigationBarTextStyle": "black",
    "navigationBarBackgroundColor": "#F8F8F8",
    "backgroundColor": "#F8F8F8",
    "rpxCalcMaxDeviceWidth": 500, // 计算所支持的最大设备宽度,单位 px,默认值为 960
    "rpxCalcBaseDeviceWidth": 375, // 计算使用的基准设备宽度,设备实际宽度超出 rpx 计算所支持的最大设备宽度时将按基准宽度计算,单位 px,默认值为 375
    "rpxCalcIncludeWidth": 750 // 计算特殊处理的值,始终按实际的设备宽度计算,单位 rpx,默认值为 750
},

2. 功能相关

2.1 下拉刷新&上拉加载

单列表页面,推荐使用页面级滚动 ( webview渲染的页面中,区域滚动的性能不及页面滚动 )。

2.1.1 下拉刷新

官网地址:https://uniapp.dcloud.io/api/ui/pulldown?id=onpulldownrefresh

/* 1.pages.json中为页面开启下拉刷新 */
{
    ...
    "pages": [
        {
            "path": "pages/index/index",
            "style": {
                "navigationBarTitleText": "导航栏",
                "enablePullDownRefresh": true 
            }
        }
    ],
    ...
}

/* 2.页面中监听下拉刷新事件 */
onPullDownRefresh() {
    // 刷新逻辑
    if(loadSuccess){
        // 结束刷新
        uni.stopPullDownRefresh();  => 对应的手动开始下拉刷新:uni.startPullDownRefresh({});
    }
}

APP端 可以动态控制页面是否支持下拉刷新:

// #ifdef APP-PLUS
const pages = getCurrentPages();  
const page = pages[pages.length - 1];  
const currentWebview = page.$getAppWebview();
currentWebview.setStyle({  
    pullToRefresh: {  
        support: !this.isSupport,   // 是否支持,这里用变量来控制
        style: plus.os.name === 'Android' ? 'circle' : 'default'  
    }  
});  
// 变量改变,控制页面是否支持下拉刷新
this.isSupport = !this.isSupport;
// #endif
2.1.2 上拉加载更多

需自己在列表底部添加上拉加载更多显示控件,通过变量状态控制控件的状态显示:loading前,loading中,没有更多数据:
上拉加载更多控件:https://ext.dcloud.net.cn/plugin?id=29

<uni-load-more v-if="compositionList.length > 0" :status="moreStatus"></uni-load-more>

// moreStatus 对应:more(loading前)、loading(loading中)、noMore(没有更多了)

监听页面滚动到底部事件:

onReachBottom() {
    this.moreStatus = "loading" // 改为加载中状态
    if(加载成功){
        this.moreStatus = "more"
        /* this.moreStatus = "noMore" */
    }
}
2.2 图片加载时&加载失败显示占位图片

使用image标签提供的两个方法:


截屏2021-01-28 下午1.56.46.png
// 使用
<view v-for="(item, index) in list" :key="index">
    <image v-show="item.imgLoaded" :src="item.logo" mode="aspectFit" @error="onErrorImg(item)" @load="onSuccessImg(item)"/>
    <image v-show="!item.imgLoaded" src="/static/images/login-grey.png" mode="aspectFit"/>
</view>

// js代码
onSuccessImg(item) {
    this.$set(item, 'imgLoaded', true)
},
onErrorImg(item) {
    this.$set(item, 'imgLoaded', false)
}
2.3 全局弹窗

例如升级弹窗,可覆盖任何页面,实现方式:跳转到一个透明背景的页面,并且修改页面展现动画。(仅支持APP)

/************* pages.json 中对页面的style做修改 *************/
{
    "path" : "pages/index/popup",
    "style" :                                                                                    
    {
        "navigationStyle":"custom",         // 隐藏导航栏
        "disableScroll":true,           // 禁止页面滑动
        "backgroundColor":"transparent",    // 背景透明
        "app-plus":{
            "animationType": "fade-in",     // 动画方式
            "background": "transparent", 
            "popGesture": "none"        // 禁用侧滑返回
        }
    }
}

/************* 页面样式 *************/

<style>
    
page{
    background: transparent;
}
    
/* 根view,给了一个黑色蒙版 */
.content{
    width: 100vw;
    height: 100vh;
    background-color: rgba(0, 0, 0, 0.4); /* 设置背景色,黑色蒙版 */
    display: flex;
    align-items: center;
    justify-content: center;
}

</style>

/************* 禁用安卓物理返回 *************/
onBackPress(options) {
    // 禁止安卓返回按钮 
    if(options.from == "backbutton"){
        return true;
    }
}

使用时,直接通过普通的uni.navigationTo()方法跳转即可,隐藏时调用uni.navigateBack({})。

2.4 开屏广告页/引导页

pages.json 中将广告页/引导页放在pages对应数组的首位,说明它是应用启动页:


"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
    // #ifdef APP-PLUS || H5   -> 这里也可以使用判断,只有在APP端和H5端,这个页面才会被编译
    {
        "path": "pages/lunchad/index",
            "style": {
                "navigationStyle": "custom",
                "disableScroll": true
            }
    }
    // #endif
    ...省略...
]

在广告页/引导页onLoad()方法中,判断是否需要展示,如果不需要则跳转到home页面,此时用uni.switchTab():

onLoad(){
    if(showAd){
        ...展示
    }else{
        // 跳转时使用switchTab方法
        uni.switchTab({
            url: '../tabbar/home/index'
        })
    }
}

3. 其它

3.1 for...in.. 问题

百度小程序不支持 v-for="(item,index) in 5",改为 v-for="(item,index) in [0,1,2,3,4]"

<view v-for="(item,index) in 5" :key="index">
    第{{index}}项
</view>
3.2 页面跳转时传多个参数
/* 页面跳转传参 */
let params = {
    "paramA":"A",
    "paramB":"B"            
}
let paramsStr = encodeURIComponent(JSON.stringify(params))
uni.navigateTo({
    url: './preview?params=' + paramsStr
})

/* 跳转后接收参数 */
onLoad(options) {
    if (options.params) {
        let params = JSON.parse(decodeURIComponent(options. params));
    }
}
上一篇 下一篇

猜你喜欢

热点阅读