uni-app uni-transition的show参数在H5环境下控制显示异常

发布于 1周前 作者 yibo5220 来自 Uni-App

uni-app uni-transition的show参数在H5环境下控制显示异常

示例代码:

<template>  
    <!-- 列表1 -->  
    <view class="list">  
        <view class="item" v-for="(item, index) in containerShow" @click="touch(item)">  
            显-{{ item.id }}  
        </view>  
    </view>  

    <!-- 列表2 -->  
    <view class="list">  
        <view class="item" v-for="(item, index) in containerHide" @click="touch(item)">  
            隐-{{ item.id }}  
        </view>  
    </view>  

    <!-- 底部控制器 -->  
    <view class="content">  
        <button @click="reSet" v-show="isShow">还原(正常的)</button>  

        <!-- 依赖 computed 计算状态-->  
        <uni-transition mode-class="fade" :show="isShow">  
            <view class="btn-container">  
                <view class="btn-item">  
                    <button @click="reSet">还原(transition 异常computed)</button>  
                </view>  
            </view>  
        </uni-transition>  
        <!-- 依赖 ref 控制状态-->  
        <uni-transition mode-class="slide-bottom" :show="showRef">  
            <view class="btn-container">  
                <view class="btn-item">  
                    <button @click="reSet">还原(transition 异常showRef)</button>  
                </view>  
            </view>  
        </uni-transition>  
    </view>  
</template>  

<script setup>  
import { ref, reactive, computed, watch, toRaw } from "vue";  

/** 原始数据列 */  
const list = reactive(  
    Array(5)  
        .fill({})  
        .map((item, index) => ({  
            id: index * 2,  
            flage: true  
        }))  
);  

/** 操作记录栈 */  
const stack = reactive([]);  

/** 状态标记:当操作记录栈不为空时true */  
const isShow = computed(() => {  
    let state = stack.length > 0;  
    console.log("计算状态", state);  
    return state;  
});  

/** 点击切换状态  并存入记录 */  
const touch = ({ id }) => {  
    let index = list.findIndex((v) => v.id == id);  

    // 获取源数据 存入记录栈  
    let history = JSON.parse(JSON.stringify(toRaw(list[index])));  
    stack.push(history);  

    // 切换状态  
    list[index].flage = !list[index].flage;  
};  

/** 计算显示的列表 */  
const containerShow = computed(() => {  
    return list.filter((v) => v.flage);  
});  
/** 计算隐藏的列表 */  
const containerHide = computed(() => {  
    return list.filter((v) => !v.flage);  
});  

/** 还原初始状态 */  
const reSet = () => {  
    list.forEach((v) => {  
        v.flage = true;  
    });  
    stack.splice(0, stack.length);  
};  

const showRef = ref(false);  
/** 监控操作栈 */  
watch(stack, (newVal) => {  
    let state = newVal.length > 0;  
    console.log("当前操作记录栈", toRaw(newVal), `长度是否>0:${state}`);  
    showRef.value = state;  
});  
</script>  

<style lang="scss" scoped>  
.list {  
    width: 80%;  
    margin: 30rpx auto;  
    padding: 20rpx;  
    border: 2rpx solid #dadada;  
    border-radius: 20rpx;  
    background-color: #efefef;  
    display: flex;  
    justify-content: space-around;  
    .item {  
        padding: 30rpx;  
        background: #fff;  
    }  
}  
.content {  
    position: fixed;  
    bottom: 0;  
    width: 100vw;  
    z-index: 10;  
    .btn-container {  
        width: 100%;  
        padding-top: 10px;  
        padding-bottom: 10px;  
        background-color: #d6d6d6b0;  
        display: flex;  
        align-self: center;  
        justify-content: space-around;  
    }  
}  
</style>

操作步骤:

  • 正常在H5浏览器运行(Edge、Chrome均可),点击上方容器按钮

预期结果:

  • show传参正确控制底部uni-transition显示、隐藏

实际结果:

  • H5中 show=true时 uni-transition 仅显示一次 后续show为true时则关闭,微信小程序中正常

bug描述:

  • H5环境下 uni-transition 的show参数控制显示异常,微信小程序端正常 控制显示/隐藏,下方gif对照

uni-ui-测试工程.rar


4 回复

看了下组件源码 按照官方的书写逻辑 其实H5是正常的 组件的opacity属性在初始化后就固定修改为了0 所以H5端组件show属性发生改变后 组件样式中的opacity就生效为0 然后消失的 小程序没有消失时因为uni-transition组件样式中有个默认的opacity: 1;(在调试器中可以看到) 所以才没有消失 // uni-transition源码
// 传false 时 opacity 为 0
let { opacity, transform } = this.styleInit(false) 如果你想实现图中小程序的效果 不要使用计算属性修改组件show属性的值 可以在show发生改变时在修改他的值 你可以试试下面的代码 <template>

<view class="list">
<view class=“item” v-for="(item, index) in containerShow" @click=“touch(item)”>
显-{{ item.id }}
</view>
</view>

