Vue3路由传递复杂参数(比如一个对象)

在 Vue 3 中,需要通过路由传递复杂参数(比如一个对象)时,有多种方法可以实现。下面我为你详细介绍几种主流方式,并提供相应的代码示例。

最佳实践提示:传递复杂对象时,由于 URL 有长度限制,对于数据量较大的对象,建议优先考虑状态管理(如 Pinia)或本地存储。若数据量不大且需要URL体现参数,可使用 queryparams 配合 JSON 序列化。

🗂️ 路由传参方法对比

方法 参数可见性 刷新数据 适用场景
Query 参数 URL中可见 保持 数据量不大,参数需体现在URL中
Params JSON 字符串 URL中可见 (作为路由一部分) 保持 数据量不大,希望以路由结构体现参数
State 传参 不可见 丢失 传递敏感数据或大数据量,不希望在URL暴露
Pinia 状态管理 不可见 可保持 (需配置) 复杂应用,跨组件/路由共享数据
LocalStorage 不可见 保持 需持久化数据,允许同源所有页面访问

🔍 具体方法与代码示例

1. Query 参数方式

通过 URL 查询字符串传递,适合数据量不大的对象。

发送参数

import { useRouter } from 'vue-router'

const router = useRouter()
const userInfo = {
  id: 1,
  name: '张三',
  profile: {
    age: 25,
    email: 'zhangsan@example.com'
  }
}

// 传递对象
const sendParams = () => {
  router.push({
    path: '/user',
    query: userInfo // Vue Router 会自动处理对象
  })
  
  // 或者使用name
  // router.push({
  //   name: 'UserDetail',
  //   query: userInfo
  // })
}

接收参数

import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue'

const route = useRoute()
const userInfo = ref({})

onMounted(() => {
  // 直接获取查询参数对象
  userInfo.value = route.query
  console.log('用户ID:', userInfo.value.id)
  console.log('用户名:', userInfo.value.name)
})

2. Params + JSON 字符串化

将对象转为 JSON 字符串通过 params 传递。

发送参数

import { useRouter } from 'vue-router'

const router = useRouter()
const complexData = {
  items: ['a', 'b', 'c'],
  config: {
    theme: 'dark',
    notifications: true
  }
}

const sendParams = () => {
  router.push({
    name: 'DetailPage',
    params: {
      // 将对象序列化为JSON字符串
      data: JSON.stringify(complexData)
    }
  })
}

注意:使用 params 传参时,路由配置需定义参数占位,例如:path: '/detail/:data'

接收参数

import { useRoute } from 'vue-router'
import { onMounted, ref } from 'vue'

const route = useRoute()
const complexData = ref({})

onMounted(() => {
  // 获取参数并解析JSON
  const dataStr = route.params.data
  if (dataStr) {
    complexData.value = JSON.parse(dataStr)
    console.log('解析后的数据:', complexData.value)
  }
})

3. State 传参方式

通过路由的 state 传递,数据不在 URL 中显示,但刷新页面会丢失。

发送参数

import { useRouter } from 'vue-router'

const router = useRouter()
const largeData = {
  // ... 大数据量对象
  records: Array.from({ length: 100 }, (_, i) => ({ id: i, value: `Item ${i}` }))
}

const sendParams = () => {
  router.push({
    name: 'DataPage',
    state: {
      internalData: largeData
    }
  })
}

接收参数

import { useRouter } from 'vue-router'
import { onMounted, ref } from 'vue'

const router = useRouter()
const internalData = ref({})

onMounted(() => {
  // 从路由状态获取数据
  if (router.currentRoute.value.state?.internalData) {
    internalData.value = router.currentRoute.value.state.internalData
  }
})

4. Pinia 状态管理

使用 Pinia(Vuex 的升级版)管理共享状态。

定义 Store

// stores/userStore.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    userData: null,
    sharedObject: null
  }),
  actions: {
    setUserData(data) {
      this.userData = data
    },
    setSharedObject(obj) {
      this.sharedObject = obj
    }
  }
})

发送参数

import { useRouter } from 'vue-router'
import { useUserStore } from '@/stores/userStore'

const router = useRouter()
const userStore = useUserStore()

const complexObject = {
  id: 123,
  name: '示例对象',
  details: { /* 复杂嵌套数据 */ }
}

const sendParams = () => {
  // 将数据存入 store
  userStore.setSharedObject(complexObject)
  
  // 跳转路由
  router.push({ name: 'TargetPage' })
}

接收参数

import { onMounted, computed } from 'vue'
import { useUserStore } from '@/stores/userStore'

const userStore = useUserStore()

// 使用计算属性获取数据
const sharedObject = computed(() => userStore.sharedObject)

onMounted(() => {
  console.log('共享对象:', sharedObject.value)
})

5. LocalStorage 方式

适合需要持久化存储的数据。

发送参数

import { useRouter } from 'vue-router'

const router = useRouter()
const persistentData = {
  token: 'abc123',
  preferences: {
    language: 'zh-CN',
    theme: 'dark'
  },
  lastUpdated: new Date().toISOString()
}

const sendParams = () => {
  // 存储到 localStorage
  localStorage.setItem('appData', JSON.stringify(persistentData))
  
  // 跳转路由
  router.push({ name: 'Settings' })
}

接收参数

import { onMounted, ref } from 'vue'

const appData = ref({})

onMounted(() => {
  // 从 localStorage 读取数据
  const storedData = localStorage.getItem('appData')
  if (storedData) {
    appData.value = JSON.parse(storedData)
    console.log('应用数据:', appData.value)
  }
})

⚠️ 重要提醒

  • URL 长度限制:浏览器对 URL 长度有限制(通常 2KB-10KB 不等),过大的对象不适合用 queryparams 传递。
  • 数据安全性:避免通过 URL 传递敏感信息(如密码、token),这类数据应使用 state、Pinia 或 localStorage
  • 数据序列化:对象中包含 DateFunction 等特殊类型时,JSON 序列化/反序列化会丢失其原始类型,需要额外处理。

💎 总结

根据你的具体需求选择合适的方法:

  • 简单对象,需URL体现:使用 Query 参数
  • 结构化路由:使用 Params + JSON 序列化
  • 敏感数据或临时传递:使用 State 传参
  • 复杂应用数据共享:使用 Pinia 状态管理
  • 需要持久化存储:使用 LocalStorage
posted @ 2025-10-10 10:24  dirgo  阅读(28)  评论(0)    收藏  举报