uni-app vivo品牌input的focus在进入页面时导致APP闪退
uni-app vivo品牌input的focus在进入页面时导致APP闪退
开发环境 | 版本号 | 项目创建方式 |
---|---|---|
Mac | 14.1.1 | HBuilderX |
示例代码:
<template>
<view>
<input focus>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>
操作步骤:
- 根据上面代码,直接进入页面
预期结果:
- 正常的input focus,比如有光标、弹出键盘,至少不闪退
实际结果:
- 光标先卡住,然后正常的闪烁几下,键盘没弹出来,然后APP闪退
bug描述:
反馈一个非常奇怪单严重的的bug:
在页面中,如果有<input>
(就是最常用的这个输入组件),如果input上写了 focus
。进入页后过几秒,整个APP就会闪退。删掉 focus
就正常了。
只要不是进入页面时出现一个有focus
的input就没事。
感觉出这个问题,是因为在进入页面时,focus
导致手机纠结要不要弹出软键盘导致的。
在 uni-app
开发中,如果在进入页面时自动触发 input
的 focus
事件,可能会导致某些设备(如 Vivo 手机)上的应用闪退。这通常是由于某些设备或系统版本对 input
的自动聚焦处理不当导致的。以下是一些可能的解决方案:
1. 延迟聚焦
在页面加载时,延迟一段时间再触发 input
的 focus
事件,以避免页面刚加载时立即聚焦导致的闪退问题。
onLoad() {
setTimeout(() => {
this.$refs.input.focus();
}, 500); // 延迟500毫秒
}
2. 使用 nextTick
使用 Vue
的 nextTick
方法,确保 DOM 更新完成后再触发 focus
事件。
onLoad() {
this.$nextTick(() => {
this.$refs.input.focus();
});
}
3. 手动触发聚焦
在页面加载完成后,通过用户交互(如点击按钮)来手动触发 input
的 focus
事件,而不是在页面加载时自动聚焦。
<template>
<view>
<input ref="input" />
<button @click="focusInput">点击聚焦</button>
</view>
</template>
<script>
export default {
methods: {
focusInput() {
this.$refs.input.focus();
}
}
}
</script>
4. 检查 input
的 focus
方法
确保 input
的 focus
方法在调用时,input
元素已经存在于 DOM 中。如果 input
元素尚未渲染完成,调用 focus
可能会导致异常。
5. 使用 uni-app
的 onReady
生命周期
在 uni-app
中,onReady
生命周期表示页面初次渲染完成,此时可以安全地操作 DOM。
onReady() {
this.$refs.input.focus();
}
6. 检查设备兼容性
如果问题仅在特定设备(如 Vivo 手机)上出现,可能是设备或系统版本的兼容性问题。可以尝试在更多设备上测试,或者联系设备厂商获取更多信息。
7. 更新 uni-app
版本
确保你使用的是最新版本的 uni-app
,因为新版本可能已经修复了类似的问题。
8. 使用 uni-app
的 focus
方法
uni-app
提供了 uni.createSelectorQuery()
方法,可以通过选择器获取元素并调用 focus
方法。
onReady() {
uni.createSelectorQuery().select('#input').node((res) => {
res.node.focus();
}).exec();
}
9. 避免在 onLoad
中直接调用 focus
onLoad
生命周期在页面加载时触发,此时 DOM 可能尚未完全渲染完成。尽量避免在 onLoad
中直接调用 focus
方法。
10. 使用 v-if
控制 input
的渲染
通过 v-if
控制 input
的渲染时机,确保 input
在页面加载完成后再渲染。
<template>
<view>
<input v-if="isInputReady" ref="input" />
</view>
</template>
<script>
export default {
data() {
return {
isInputReady: false
};
},
onReady() {
this.isInputReady = true;
this.$nextTick(() => {
this.$refs.input.focus();
});
}
}
</script>