【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 表单写法模板 👌
相关推荐
是罐装可乐5 小时前
深入理解“句柄(Handle)“:从浏览器安全到文件系统访问
前端·javascript·安全
华科易迅5 小时前
Vue如何集成封装Axios
前端·javascript·vue.js
不是az5 小时前
CSS知识点记录
前端·javascript·css
昵称暂无16 小时前
.NET 高级开发 | i18n 原理、实现一个 i18n 框架
javascript·c#·.net
h_jQuery6 小时前
vue使用gm-crypto对数据进行sm4加密处理
前端·javascript·vue.js
阿赛工作室6 小时前
Vue中onBeforeUnmount不触发的解决方案
前端·javascript·vue.js
浩星7 小时前
electron系列1:Electron不是玩具,为什么桌面应用需要它?
前端·javascript·electron
_院长大人_8 小时前
Vue + ECharts 实现价格趋势分析图
前端·vue.js·echarts
疯笔码良8 小时前
【Vue】自适应布局
javascript·vue.js·css3
浩星8 小时前
electron系列2:搭建专业Electron开发环境
javascript·typescript·electron