【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 表单写法模板 👌
相关推荐
hhb_61819 分钟前
TypeScript泛型实战:企业级请求封装全解析
javascript·ubuntu·typescript
BomanGe237 分钟前
NSK直线导轨LH55EL与NH55EM替代指南
前端·javascript·数据库·经验分享·规格说明书
云水一下37 分钟前
Vue.js从零到精通系列(四):前端路由与Vue Router——打造多页单页应用
前端·javascript·vue.js
baozj41 分钟前
把徒步轨迹做成 3D 地形模型:开源工具「印迹 TrailPrint 3D」
前端·vue.js·github
Momo__42 分钟前
alien-signals — 驱动 Vue 3.6 响应式引擎的那个 1KB 库
前端·vue.js·响应式编程
用户831348593069844 分钟前
Vue3+Cesium实现3DTiles模型实时调节(离地面高度/xyz轴旋转/模型经纬度偏移)
vue.js·cesium
zhedream1 小时前
Vue 3 Teleport 报错实录:从 patch 时机到 `defer` 属性
前端·vue.js
雁北向1 小时前
自定义指令 数值输入显示优化 巴飞特 测试
前端·vue.js
研☆香1 小时前
jQuery补充知识点
前端·javascript·jquery
先吃饱再说1 小时前
JavaScript栈和队列:从“冰柜里的雪糕”到“排队打饭”
javascript·数据结构