Uniapp X 数据列表在web端显示正常,但是app端没有显示,或没有根据列表的数据条件变化
在 uni-app x 的 App 端(Android / iOS / 鸿蒙)里,页面是 uvue,运行时是原生渲染,H5 端仍然走了 Web 渲染,Vue 的响应式系统可以在模板渲染时再去执行。后手动算出的布尔值,也能避免函数在渲染时被提前执行。如果仍想保留“先渲染后拿数据”的写法,可以在拿到。,于是那几项就被直接移除,后面即使。再变成医院用户,也不会重新触发。,让它整行重新挂载,从而再次执行。
项目场景(错误示例):
<template>
...
<!-- 服务中心 -->
<view class="service-option">
<view class="title">
<view class="left">
<text class="tt">服务中心</text>
<image src="https://www.pengpaicoding.com.cn/static/app/home/title-star.png" class="w-[44rpx] h-[44rpx] tt-bg"></image>
</view>
</view>
<view class="mt-3">
<cl-row :gutter="12">
<template v-for="(e,ei) in services" :key="ei">
<cl-col :span="6" @click="handelServiceNav(e)">
<view class="flex justify-center items-center mb-2">
<cl-image :src="e.icon" width="72rpx" height="72rpx" />
<text class="text-[#666666] text-[28rpx] mt-1">{{e.label}}</text>
</view>
</cl-col>
</template>
</cl-row>
</view>
</view>
...
</template>
// js部分:
/* 服务中心 */
const servicesBase : ServiceItem[] = [
{
label: '用户协议',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/yhxy.png',
show: () => true,
logined: false,
to: '/pages/article/index',
params: { code: 'user' }
},
{
label: '隐私协议',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/ysxy.png',
show: () => true,
logined: false,
to: '/pages/article/index',
params: { code: 'secret' }
},
{
label: '收货地址',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/shdz.png',
show: () => true,
logined: true,
to: '/pages/user/address/index'
},
{
label: '联系客服',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/lxkf.png',
show: () => true,
logined: false,
to: '/pages/user/contact/index'
},
{
label: '医院入驻',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/yyrz.png',
show: () => userInfo.value?.userType != '02',
logined: true,
to: '/pages/hospital/apply'
},
{
label: '我的团队',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/wdtd.png',
show: () => userInfo.value?.userType == '02',
logined: true,
to: '/pages/hospital/teams'
},
{
label: '我的服务',
icon: 'https://www.pengpaicoding.com.cn/static/app/hospital/my-service.png',
show: () => userInfo.value?.userType == '02',
logined: true,
to: '/pages/hospital/service'
},
{
label: '认证详情',
icon: 'https://www.pengpaicoding.com.cn/static/app/user/rzxq.png',
show: () => userInfo.value?.userType == '02',
logined: true,
to: ''
}
];
原因分析:
在 uni-app x 的 App 端(Android / iOS / 鸿蒙)里,页面是 uvue,运行时是原生渲染,对响应式数据的“读取时机”与 H5 端不同。
H5 端仍然走了 Web 渲染,Vue 的响应式系统可以在模板渲染时再去执行 e.show(),此时 userInfo.value 已经拿到;而 App 端在渲染那一帧就把 e.show() 的结果“固化”了,如果当时 userInfo 还是 undefined,userInfo.value?.userType === '02' 就返回 false,于是那几项就被直接移除,后面即使 userInfo 再变成医院用户,也不会重新触发 v-if 的更新。
解决方案:
-
先把数据准备好再渲染列表
在拿到userInfo之后再给services赋值,或者用一个计算属性包裹services,确保userInfo已经就绪。// 伪代码 const services = computed<ServiceItem[]>(() => { if (!userInfo.value) return [] // 没拿到用户信息先不渲染 return [ ... // 这里放原来的数组 ] }) -
强制重新渲染
如果仍想保留“先渲染后拿数据”的写法,可以在拿到userInfo后给<cl-row>加一个v-if或:key,让它整行重新挂载,从而再次执行e.show()。<cl-row :gutter="12" v-if="userInfo"> ... </cl-row> -
把 show 改成普通布尔值
把show: () => userInfo.value?.userType === '02'改成在拿到userInfo后手动算出的布尔值,也能避免函数在渲染时被提前执行。const services = computed(() => { const isHospital = userInfo.value?.userType === '02' return [ { label: '我的团队', show: isHospital, ... }, ... ] })
更多推荐
所有评论(0)