Redmi Note5的MIUI浏览器10.9.8-g中Vite+Vue3页面空白无DOM问题求助
问题:Redmi Note5的MIUI浏览器10.9.8-g中Vite+Vue3页面空白无DOM元素
在Redmi Note5真机的MIUI浏览器10.9.8-g版本中,使用Vite和Vue3开发的页面打开后完全空白,无DOM元素渲染,同时存在窗口打开相关Bug,相关截图如下:

以下是组件代码、Vite配置及路由配置:
组件代码
<script setup> import RechargePhoneItem from '@/components/RechargePhoneItem.vue' import { useGlobalStore } from '@/stores/global.js' import { useOrderStore } from '@/stores/order.js' import { isEmpty } from '@/lib/common.js' import { checkCustomerV2 } from '@/api' import { onMounted, ref, watch } from 'vue' import router from '@/router' const global = useGlobalStore() const order = useOrderStore() const dataUser = ref(null) async function getUserInformation() { try { if (import.meta.env.MODE !== 'development') { global.showLoading() const data = await window.sdk.getUserInfo() const { id, phone } = data const {statusCode, data: dataRes} = await checkCustomerV2({ phoneNumber: phone, fptplayId: id, customer_name: "", token: "" }) if(statusCode === 200) { global.setUserInfo({ ...data, phone: dataRes?.phone_number.trim(), id: dataRes?.uid }) dataUser.value = { ...data, phone: dataRes?.phone_number.trim(), id: dataRes?.uid, } global.hideLoading() } } else { dataUser.value = { phone: '0968790025', id: '343' } global.setUserInfo(dataUser.value) } } catch (error) { global.hideLoading() if(error.code === 100) return order.setDataTransaction({message: error.message}) router.push('/card/error-order') console.log(error); } } function handleEventKey(e) { if (import.meta.env.MODE !== 'development' && e.keyCode === window.sdk.keys.backspace && router?.currentRoute?.value?.name === 'RechargePhone' && !global.isModal) { window.sdk.destroy() return } else { global.showModal(false) return } } watch( () => global.userInfo, (val, oldVal) => { dataUser.value = val global.setUserInfo(val) }, { deep: true } ) onMounted(() => { if (!window.sdk) alert('close') if (!dataUser.value || isEmpty(dataUser.value)) getUserInformation() global.setService('Nạp tiền điện thoại') document.addEventListener("keydown", handleEventKey) }) </script> <template> <RechargePhoneItem v-if="dataUser" :dataUser="dataUser" /> </template> <style lang="scss"></style>
Vite配置
import { fileURLToPath, URL } from 'node:url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import vueJsx from '@vitejs/plugin-vue-jsx' // https://vitejs.dev/config/ process.env.BROWSER = "chrome" export default defineConfig({ plugins: [ vue(), vueJsx(), ], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } } })
路由配置
import { createRouter, createWebHistory } from 'vue-router' import HomeView from '../views/HomeView.vue' const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', name: 'home', component: HomeView }, { path: '/card/nap-tien-dien-thoai', name: 'RechargePhone', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/RechargePhone.vue') }, { path: '/card/history-transaction', name: 'HistoryTransaction', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/HistoryTransaction.vue') }, { path: '/card/order-confirm', name: 'DetailTransaction', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/DetailTransaction.vue') }, { path: '/card/payment-methods', name: 'PaymentMethods', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/PaymentMethods.vue') }, { path: '/card/payment-manages', name: 'PaymentManages', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/PaymentManages.vue') }, { path: '/card/success', name: 'SuccessOrder', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/SuccessOrder.vue') }, { path: '/card/error-order', name: 'ErrorOrder', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/ErrorOrder.vue') }, { path: '/card/pending-order', name: 'PendingOrder', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/PendingOrder.vue') }, { path: '/card/error-network', name: 'ErrorPage', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/ErrorPage.vue') }, { path: '/card/support', name: 'Support', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/Support.vue') }, { path: '/card/credit-card', name: 'CreditCard', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/CreditCard.vue') }, { path: '/card/receiver', name: 'ReceiverCard', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/ReceiverCard.vue') }, { path: '/card/check-transaction', name: 'CheckTransaction', // route level code-splitting // this generates a separate chunk (About.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import('@/views/CheckTransaction.vue') } ] }) export default router
期望:页面能正常渲染DOM元素,恢复正常显示。
解决建议
1. 适配旧浏览器内核
MIUI浏览器10.9.8-g基于老旧Chromium内核,对ES6+语法支持有限,修改Vite配置降低构建目标:
export default defineConfig({ // ...原有配置 build: { target: ['es2015', 'chrome60', 'android6'] // 适配旧安卓浏览器 }, optimizeDeps: { esbuildOptions: { target: 'es2015' } } })
2. 更换路由模式
createWebHistory依赖HTML5 History API,旧浏览器可能不兼容,换成哈希模式:
import { createRouter, createHashHistory } from 'vue-router' const router = createRouter({ history: createHashHistory(import.meta.env.BASE_URL), // ...路由配置 })
3. 修复组件潜在问题
- 模板添加兜底内容,避免
dataUser为空时完全空白:
<template> <RechargePhoneItem v-if="dataUser" :dataUser="dataUser" /> <div v-else>加载中...</div> </template>
- 移除
watch中的循环更新逻辑,避免无限触发状态更新:
watch( () => global.userInfo, (val) => { dataUser.value = val // 移除 global.setUserInfo(val) 这行代码 }, { deep: true } )
4. 调试错误根源
在关键位置添加日志,确认代码执行状态:
- 在
onMounted开头添加console.log('组件已挂载'),检查组件是否正常初始化 - 扩展
getUserInformation的catch逻辑,打印完整错误信息,确认是否是SDK或接口请求失败导致dataUser未赋值
5. 确保SDK提前加载
在入口文件(如main.js)中等待SDK加载完成后再初始化Vue:
// main.js function initApp() { createApp(App) .use(router) .use(pinia) // 若使用Pinia状态管理 .mount('#app') } if (window.sdk) { initApp() } else { // 监听SDK加载完成事件(需根据SDK文档调整) window.addEventListener('sdkReady', initApp) }
内容的提问来源于stack exchange,提问作者Sang Phan
相关产品推荐
相关产品推荐

