wagmi Vue useClient 组合式函数完全指南:获取与响应式监听 Viem Client
2026/9/18 18:56:49 网站建设 项目流程

wagmi Vue useClient 组合式函数完全指南:获取与响应式监听 Viem Client

【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi

useClient 是@wagmi/vue提供的组合式函数(Composable),用于在 Vue 组件中获取 Viem 的Client实例,并在链或配置变化时自动响应式更新。本文围绕 useClient 官方文档 展开,结合@wagmi/vue@wagmi/core的源码与测试实现,完整讲解其导入方式、用法、参数与返回值类型,帮助读者在自己的 Vue 应用中正确、高效地拿到链上客户端,用于签名、发送交易或调用合约。

背景:Viem Client 与 useClient 的角色

在 wagmi 生态中,Viem 的Client中管理,而useClient就是 Vue 组件与 ViemClient之间的桥梁:

  • 它从 WagmiPlugin 提供的全局配置中读取链状态;
  • 它返回一个 Vue 的Ref<Client | undefined>,当链切换(switchChain)或配置初始化完成后,client.value会随之更新;
  • 组件卸载时自动清理订阅,无需手动调用unwatch

也就是说,useClient并不是简单的一次性取值,而是一个响应式的客户端访问入口

导入方式

@wagmi/vue其他组合式函数一致,直接从包入口导入即可:

import { useClient } from '@wagmi/vue'

对应的类型UseClientParametersUseClientReturnType同样从@wagmi/vue导出,供需要显式标注类型的场景使用:

import { type UseClientParameters } from '@wagmi/vue' import { type UseClientReturnType } from '@wagmi/vue'

基础用法

<script setup>中调用useClient(),即可拿到当前链对应的 Viem Client:

<script setup lang="ts"> import { useClient } from '@wagmi/vue' const client = useClient() </script>

该组合式函数需要配合已安装的WagmiPlugin使用——插件通过app.provide(configKey, config)将 Config 注入到组件树中(见 packages/vue/src/plugin.ts),useClient内部再通过inject取出。示例中./config对应的配置文件如下(见 site/snippets/vue/config.ts):

import { createConfig, http } from '@wagmi/vue' import { mainnet, sepolia } from '@wagmi/vue/chains' export const config = createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })

默认(不传任何参数)时,useClient返回当前激活链对应的 Client:若当前激活链为主网,则返回连接 mainnet 的 Client。

一个完整的组件示例

下面是一个可直接运行的组合示例,先安装插件,再在组件中读取 Client 并展示其链信息:

// main.ts import { createApp } from 'vue' import { WagmiPlugin } from '@wagmi/vue' import { config } from './config' const app = createApp(App) app.use(WagmiPlugin, { config }) app.mount('#app')
<!-- App.vue --> <script setup lang="ts"> import { useClient } from '@wagmi/vue' const client = useClient() </script> <template> <div v-if="client"> <p>当前链 ID:{{ client.chain.id }}</p> <p>Transport 类型:{{ client.transport.type }}</p> </div> <p v-else>Client 尚未就绪或当前链未配置</p> </template>

参数详解

useClient接受一个可选的UseClientParameters对象。从源码看(packages/vue/src/composables/useClient.ts),其类型为DeepMaybeRef<GetClientParameters<config, chainId> & ConfigParameter<config>>,其中DeepMaybeRef意味着参数既可以是普通值,也可以是 Vue 的 ref,从而支持响应式传参。可配置的参数共有两个。

chainId

  • 类型:config['chains'][number]['id'] | undefined
  • 作用:指定要获取 Client 的链 ID。不传时使用当前激活链。

典型用法是明确指定某条链:

<script setup lang="ts"> import { useClient } from '@wagmi/vue' import { mainnet } from '@wagmi/vue/chains' // [!code focus] import { config } from './config' const client = useClient({ chainId: mainnet.id, // [!code focus] }) </script>

几点重要的行为细节(均有源码或测试佐证):

  • 响应式参数chainId可以传入一个ref,改变 ref 的值会触发 Client 更新。测试 packages/vue/src/composables/useClient.test.ts 中,chainIdref(456)变为1后,等待断言client?.chain.id === 1通过,验证了这一行为。
  • 未配置的链返回 undefined:若传入的chainId不在configchains列表中,返回值是undefined而非抛错。测试behavior: unconfigured chain(同文件第 38-40 行)以chainId: 123456验证了这一点;底层原因在于getClient内部用try/catch包裹config.getClient(parameters),失败时返回undefined(见 packages/core/src/actions/getClient.ts)。
  • 类型层面的约束:在类型测试 packages/vue/src/composables/useClient.test-d.ts 中,向已配置的config传入chainId: 123456会触发@ts-expect-error,即 TS 会在编译期阻止你访问未配置链的 Client 类型;而省略config参数时,未配置链只会收窄为undefined,代码需先做空值判断才能访问client.value.chain

