在Nuxt 3中使用useWeb3ModalState追踪钱包连接状态遇阻
解决Web3Modal钱包连接状态追踪及页面刷新失效问题
问题背景
实现connectedButton.vue组件集成Web3Modal按钮,功能正常,但无法正确追踪钱包连接状态:
- 方案一:完全无法识别连接状态
- 方案二:临时识别有效,但页面刷新后状态丢失
方案一代码(无效)
<script setup> import { createWeb3Modal, defaultConfig, useWeb3ModalState } from "@web3modal/ethers5/vue"; import { computed } from 'vue'; import { ref, watch, onMounted } from 'vue'; const projectId = "737c1a9a3cd995ca3f5a235c87f78103"; const mainnet = { chainId: 80001, name: "Mumbai", currency: "MATIC", explorerUrl: "https://mumbai.polygonscan.com/", rpcUrl: "https://rpc-mumbai.maticvigil.com/", }; const metadata = { name: "My Website", description: "My Website description", url: "https://mywebsite.com", icons: ["https://avatars.mywebsite.com/"], }; createWeb3Modal({ ethersConfig: defaultConfig({ metadata }), chains: [mainnet], projectId, enableAnalytics: true, }); const { open, selectedNetworkId } = useWeb3ModalState(); const isConnected = computed(() => open.value && selectedNetworkId.value !== null); console.log(open.open) </script> <template> <div> <w3m-button /> <p v-if="isConnected">Wallet Connected (Chain ID: {{ selectedNetworkId }})</p> <p v-else>Wallet Not Connected</p> </div> </template>
方案二代码(刷新失效)
<script setup> import { createWeb3Modal, defaultConfig, useWeb3ModalState } from "@web3modal/ethers5/vue"; import { computed } from 'vue'; import { ref, watch, onMounted } from 'vue'; const projectId = "737c1a9a3cd995ca3f5a235c87f78103"; const mainnet = { chainId: 80001, name: "Mumbai", currency: "MATIC", explorerUrl: "https://mumbai.polygonscan.com/", rpcUrl: "https://rpc-mumbai.maticvigil.com/", }; const metadata = { name: "My Website", description: "My Website description", url: "https://mywebsite.com", icons: ["https://avatars.mywebsite.com/"], }; createWeb3Modal({ ethersConfig: defaultConfig({ metadata }), chains: [mainnet], projectId, enableAnalytics: true, }); const { selectedNetworkId } = useWeb3ModalState(); const isConnected = ref(false); watch(selectedNetworkId, (newValue) => { isConnected.value = newValue !== null; }, { immediate: true }); </script> <template> <div> <w3m-button /> <p v-if="isConnected">Wallet Connected (Chain ID: {{ selectedNetworkId }})</p> <p v-else>Wallet Not Connected</p> </div> </template>
问题分析
- 方案一错误点:用
open.value(模态框打开状态)判断钱包连接,逻辑完全错误,open与连接状态无关联。 - 方案二错误点:仅监听
selectedNetworkId,页面刷新时Web3Modal需要时间初始化并恢复会话,初始监听无法捕获异步完成后的连接状态,导致刷新后状态丢失。
正确解决方案
利用Web3Modal内置的isConnected状态,结合页面挂载后的主动检查,确保刷新后状态正常:
<script setup> import { createWeb3Modal, defaultConfig, useWeb3ModalState } from "@web3modal/ethers5/vue"; import { ref, watch, onMounted } from 'vue'; const projectId = "737c1a9a3cd995ca3f5a235c87f78103"; const mumbai = { chainId: 80001, name: "Mumbai", currency: "MATIC", explorerUrl: "https://mumbai.polygonscan.com/", rpcUrl: "https://rpc-mumbai.maticvigil.com/", }; const metadata = { name: "My Website", description: "My Website description", url: "https://mywebsite.com", icons: ["https://avatars.mywebsite.com/"], }; createWeb3Modal({ ethersConfig: defaultConfig({ metadata }), chains: [mumbai], projectId, enableAnalytics: true, }); const { isConnected, selectedNetworkId } = useWeb3ModalState(); const walletConnected = ref(isConnected.value); watch(isConnected, (newStatus) => { walletConnected.value = newStatus; }, { immediate: true }); onMounted(() => { setTimeout(() => { walletConnected.value = isConnected.value; }, 500); }); </script> <template> <div> <w3m-button /> <p v-if="walletConnected">钱包已连接(链ID: {{ selectedNetworkId }})</p> <p v-else>钱包未连接</p> </div> </template>
关键说明
- 使用内置状态:
useWeb3ModalState提供的isConnected是官方维护的连接状态标识,比自行判断更准确。 - 会话恢复处理:页面刷新时Web3Modal会自动恢复钱包连接会话,短延迟确保初始化完成后状态同步。
- 实时响应:通过
watch监听状态变化,保证UI实时更新。
内容的提问来源于stack exchange,提问作者Amr
相关产品推荐
相关产品推荐

