【vue】pinia中的值使用 v-model绑定出现[object Object]

版本

javascript 复制代码
  "dependencies": {
    "pinia": "^3.0.4",
    "vue": "^3.5.26"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^6.0.3",
    "vite": "^7.3.1",
    "vite-plugin-vue-devtools": "^8.0.5"
  },
  "engines": {
    "node": "^20.19.0 || >=22.12.0"
  }

代码

user.js

javascript 复制代码
import { defineStore } from 'pinia';

export const useUserStore = defineStore('userStore', {
    actions: {
        changeUsername(value) {
            if(value && value.length<10) {
                this.username += value
            }
        }
    },
    getters: {
        getUsername() {
            return this.username.toUpperCase()
        }
    },
    state: () => ({
        username: 'abc'
    }),
})

App.vue

javascript 复制代码
<script setup>
import { useUserStore } from '@/store/user'
import { storeToRefs } from 'pinia';
import { ref, toRef, toRefs } from 'vue';

  const user = useUserStore()
  
  // 错误
  const userInfo = storeToRefs(user)
  console.log(userInfo.username)

  // 正确
  const {username} = storeToRefs(user)
  console.log(username)

</script>

<template>
  <!-- 错误 -->
  <div> {{ userInfo.username }} </div>
  <input type="text" v-model="userInfo.username">

  <!-- 正确 -->
  <div> {{ username }} </div>
  <input type="text" v-model="username">

</template>

现象


分析

原因

👉 问题不是出在 storeToRefs,而是出在你"把一个 ref 对象当成普通值来用"的心智模型上
[object Object] 说明 input 绑定到的不是字符串,而是一个对象


关键点:storeToRefs 返回的是什么?

js 复制代码
const userInfo = storeToRefs(user)

此时:

js 复制代码
userInfo = {
  username: Ref<string>
}

也就是说:

  • userInfo.username是一个 ref 对象
  • userInfo.username.value → 才是真正的字符串 "abc"

那为什么模板里会出现 [object Object]

表面看很迷惑,因为你写的是:

vue 复制代码
<input v-model="userInfo.username">

v-model 只能直接绑定:

  • 普通变量
  • 或单个 ref

❌ 它不擅长绑定「对象里的 ref」

在这种情况下,Vue 会把整个 Ref 当成值塞进 input,于是:

复制代码
String(Ref) → [object Object]

为什么很多教程让你这样写?

js 复制代码
const { username } = storeToRefs(user)

因为这样:

js 复制代码
username === Ref<string>

这是一个干净的 ref ,非常适合 v-model


✅ 正确、推荐写法(重点)

App.vue

vue 复制代码
<script setup>
import { useUserStore } from '@/store/user'
import { storeToRefs } from 'pinia'

const user = useUserStore()
const { username } = storeToRefs(user)
</script>

<template>
  <div>{{ username }}</div>
  <input type="text" v-model="username" />
</template>

这和你原来的代码真正的区别

你的写法 推荐写法
userInfo.username username
对象里的 ref 单独的 ref
v-model 易出坑 v-model 官方推荐

为什么 {``{ userInfo.username }} 有时"看起来能用"?

因为:

  • 插值表达式会自动解包 ref
  • v-model 在对象嵌套 ref 的场景下不会稳定解包

所以你会看到一个很典型的新手陷阱:

显示正常,但 input 变成 [object Object]


总结一句好记的

storeToRefs 之后,一定要解构再用 v-model

v-model="obj.xxx"

const { xxx } = storeToRefs(store)

如果你愿意,我可以顺手帮你把

  • getter
  • action
  • v-model + 业务校验
    整理成一个标准 Pinia 表单写法模板 👌
相关推荐
山河木马8 小时前
矩阵专题3-怎么创建投影矩阵(uProjectionMatrix)
javascript·webgl·计算机图形学
泯泷9 小时前
第 2 篇:设计第一套字节码:Opcode、Instruction 与 Constant Pool
前端·javascript·安全
泯泷9 小时前
第 1 篇:从 1 + 2 开始:亲手写出第一台 JSVM
前端·javascript·安全
古夕10 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
朦胧之10 小时前
页面白屏卡住排查方法
前端·javascript
Ruihong10 小时前
Vue withDefaults 转 React:VuReact 怎么处理?
vue.js·react.js·面试
犇驫聊AI11 小时前
Chrome DevTools MCP + Claude Code 自定义skills生成接口代码生成器
前端·javascript
kyriewen11 小时前
别再这样写 async/await 了:我在 Code Review 中见过最多的 8 个错误
前端·javascript·面试
稀土熊猫君12 小时前
一个人能做出什么开源项目?
vue.js·后端·开源
用户2986985301416 小时前
在 React 中使用 JavaScript 将 Excel 转换为 SVG
前端·javascript·react.js