DefterYu
DefterYu
  • 发布:2023-12-04 19:22
  • 更新:2023-12-05 11:16
  • 阅读:198

【报Bug】uni-transition 的show参数控制显示异常(H5环境)

分类:uni-app

产品分类: uniapp/H5

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: win10

HBuilderX类型: 正式

HBuilderX版本号: 3.98

浏览器平台: Chrome

浏览器版本: 119.0.6045.200

项目创建方式: HBuilderX

示例代码:
<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对照

2023-12-04 19:22 负责人:无 分享
已邀请:
爱豆豆

爱豆豆 - 办法总比困难多

看了下组件源码 按照官方的书写逻辑 其实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>  
    <!-- 列表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="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>  
  • DefterYu (作者)

    哦 原来还可以这样

    2023-12-05 18:46

DCloud_UNI_OttoJi

DCloud_UNI_OttoJi - 日常回复 uni-app/x 问题,如果艾特我没看到,请主动私信

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

要回复问题请先登录注册