uniapp之实战技巧+踩坑求解

493 阅读1分钟

1. 修饰符.stop只对view标签有效

解决方法

<view class="history-icons" @click.stop>
    <uni-icons @click="handleClearHistory($event, index)" class="icon" type="close" color="#333" size="20"></uni-icons>
</view>

// 或
handleClearHistory(event, index) {
    event.stopPropagation();
    // 其他清除历史记录的逻辑
}

2. 使用css / scss变量时.不要使用驼峰命名

:style="{'--leftWidth':'20rpx}" // 变量会失效

:style="{'--width':'20rpx}" // 正常

3. 简单封装一个返回上一页并刷新页面的方法

// 使用场景: 从列表页进入详情页->在详情页修改完数据->点击保存后返回列表页->列表页中对应的那一项状态根据业务需求改变

当然还有其他解决方案,例如 uni.navigateToeventChannel

// 返回上一页并执行指定方法,tips:需要在上一页中暴露指定方法
// defineExpose({
//  methodName,
// })

export async function goBackAndRefresh(methodName: string, delay = 0) {
  const pages = getCurrentPages()
  const prePage = pages[pages.length - 2]
  if (prePage && prePage.$vm && typeof prePage.$vm[methodName] === 'function') {
    setTimeout(() => {
      uni.navigateBack({
        delta: 1,
        success: () => {
        // 返回到页面后再执行,也可以放到setTimeout外,提前执行,用户体验更好,根据业务需求使用
          prePage.$vm[methodName]()
        },
      })
    }, delay)
  } else {
    console.error(`Method '${methodName}' not found on the previous page`)
    setTimeout(() => {
      uni.navigateBack({ delta: 1 })
    }, delay)
  }
}

// 使用例子: 详情页处理完数据后

const handleSomething = async (item: any) => {
  uni.showModal({
    title: '提示',
    content: '是否修改当前数据?',
    success: async (res) => {
      if (res.confirm) {
        // 执行某些异步修改操作
        //  await updateSomeThing()
        uni.showToast({
          icon: 'success',
          title: '更新成功',
        })
     // 返回上一页并执行方法,可以是刷新页面等等
       goBackAndRefresh('methodName', 500)
      } else if (res.cancel) {
        // console.log('用户点击取消')
      }
    },
  })
}

4. 踩坑-触发加载更多的loading重置了页面列表的滚动

问题: 之前官方文档中有一个例子是下面这样的(现在不知道改了没)

<unicloud-db v-slot:default="{data, loading, error, options}" collection="user">
    <view v-if="error">{{error.message}}</view>
    <view v-else-if="loading">正在加载...</view>
    <view v-else>
        {{data}}
    </view>
</unicloud-db>

但是这样写的话滚动到底部,加载下一页时候页面闪一下后就会回到列表中的第一条。

onReachBottom() {
	//滚动到底翻页
	this.$refs.udb.loadMore();
},

解决方法

<unicloud-db v-slot:default="{data, loading, hasMore, error}" collection="paint" :where="'type==' + tempstr" ref='udb' :page-size='12' >    
  <view v-if="error">加载错误</view>    
  <!-- <view v-else-if="loading" class="loading"></view> --> 
     <view v-else>  
     <view v-if="loading" class="loading"></view>  
     <view class="imageLists">    
       <image :src="items.compress.url" mode="widthFix" v-for="(items,index) in data"  :key='index'>    
       </image>    
    </view>    
  </view>    
</unicloud-db> 

将加载中的代码去掉,因为上面代码每次触发加载时,都会只渲染加载,而数据页面都会重新销毁渲染。如果需要加载状态,将加载的代码结构跟数据页面放在一起,根据loading来显示加载状态。

当然,最好是结合 load-more 的组件使用

5. 隐藏滚动条

::-webkit-scrollbar {
	width: 0 !important;
	height: 0 !important;
    color: transparent;
    background: transparent;
	display: none;
}

6.使用flex布局让 scroll-view 在y轴方向滚动时自适应高度

<template>
  <view class="container">

    <view class="scroll-box">
      <scroll-view
        class="scroll-view"
        scroll-with-animation
        scroll-y
        refresher-enabled
        enable-back-to-top
        scroll-anchoring
        :refresher-triggered="freshing"
        @refresherrefresh="onRefresh"
        @scrolltolower="nextPage"
      >
        <view class="wrap-list">
 
        </view>
      </scroll-view>
    </view>

    <view class="footer"> </view>
  </view>
</template>

<style lang="scss" scoped>
.container {
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.scroll-box {
  width: 100%;
  flex: 1;
  overflow: hidden;
}
.scroll-view {
  width: 100%;
  height: 100%;
}

.footer {
  height:100px;
  flex-shrink: 0;
}
</style>

7.在 scroll-view 中使用 (sticky)吸顶组件时,如果没有吸顶效果,尝试多嵌套一层 view,并设置 position: relative;

      <scroll-view
        class="scroll-view"
        scroll-with-animation
        scroll-y
        refresher-enabled
        enable-back-to-top
        scroll-anchoring
        :refresher-triggered="freshing"
        @refresherrefresh="onRefresh"
        @scrolltolower="nextPage"
      >
        <view class='wrap'>
         <fui-sticky>
	        <view>滑动页面查看效果</view>
        </fui-sticky>
        </view>
      </scroll-view>
      
<style lang="scss" scoped>
  .wrap {
     position: relative;
  }   
</style>

最后. ios textarea 的@input有概率会触发页面中其他元素的事件,例如@change,@click等,官方问答社区页挺多类似的bug

蹲一个最佳解决方案