<!-- 列表2 -->  
<view class="list">  
    <view class="item" v-for="(item, index) in containerHide" @click="touch(item)">  
        隐-{{ item.id }}  
    </view>  
</view>  
<!-- 底部控制器 -->  
<view class="content">  
    <button @click="reSet" v-show="isShow">还原(正常的)</button>  
    <!-- 依赖 computed 计算状态-->  
    <uni-transition mode-class="fade" :show="isShow">  
        <view class="btn-container">  
            <view class="btn-item">  
                <button @click="reSet">还原(transition 异常computed)</button>  
            </view>  
        </view>  
    </uni-transition>  
    <!-- 依赖 ref 控制状态-->  
    <uni-transition mode-class="fade" :show="showRef">  
        <view class="btn-container">  
            <view class="btn-item">  
                <button @click="reSet">还原(transition 异常showRef)</button>  
            </view>  
        </view>  
    </uni-transition>  
</view>  
</template> <script setup> import { ref, reactive, computed, watch, toRaw } from "vue"; /** 原始数据列 */ const list = reactive( Array(5) .fill({}) .map((item, index) => ({ id: index * 2, flage: true })) ); /** 操作记录栈 */ const stack = reactive([]); const isShow = ref(false) // 检测显示状态 const isComputed = () => { let state = stack.length >=1; if(isShow.value !== state) { isShow.value = state; showRef.value = state; } } /** 点击切换状态 并存入记录 */ const touch = ({ id }) => { let index = list.findIndex((v) => v.id == id); // 获取源数据 存入记录栈 let history = JSON.parse(JSON.stringify(toRaw(list[index]))); stack.push(history); // 切换状态 list[index].flage = !list[index].flage; // 检测显示状态 isComputed() }; /** 计算显示的列表 */ const containerShow = computed(() => { return list.filter((v) => v.flage); }); /** 计算隐藏的列表 */ const containerHide = computed(() => { return list.filter((v) => !v.flage); }); /** 还原初始状态 */ const reSet = () => { list.forEach((v) => { v.flage = true; }); stack.splice(0, stack.length); // 检测显示状态 isComputed() }; const showRef = ref(false); </script> <style lang="scss" scoped> .list { width: 80%; margin: 30rpx auto; padding: 20rpx; border: 2rpx solid #dadada; border-radius: 20rpx; background-color: #efefef; display: flex; justify-content: space-around; .item { padding: 30rpx; background: #fff; } } .content { position: fixed; bottom: 0; width: 100vw; z-index: 10; .btn-container { width: 100%; padding-top: 10px; padding-bottom: 10px; background-color: #d6d6d6b0; display: flex; align-self: center; justify-content: space-around; } } </style>

哦 原来还可以这样

感谢反馈,我来跟进下这个问题

uni-app 中,uni-transition 组件用于实现过渡动画。show 参数用于控制组件的显示与隐藏。如果你在 H5 环境下遇到 show 参数控制显示异常的问题,可能是由于以下原因导致的:

1. CSS 样式冲突

  • H5 环境下,样式可能与全局或其他组件的样式发生冲突,导致 uni-transition 的显示异常。
  • 解决方法:检查并确保 uni-transition 组件的样式没有被其他样式覆盖,必要时可以使用 scoped 样式或在组件中添加自定义类名。

2. 动画未正确触发

  • uni-transition 的动画依赖于 show 参数的变化,如果 show 参数没有正确触发,可能会导致显示异常。
  • 解决方法:确保 show 参数的值在组件的生命周期中正确变化,并且 uni-transition 组件的 animation 属性配置正确。

3. DOM 渲染延迟

  • H5 环境下,DOM 渲染可能会有延迟,导致 show 参数的控制未能及时生效。
  • 解决方法:可以尝试在 show 参数变化后,使用 setTimeout 延迟执行一些操作,确保 DOM 已经更新。

4. 组件版本问题

  • 如果你使用的 uni-app 版本较旧,可能存在一些已知的 bug 或兼容性问题。
  • 解决方法:尝试更新 uni-app 到最新版本,或者查看官方文档和社区是否有相关的修复方案。

5. 事件绑定问题

  • 如果 show 参数的变化与事件绑定有关,可能会因为事件触发顺序或异步操作导致显示异常。
  • 解决方法:检查事件绑定逻辑,确保 show 参数的变化是在正确的事件回调中触发的。

6. 自定义动画配置

  • 如果你使用了自定义的动画配置,可能会导致 H5 环境下的显示异常。
  • 解决方法:检查 uni-transitionanimation 配置,确保它与 H5 环境兼容。

示例代码

以下是一个简单的 uni-transition 使用示例,确保 show 参数在 H5 环境下正常工作:

<template>
  <view>
    <button @click="toggleShow">Toggle Show</button>
    <uni-transition :show="show" mode="fade">
      <view class="content">This is a transition content</view>
    </uni-transition>
  </view>
</template>

<script>
export default {
  data() {
    return {
      show: false
    };
  },
  methods: {
    toggleShow() {
      this.show = !this.show;
    }
  }
};
</script>

<style scoped>
.content {
  width: 100%;
  height: 200px;
  background-color: #f0f0f0;
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!