vue-router路由传值

8 阅读2分钟

一、路由传值的核心方式与场景

定义:在Vue应用中,页面跳转时传递数据的机制,是单页应用(SPA)数据流通的重要方式。
核心场景

  • 详情页传递资源ID(如商品详情页传商品ID);
  • 列表页传递筛选条件(如搜索关键词、页码);
  • 跨页面传递临时状态(如表单填写进度)。

二、URL 传值(最常用方案)

1. 路径参数(Path Parameters)
  • 配置与传值
    // 路由配置(定义参数)
    const routes = [
      { path: '/user/:id', component: UserDetail }
    ]
    
    // 编程式导航传值
    this.$router.push('/user/123') // URL变为 /user/123
    
    // 声明式导航传值
    <router-link to="/user/123">用户详情</router-link>
    
  • 接收参数
    // 组件中获取参数
    const userId = this.$route.params.id // userId = '123'
    
    // Vue 3 组合式API
    import { useRoute } from 'vue-router'
    const route = useRoute()
    const userId = route.params.id
    
  • 特点
    • 参数显示在URL中,刷新页面不丢失;
    • 适合传递标识性数据(如ID、类型),参数结构固定。
2. 查询参数(Query Parameters)
  • 配置与传值
    // 编程式导航
    this.$router.push({
      path: '/search',
      query: { keyword: 'apple', page: 1 }
    }) // URL变为 /search?keyword=apple&page=1
    
    // 声明式导航
    <router-link :to="{ path: '/search', query: { keyword: 'apple' }}">搜索</router-link>
    
  • 接收参数
    const keyword = this.$route.query.keyword // 'apple'
    const page = Number(this.$route.query.page) // 1
    
  • 特点
    • 参数显示在URL中,适合传递非标识性数据(如搜索条件、分页参数);
    • 支持更灵活的参数结构(如对象、数组,但需JSON序列化)。

三、编程式传值(state 传值)

  • 传值方式
    // 跳转时传递state(数据不显示在URL中)
    this.$router.push({
      name: 'User',
      params: { id: 123 },
      state: { from: 'home', data: { foo: 'bar' } }
    })
    
    // 命名路由传值(更推荐)
    this.$router.push({
      name: 'UserDetail',
      params: { id: 123 },
      state: { from: 'home' }
    })
    
  • 接收参数
    // 仅在同一路由跳转时有效(如从A→B→A)
    const from = this.$route.state.from // 'home'
    
    // 注意:刷新页面会丢失state数据
    
  • 局限性
    • 兼容性差(部分浏览器不支持);
    • 仅适用于临时状态传递,不推荐作为主要方案。

四、非URL传值方案(复杂场景)

1. Vuex/Pinia 状态管理
  • 适用场景:跨页面、跨组件的大量数据传递(如用户信息、购物车)。
  • 示例
    // 存储数据到Vuex
    store.commit('setProduct', { id: 123, name: '手机' })
    
    // 跳转页面
    this.$router.push('/product/detail')
    
    // 接收数据
    const product = this.$store.state.product
    
2. 本地存储(localStorage/sessionStorage)
  • 适用场景:传递大量数据或需要刷新保留的数据(如表单草稿)。
  • 示例
    // 存储数据
    localStorage.setItem('formData', JSON.stringify({ name: '小明', age: 18 }))
    
    // 跳转页面
    this.$router.push('/form/submit')
    
    // 接收数据
    const formData = JSON.parse(localStorage.getItem('formData'))
    
  • 注意:需手动管理数据生命周期,避免内存泄漏。
3. 事件总线(EventBus)
  • 适用场景:简单场景下的跨页面通信(如登录成功后刷新用户信息)。
  • 示例
    // 事件总线
    import { ref } from 'vue'
    export const eventBus = ref({})
    
    // 发送数据
    eventBus.value.emit('update-user', { id: 123 })
    
    // 接收数据
    eventBus.value.on('update-user', (data) => {
      this.userId = data.id
    })
    

五、问题

1. 问:路径参数和查询参数的本质区别?
    • URL结构:路径参数嵌入路径(如/user/123),查询参数附加在URL后(如?id=123);
    • 语义化:路径参数更符合RESTful规范(标识资源),查询参数表示资源的筛选条件;
    • 参数限制:路径参数通常为字符串,查询参数可通过编码传递复杂数据(如JSON)。
2. 问:如何传递复杂对象数据?
    • URL传值:需先序列化对象(如JSON.stringify),接收时再解析:
      // 传值
      const params = { id: 123, options: { color: 'red' } }
      this.$router.push({
        path: '/page',
        query: { data: JSON.stringify(params) }
      })
      
      // 取值
      const data = JSON.parse(this.$route.query.data)
      
    • 非URL方案:使用Vuex或本地存储传递,避免URL长度限制(浏览器通常限制URL长度在2KB以内)。
3. 问:路由传值时中文乱码如何解决?
    • 编码处理:传值时用encodeURIComponent编码,取值时用decodeURIComponent解码:
      // 传值
      const keyword = '苹果';
      this.$router.push(`/search?keyword=${encodeURIComponent(keyword)}`);
      
      // 取值
      const decodedKeyword = decodeURIComponent(this.$route.query.keyword);
      
    • 服务器配置:确保后端接口和服务器支持UTF-8编码(如Nginx添加charset utf-8)。

六、传值方案对比与最佳实践

方案优点缺点推荐场景
路径参数URL语义化,刷新保留参数结构固定,不适合复杂数据详情页ID、分类导航
查询参数灵活支持多参数,刷新保留URL可能过长,中文需编码搜索条件、分页、筛选器
state 传值数据不暴露在URL中刷新丢失,兼容性差临时状态(如跳转来源页面)
Vuex/Pinia适合大量数据,跨组件共享引入状态管理复杂度大型应用、全局数据共享
本地存储可存储大量数据,刷新不丢失数据需手动清理,可能过期临时草稿、跨页面缓存