config

  • 类型:Config | undefined
  • 作用:显式传入 Config,以替代从WagmiPlugin注入的全局配置。适用于测试、多配置实例或希望在组件树之外使用useClient的场景。
<script setup lang="ts"> import { useClient } from '@wagmi/vue' import { config } from './config' // [!code focus] const client = useClient({ config, // [!code focus] }) </script>

从实现看,useClient内部先调用useConfig(params)(packages/vue/src/composables/useConfig.ts):若显式传入了config则直接透传使用;否则检查是否存在注入上下文并inject全局配置,未安装WagmiPlugin时会抛出WagmiPluginNotFoundError。因此config参数既是覆盖手段,也是脱离插件依赖时的逃生通道。

返回值类型

useClient的返回类型为:

import { type UseClientReturnType } from '@wagmi/vue'
  • 类型:Ref<Client | undefined>
  • 含义:一个 Vue 响应式引用,其值为 Viem 的Client实例或undefined

关于返回值的三个关键点:

  1. 可能是 undefined:链未配置、配置尚未就绪或当前链没有可用 transport 时,client.valueundefined。在模板中应使用v-if="client"之类的守卫,或在使用前做空值判断。
  2. 只读 Ref:源码最后返回readonly(client)(见 packages/vue/src/composables/useClient.ts),即外部无法直接改写返回值,客户端实例始终由 wagmi 内部状态驱动,避免出现状态漂移。
  3. 类型随参数收窄:通过configchainId泛型推导,TypeScript 能精确推断出client.value.chainclient.value.transport.type的具体类型(见 packages/vue/src/composables/useClient.test-d.ts),为链 ID、transport 类型等提供编译期校验。

响应式更新机制与底层 Action

useClient的响应式能力建立在两个核心 Action 之上,这也是文档末尾 Action 一节列出的内容:

  • getClient:同步获取 Client 实例。核心实现为config.getClient(parameters),失败时捕获异常并返回undefined(见 packages/core/src/actions/getClient.ts)。
  • watchClient:订阅 Client 的变化。它通过config.subscribe注册监听,并用a?.uid === b?.uid作为相等性判断(见 packages/core/src/actions/watchClient.ts)——只要 Client 实例的uid未变,就认为没有变化,避免无意义的重复触发。

结合 packages/vue/src/composables/useClient.ts 的实现,useClient的完整工作流程如下:

  1. const params = computed(() => deepUnref(parameters)):把参数中的 ref 全部解包,得到稳定的纯对象(deepUnref的实现见 packages/vue/src/utils/cloneDeep.ts);
  2. const config = useConfig(params):按上文规则解析配置;
  3. const client = ref(getClient(config, params.value)):初始同步取值;
  4. watchEffect(() => { client.value = getClient(...) }):当参数(如chainIdref)变化时重新取值;
  5. watchClient(config, { onChange }):订阅全局 Client 变化(如调用switchChain切换链),仅在uid变化时更新本地 ref;组件卸载时通过onScopeDispose(() => unsubscribe())自动清理订阅。

这一设计保证了:无论用户手动switchChain切换链,还是配置在运行时被更新,client.value都会保持与全局状态一致。

典型使用场景

  • 发送交易与合约调用:将useClient()返回的 Client 传给viemwriteContractsendTransaction等函数,用于签名与广播交易。
  • 读取链上数据:结合readContractgetBalance等读取操作,并在链切换后自动使用新链的 Client。
  • 展示当前网络状态:在 UI 中展示client.chain.idclient.transport.type等信息,切换网络时界面自动刷新。
  • 多链场景按需取客户端:通过chainId参数固定获取某条链的 Client,而不受当前激活链影响。

常见问题与注意事项

  • 没有安装 WagmiPlugin 会怎样?未传config参数且未安装插件时,useConfig会抛出WagmiPluginNotFoundError;若连注入上下文都不存在(如在非组件环境中调用),则抛出WagmiInjectionContextError。解决方式是安装插件,或显式传入config
  • client 为 undefined 时不要直接解构useClient返回值可能为undefined,直接访问client.value.chain会报错;建议先用v-ifif守卫。
  • chainId 未配置时不会报错,但会静默返回 undefined:这便于实现“可用则用、不可用则降级”的逻辑,但也要求开发者对未配置链做显式处理。
  • 订阅自动清理useClient借助 Vue 的onScopeDispose在组件卸载时取消watchClient订阅,因此无需在onUnmounted中手动清理。

小结

useClient@wagmi/vue中连接 Vue 响应式系统与 ViemClient的核心组合式函数:它从 WagmiPlugin 提供的全局配置解析链状态,支持通过chainId指定目标链、通过config覆盖全局配置,内部依托getClientwatchClient两个 Action 实现同步取值与响应式监听。理解其参数语义、返回类型及底层订阅机制,有助于在多链、动态切换网络的 Vue dApp 中写出类型安全且状态一致的客户端访问代码。

【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询