You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Pinia Store最新状态并传入wagmi异步函数?

问题描述

我创建了一个简单的Pinia计数器store,计数器更新时页面能正常显示最新数值,但在调用wagmi的useContractWrite函数时,无法获取到计数器的最新状态,传入的始终是初始值0。尝试使用getter函数(如const currentCount = counterStore.getCount)还会导致应用崩溃。请问如何正确获取Pinia Store的最新状态,并将其传入wagmi的异步函数中?

附相关代码

count.ts(Pinia store)

export const useCounterStore = defineStore('counter', {
  state: () => {
    return {
    count: 0
    }
  },
  actions: {
    increment() {
    return this.count++
    },
    decrement() {
      return this.count--
    }
  },
  getters: {
    getCount() {
      return this
    }
  }
});

page.vue

<template>
    <div>
      <button @click="counterStore.increment">+</button>
        <p>{{ counterStore.count }}</p>
          <button @click="counterStore.decrement" :disabled="counterStore.count == 0">-</button>
         <button v-if="user.isConnected" @click="() => write()">Mint</button>
        <p v-else="" @click="user.connect">Connect Wallet</p>
    </div>
</template>

<script setup>
import { useCounterStore } from '#imports'
import { useContractWrite } from 'use-wagmi'
import { parseEther } from 'ethers';
import { useMyUserStore } from '#imports';

const counterStore = useCounterStore()
const user = useMyUserStore()

const { data, isLoading, isSuccess, write } = useContractWrite({
  address: '0x3E966c216fB0b92664DB70b4217AD15d470fe7AC',
    abi: [
  {
      inputs: [
        {
          "internalType": "uint256",
          "name": "amount",
          "type": "uint256"
        }
      ],
      name: "T2GMint",
      outputs: [],
      stateMutability: "payable",
      type: "function"
    }
  ],
  functionName: 'T2GMint',
  value: parseEther('0.015'),
  args: [counterStore.count], //counterStore.count is 0. Using getter function here breaks app
  account: user.address
})

</script>
解决方案

1. 修复Pinia Store的错误Getter

你的getCount getter错误返回了整个store实例,这会导致wagmi解析参数时崩溃。修改为直接返回count值:

// count.ts
export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  actions: {
    increment() { this.count++ },
    decrement() { if(this.count > 0) this.count-- } // 加判断避免负数
  },
  getters: {
    getCount: (state) => state.count // 正确返回count数值
  }
});

2. 动态传递最新状态到wagmi

useContractWrite的初始化配置只会执行一次,无法跟踪Pinia状态变化。解决方案是使用writeAsync(推荐)或write的动态参数,在调用时实时获取最新count:

修改page.vue的点击逻辑和useContractWrite配置:

<template>
  <div>
    <button @click="counterStore.increment">+</button>
    <p>{{ counterStore.count }}</p>
    <button @click="counterStore.decrement" :disabled="counterStore.count === 0">-</button>
    <button v-if="user.isConnected" @click="handleMint">Mint</button>
    <p v-else @click="user.connect">Connect Wallet</p>
  </div>
</template>

<script setup>
import { useCounterStore } from '#imports'
import { useContractWrite } from 'use-wagmi'
import { parseEther } from 'ethers';
import { useMyUserStore } from '#imports';

const counterStore = useCounterStore()
const user = useMyUserStore()

// 初始化时不传入args,留空
const { data, isLoading, isSuccess, writeAsync } = useContractWrite({
  address: '0x3E966c216fB0b92664DB70b4217AD15d470fe7AC',
  abi: [
    {
      inputs: [{ internalType: "uint256", name: "amount", type: "uint256" }],
      name: "T2GMint",
      outputs: [],
      stateMutability: "payable",
      type: "function"
    }
  ],
  functionName: 'T2GMint',
  value: parseEther('0.015'),
  account: user.address
})

// 点击时动态传入最新count
const handleMint = async () => {
  if (counterStore.count === 0) return; // 避免 mint 0 数量
  try {
    await writeAsync({
      args: [counterStore.count] // 每次调用都取最新状态
    })
  } catch (err) {
    console.error('Mint失败:', err)
  }
}
</script>

3. 原理说明

  • useContractWrite的配置对象在组件挂载时就完成求值,初始counterStore.count为0,之后不会自动更新。
  • 通过writeAsync动态传参,可以在每次点击时获取最新的Pinia状态,确保传入正确的数值。

内容的提问来源于stack exchange,提问作者Meltxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:20:30