Taro踩坑经验总结,持续更新...

1,637 阅读4分钟

Taro版本:"@tarojs/taro": "3.5.4"

1. IphoneX底部安全区域小黑条适配问题

在苹果 iPhoneX 、iPhone XR等机型上,物理Home键被取消,改为底部小黑条替代home键功能,从而导致吸底元素会被小黑条遮挡覆盖的问题。

解决方案推荐(使用苹果官方推出的css函数env()、constant()来适配)

.detailBotoom{
    position: fixed;
    bottom: 0;
    width: 100%;
    height: calc(96rpx+ constant(safe-area-inset-bottom));///*兼容 IOS<11.2*/
    height: calc(96rpx + env(safe-area-inset-bottom));///*兼容 IOS>11.2*/
    display: flex;
    background: #fff;
    border-top: 1rpx solid #eaeef1;
    z-index: 99;
    padding-bottom: constant(safe-area-inset-bottom);///*兼容 IOS<11.2*/
    padding-bottom: env(safe-area-inset-bottom);///*兼容 IOS>11.2*/
}

注意 constant与env顺序不能改变,先constant再env

2. ScrollView设置scrollTop失效问题

设置 scrollTop=0 并不能实现置顶,最后使用随机数解决的。

const [scrollTop, setScrollTop] = useState<number>(0);
setScrollTop(Math.random());

3. 输入光标抖动问题

const [searchText, setSearchText] = useState<{ val: string }>({ val: '' });

const handleChange = useCallback(_.debounce((value: string, key: string) => {
    const inputValueArr = { ...searchText };
    inputValueArr[key] = value;
    setSearchText(inputValueArr);
}, 300), []);

return (
    <Input onChange={value => handleChange(value as string, 'val')} />
)

4. ScrollView高度动态计算

const computedScrollViewHeight = async () => {
    const systemInfo = wx.getSystemInfoSync();
    // 获取可使用窗口宽度
    const windowWidth = systemInfo.windowWidth;
    // 获取可使用窗口高度
    const windowHeight = systemInfo.windowHeight;
    // 算出比例
    const ratio = 750 / windowWidth;
    // 状态栏高度
    const statusBarHeight = Number(Taro.getStorageSync('statusBarHeight'));
    // 导航栏高度
    const navigationBarHeight = Number(Taro.getStorageSync('navigationBarHeight'));
    // Tab高度
    const tab = await hTaro.delayQuerySelector('.at-tabs__item');
    // 搜索+标签高度
    const filterWrap = await hTaro.delayQuerySelector('.filter-wrap');
    // 底部固定按钮高度
    const footerFixed = await hTaro.delayQuerySelector('.footer-fixed');
    // 设置scrollView高度
    setScrollViewHeight(windowHeight - (statusBarHeight + navigationBarHeight + filterWrap.height + tab.height + footerFixed.height + (24 / ratio)));
};

useEffect(() => {
    computedScrollViewHeight();
}, []);

5. Textarea文字穿透问题

当页面上用到Textarea组件的时候,弹框或底部固定按钮都会出现placeholder文字或者输入的文字内容,穿透遮罩层和浮动弹框,显示在最上面。修改z-index是没有效果的。针对两种不同情况不同的解决方案。

弹框

解决方案:当弹框显示的时候,显示Textarea标签的替代元素(这里用的是RichText),当隐藏弹框的时候,显示Textarea元素。

const flag = modalVisible || hasMask || comfirmModal.visible;

<View>
    <RichText
       className={`textarea ${flag ? 'show' : 'hide'}`}
    />
    <Textarea
        className={`textarea ${flag ? 'hide' : 'show'}`}
    />
</View>

底部固定按钮

解决方案:当弹框显示的时候,显示View标签的替代元素(CoverView),当隐藏弹框的时候,显示View元素。

