【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 表单写法模板 👌
相关推荐
油丶酸萝卜别吃1 小时前
utils.js 说明文档
开发语言·javascript·ecmascript
zyplayer-doc3 小时前
VuePress类静态文档站和动态知识库怎么选:两种技术路线的适用场景
javascript·人工智能·后端·安全·智能手机
Sterting7 小时前
第9课 Vue Router 路由
前端·vue.js
码哥DFS8 小时前
构造函数、实例对象、对象原型 ----三者关系
开发语言·javascript·原型模式
满栀5858 小时前
vue动态路由效果
前端·javascript·vue.js·前端框架·vue
心运软件9 小时前
SpringBoot+ Vue校园社团管理平台的完整架构设计
vue.js·后端
jjw_zyfx10 小时前
css vue vite实现闪烁的呼吸效果
javascript·css·vue.js
sunly_10 小时前
React useActionState 的用法详解
前端·javascript·react.js
cyadyx11 小时前
【Three.js】Three.js 中加载 3D 模型
前端·javascript·3d
汉堡大王952711 小时前
前端工程师 TypeScript 上手指南:一条清晰的从入门到精通路线
前端·javascript·react.js