使用 Wagmi Vue 发送交易:useSendTransaction 与 useWaitForTransactionReceipt 实战指南 📅 发布时间:2026/9/18 3:22:27 👁 浏览次数: 使用 Wagmi Vue 发送交易useSendTransaction 与 useWaitForTransactionReceipt 实战指南【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi本文基于 Wagmi 仓库中 Vue 发送交易指南 展开面向使用 Vue 3 wagmi/vue构建 DApp 的开发者。你将学会如何从零搭建一个「转账」表单接入useSendTransaction发起交易、用useWaitForTransactionReceipt监听上链确认、处理加载状态与用户拒绝/余额不足等错误并在文章末尾看到源码级的底层调用链解析。读完即可在真实项目中落地一个完整、健壮的 Send Transaction 模块。前置准备先让钱包连接起来发送交易的前提是用户已经通过钱包连接。本指南直接建立在 Connect Wallet 指南 之上你需要先完成以下三件事创建 Wagmi 配置通过createConfig配置链、连接器connector与传输层例如injected、metaMask、safe、walletConnect注入插件在应用入口同时注入WagmiPlugin提供 Wagmi 响应式状态与VueQueryPlugin提供 TanStack Vue Query 的内存缓存与查询状态管理实现连接 UI使用useConnect、useConnectors、useConnection等组合式函数让用户选择并连接钱包。import { VueQueryPlugin } from tanstack/vue-query import { WagmiPlugin } from wagmi/vue import { createApp } from vue import App from ./App.vue import { config } from ./wagmi createApp(App) .use(WagmiPlugin, { config }) .use(VueQueryPlugin, {}) .mount(#app)注意如果使用 WalletConnect请务必把config.ts中的WALLETCONNECT_PROJECT_ID替换为你自己的 Project ID。连接完成、useConnection().isConnected变为true之后再渲染发送交易组件。第 1 步创建 SendTransaction 组件骨架先创建一个SendTransaction.vue包含一个最简单的转账表单一个收款地址输入框、一个转账金额输入框和一个提交按钮。script setup langts /script template form input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button typesubmitSend/button /form /template两个输入框都带有name属性address与value这是下一步通过FormData读取表单数据的关键。required保证用户在提交前必须填写完整。第 2 步添加表单处理器接下来为表单添加提交事件处理器。当用户点击 Send 时从表单中提取地址与金额并调用sendTransactionscript setup langts function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button typesubmitSend/button /form /template这里有两个关键细节submit.prevent阻止表单默认的整页刷新行为parseEther(value)来自viem的单位换算工具。用户在输入框中填写的是人类可读的0.05ETH而链上交易要求以wei为单位的bigint。parseEther(0.05)会返回50000000000000000n。第 3 步接入 useSendTransaction 组合式函数现在把useSendTransaction接入进来它是整个发送交易流程的核心。从wagmi/vue导入组合式函数从viem导入parseEtherscript setup langts import { useSendTransaction } from wagmi/vue import { parseEther } from viem const { data: hash, sendTransaction } useSendTransaction() function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button typesubmitSend/button div v-ifhashTransaction Hash: {{ hash }}/div /form /templateuseSendTransaction返回的data解构为hash就是交易哈希0x${string}。一旦钱包签名并广播交易成功hash就会填充我们可以立即把它渲染在页面上供用户在区块浏览器中查询。useSendTransaction 的入参与返回值从 useSendTransaction API 文档 与仓库源码可以看到它的完整形态。其类型定义位于 packages/vue/src/composables/useSendTransaction.ts本质上是对 TanStack Vue QueryuseMutation的封装export function useSendTransaction(parameters {}) { const config useConfig(parameters) const options sendTransactionMutationOptions(config, parameters) const mutation useMutation(options) return { ...mutation, sendTransaction: mutation.mutate, sendTransactionAsync: mutation.mutateAsync, } }参数Parameters参数类型说明configConfig \| undefined显式指定要使用的 Config默认从WagmiPlugin注入的配置中获取mutationMutationParametersTanStack Query 的 mutation 级选项如onSuccess、onError、onSettled、retry等提交变量VariablessendTransaction({ to, value })接收的是核心 action sendTransaction 的参数常见字段包括to必填0x${string}收款地址valuebigint转账金额注意必须用parseEther等工具转成 weigas/gasPrice/maxFeePerGas/maxPriorityFeePerGasGas 相关覆盖项不传则自动估算chainIdconfig[chains][number][id]目标链 ID不传则使用当前链connector指定使用某个连接器签名不传则使用当前已连接的钱包data合约调用的 calldata本示例为普通转账无需填写若调用合约可配合 ABI 编码使用。返回值Return Type返回值类型说明sendTransaction(variables, options?) void触发交易的函数即mutate的别名在源码中标注为 deprecated推荐直接使用mutatesendTransactionAsync(variables, options?) PromiseSendTransactionData异步版本mutateAsync的别名同样 deprecated返回可 await 的 PromisedataSendTransactionData \| undefined最近一次成功解析的数据即交易哈希默认undefinederrorSendTransactionErrorType \| null最近一次 mutation 的错误对象isPendingbooleanmutation 是否正在执行status pendingisError/isSuccess/isIdleboolean由status派生的状态布尔值statusidle \| pending \| error \| successmutation 的完整状态机reset() void将 mutation 内部状态重置为初始状态variablesVariables \| undefined最近一次传给mutate的变量对象完整的返回值清单可参考仓库中 mutation-result 共享文档其字段语义与 TanStack Query v5 的useMutation保持一致。第 4 步添加加载状态可选用户点击 Send 后钱包会弹出签名确认窗口这段时间内应禁用按钮并给出反馈防止重复提交script setup langts import { useSendTransaction } from wagmi/vue import { parseEther } from viem const { data: hash, isPending, sendTransaction } useSendTransaction() function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button :disabledisPending typesubmit span v-ifisPendingSending.../span span v-elseSend/span /button div v-ifhashTransaction Hash: {{ hash }}/div /form /templateisPending在钱包签名、交易广播期间为true此时按钮禁用并显示 Sending...hash一旦产生则切回 Send。第 5 步等待交易确认可选hash产生只代表交易已被广播并不代表交易已上链。要拿到确切的交易回执receipt需要使用 useWaitForTransactionReceiptscript setup langts import { useSendTransaction, useWaitForTransactionReceipt, } from wagmi/vue import { parseEther } from viem const { data: hash, isPending, sendTransaction } useSendTransaction() function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } const { isLoading: isConfirming, isSuccess: isConfirmed } useWaitForTransactionReceipt({ hash, }) /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button :disabledisPending typesubmit span v-ifisPendingSending.../span span v-elseSend/span /button div v-ifhashTransaction Hash: {{ hash }}/div div v-ifisConfirmingWaiting for confirmation.../div div v-ifisConfirmedTransaction Confirmed!/div /form /template把上一步拿到的hash直接传入useWaitForTransactionReceipt组合式函数会持续轮询直到交易被打包进区块并返回回执isLoading解构为isConfirming正在等待交易上链isSuccess解构为isConfirmed交易已确认。useWaitForTransactionReceipt 的常用参数参考 useWaitForTransactionReceipt API 文档该组合式函数的关键参数如下参数类型说明hash0x${string} \| undefined要等待的交易哈希。当hash为undefined时查询的enabled自动为false不会发起轮询——这正是本示例中hash未产生时组件不会空转的原因chainIdconfig[chains][number][id] \| undefined查询目标链 ID默认取当前链confirmationsnumber \| undefined等待的确认区块数默认 1传2即等两个区块后再 resolvepollingIntervalnumber \| undefined轮询频率毫秒默认取 createConfig 的pollingInterval配置onReplaced((replacement) void) \| undefined交易被替换replaced/repriced/cancelled例如用户加速或取消交易时的回调configConfig \| undefined显式指定 Config从源码 packages/vue/src/composables/useWaitForTransactionReceipt.ts 可以看到它是一个基于 TanStack Vue QueryuseQuery的封装参数类型为DeepMaybeRef内部通过deepUnref把响应式参数解包成普通对象再交给waitForTransactionReceiptQueryOptions生成查询选项chainId默认来自useChainId且支持参数级覆盖。这也意味着它天然支持响应式——把hash这个ref传进去hash一旦变化查询会自动重新触发。第 6 步处理错误可选如果用户在钱包中拒绝了交易或者账户余额不足以覆盖「转账金额 Gas 费」mutation 会进入错误状态。此时应该把错误信息展示给用户script setup langts import { useSendTransaction, useWaitForTransactionReceipt, } from wagmi/vue import { parseEther } from viem const { data: hash, error, isPending, sendTransaction } useSendTransaction() function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } const { isLoading: isConfirming, isSuccess: isConfirmed } useWaitForTransactionReceipt({ hash, }) /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button :disabledisPending typesubmit span v-ifisPendingSending.../span span v-elseSend/span /button div v-ifhashTransaction Hash: {{ hash }}/div div v-ifisConfirmingWaiting for confirmation.../div div v-ifisConfirmedTransaction Confirmed!/div div v-iferror Error: {{ (error as BaseError).shortMessage || error.message }} /div /form /template展示错误时优先取(error as BaseError).shortMessage——BaseError是viem提供的错误基类从viem导入类型即可shortMessage是提炼过的简短可读信息比冗长的原始error.message更适合直接面向用户。第 7 步组装到应用入口最后把SendTransaction组件挂到应用入口。沿用 Connect Wallet 指南的模式未连接时显示Connect已连接时显示Connection与SendTransactionscript setup langts import { useConnection } from wagmi/vue import Connection from ./Connection.vue import Connect from ./Connect.vue import SendTransaction from ./SendTransaction.vue const { isConnected } useConnection() /script template Connection v-ifisConnected / Connect v-else / SendTransaction v-ifisConnected / /template完整代码汇总将上述步骤合并后的完整SendTransaction.vue如下可直接复制运行script setup langts import { useSendTransaction, useWaitForTransactionReceipt, } from wagmi/vue import { parseEther } from viem const { data: hash, error, isPending, sendTransaction } useSendTransaction() function submit(event: Event) { const formData new FormData(event.target as HTMLFormElement) const to formData.get(address) as 0x${string} const value formData.get(value) as string sendTransaction({ to, value: parseEther(value) }) } const { isLoading: isConfirming, isSuccess: isConfirmed } useWaitForTransactionReceipt({ hash, }) /script template form submit.preventsubmit input nameaddress placeholder0xA0Cf…251e required / input namevalue placeholder0.05 required / button :disabledisPending typesubmit span v-ifisPendingSending.../span span v-elseSend/span /button div v-ifhashTransaction Hash: {{ hash }}/div div v-ifisConfirmingWaiting for confirmation.../div div v-ifisConfirmedTransaction Confirmed!/div div v-iferror Error: {{ (error as BaseError).shortMessage || error.message }} /div /form /template底层原理一次点击背后的完整调用链理解useSendTransaction的封装层级有助于排查问题和按需定制。从仓库源码可以还原出如下调用链组合式函数层packages/vue/src/composables/useSendTransaction.ts 调用sendTransactionMutationOptions(config, parameters)生成 mutation 选项再交给 TanStack Vue Query 的useMutationQuery 选项层packages/core/src/query/sendTransaction.ts 定义mutationKey: [sendTransaction]并把mutationFn指向核心 actionreturn { ...(options.mutation as any), mutationFn(variables) { return sendTransaction(config, variables) }, mutationKey: [sendTransaction], }核心 action 层packages/core/src/actions/sendTransaction.ts 通过getConnectorClient获取当前连接器对应的 viem 客户端携带已连接账户与签名能力然后委托给viem/actions的sendTransaction完成「构造交易 → 钱包签名 → 广播」全流程最终返回交易哈希。其参数类型SendTransactionParameters在 viem 参数基础上移除了chain/gas字段并叠加了ChainIdParameter与可选的gas覆盖项。同理useWaitForTransactionReceipt的封装路径是Vue 组合式函数packages/vue/src/composables/useWaitForTransactionReceipt.ts→waitForTransactionReceiptQueryOptions→ 核心 actionwaitForTransactionReceipt轮询直到交易上链或回滚。文档描述其行为为等待交易被包含进区块后返回回执若交易 revert 则抛出错误同时支持替换交易如加速/取消的检测。延伸阅读想读取合约数据view/pure函数参见 从合约读取数据指南其中演示了useReadContract以及用query.enabled控制依赖就绪的写法想向合约写入状态参见 写入合约指南完整的组合式函数参数与返回值 useSendTransaction API、useWaitForTransactionReceipt API底层核心 action sendTransaction 与 waitForTransactionReceipt。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考