{
    !isModalShow ? (
        <CoverView className='footer-fixed'>
            <CoverView className='btns'>
                <CoverView className='btn left' onClick={() => handleClick('save')}>保存</CoverView>
                <CoverView className='btn right' onClick={() => handleClick('launch')}>发起</CoverView>
            </CoverView>
        </CoverView>
    ) : (
        <View className='footer-fixed'>
            <View className='btns'>
                <View className='btn left' onClick={() => handleClick('save')}>保存</View>
                <View className='btn right' onClick={() => handleClick('launch')}>发起</View>
            </View>
        </View>
    )
}
.footer-fixed {
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100vw;
    height: 110rpx;
    background: #fff;
    z-index: 2;
    padding-bottom: constant(safe-area-inset-bottom);
    padding-bottom: env(safe-area-inset-bottom);

    .btns {
        box-sizing: border-box;
        display: flex;
        justify-items: center;
        justify-content: space-between;
        width: 100%;
        height: 110rpx;
        padding: 15rpx 24rpx;

        .btn {
            width: 335rpx;
            height: 80rpx;
            line-height: 80rpx;
            text-align: center;
            border-radius: 90rpx;
            font-size: 32px;

            &.left {
                background: #fff;
                color: #0EC17C;
                border: 1px solid #0EC17C;
            }

            &.right {
                color: #fff;
                background: #13D188;
            }
        }
    }
}

注意:footer-fixed这个类一定要加z-index,否则无效。

6. 1rpx border导致文字缩放问题

解决方案:

@mixin border-common {
    position: relative;

    &::after {
        position: absolute;
        content: '';
        top: 0;
        left: 0;
        box-sizing: border-box;
        width: 200%;
        height: 200%;
        transform: scale(0.5);
        transform-origin: left top;
        pointer-events: none;
    }
}

/**
* 移动端1px边框
* @param $radiusValue 圆角度 设置值需要*2
* @param $borderColor 边框颜色
*/

@mixin border-one-px ($radiusValue, $borderColor, $type:solid, $borderValue:1PX) {
    @include border-common;

    &::after {
        border: $borderValue $type $borderColor;
        border-radius: $radiusValue;
    }
}

7. 1rpx border ios真机显示不全问题

原因:经网上查资料,结论是当标签的父容器宽度(单位rpx)÷2的值为偶数或偶数.5的时候会出现该bug

解决方案1:设置标签父容器的宽度到无bug值,即(奇数或奇数.5)*2,例如281 * 2rpx, 281.5 * 2rpx可以解决;

解决方案2: 补充像素单位,加一个1rpx的标签,比如

.space {
    width1rpx;
    height100%;
    float: left;
}

8. ScrollView 滚动到底部或者顶部,再次设置 scrollIntoView 无效

产生bug原因: 当我们第一次滑倒底部点击A回到顶部成功,再次滑倒底部,再次点击A无法回到顶部,因为此时的scrollIntoView 对应的值还是A,需要将scrollIntoView对应的值清空,然后重新赋值A,即可解决

解决方案:滑动到顶部或者底部时,清空之前设置的scrollIntoId即可

const [toView, setToView] = useState<string>('');
 
// 清除scrollIntoId
const cleanScrollIntoId = () => {
    setToView('');
};

<ScrollView
    scrollIntoView={toView}
    onScrollToUpper={cleanScrollIntoId}
    onScrollToLower={cleanScrollIntoId}
></ScrollView>

9. 字符串图标截取

如下图展示,如果用字符串的方法去截取图标会乱码,原因应该是字符串的所有属性和方法都是基于 16 位的码元,但是后来生僻字越来越多,16位的空间不够用了,就把编码方式换成了utf-16,utf-16允许一个文字占用16位的空间也就是一个码元或者32位的空间就是两个码元 ,一些特殊的文字就占用了两个码元。

解决方案:可以转成数组,然后通过数组下标去获取

const arr = v.username && [...v.username];

<Text className='name'>
    <Text>{arr && arr[0]}</Text>**<Text>{arr && arr[arr.length - 1]}</Text>
</Text>

image.png

文章会持续更新,欢迎大家关注,如果有问题或者有更好的解决方案,也欢迎大家指正和告知。