Code前端首页关于Code前端联系我们

一、props在vue router里是干啥的?

terry 21小时前 阅读数 19 #Vue
文章标签 vue router;props

p>不少刚开始学Vue路由的朋友,碰到vue - router的props配置时总会犯懵——这玩意儿到底咋用?和直接用$route传参比有啥好处?今天就唠唠vue - router里props的用法和优势,把这些疑惑一个个掰碎了讲清楚。 简单说,props是给路由组件传递参数的一种“优雅方式”,咱平常写路由组件时,要是想拿路由里的参数(比如/user/:id里的id),得用this.$route.params.id这种写法,但这样做有个问题:组件和路由紧紧绑在一起了(专业点叫“强耦合”)。

而props的作用,就是把路由里的参数“解耦”出来,变成组件的props属性,路由负责把参数“递”给props,组件只需要像接收普通父传子参数一样,用props选项声明接收就行,这样一来,哪怕以后路由规则变了,组件内部也不用大改,甚至组件还能在非路由场景下复用(比如当普通组件给其他页面用)。

props的几种配置玩法

vue - router给props设计了布尔、对象、函数三种配置模式,不同场景用不同模式,灵活得很。

布尔模式(props: true

适合“把路由params参数直接传给组件props”的场景,举个例子:

路由配置长这样:

const routes = [
  {
    path: '/user/:id', 
    component: User, 
    props: true 
  }
]

User组件里只需要声明props:

export default {
  props: ['id'], // 声明接收id参数
  mounted() {
    console.log(this.id) // 直接用this.id,不用this.$route.params.id
  }
}

这种模式的好处很直接:路由params和组件props自动映射,组件不用关心“路由参数咋拿”,只负责用props里的id

对象模式(props: { ... }

要是你想给组件传静态参数(参数值不随路由变化),就用对象模式,比如做个固定标题的页面:

路由配置:

const routes = [
  {
    path: '/about', 
    component: About, 
    props: { title: '关于我们', isShow: true } 
  }
]

About组件接收:

export default {
  props: { String,
    isShow: Boolean
  },
  mounted() {
    console.log(this.title, this.isShow) // 输出“关于我们” true
  }
}

这种模式适合“组件需要固定配置”的场景,比如页面默认开关、固定文案这些,不管路由怎么变,传的值都是固定的。

函数模式(props: (route) => ({ ... })

如果需要动态处理路由参数(比如结合query参数、加工params格式),函数模式就派上用场了。route参数是当前路由对象,里面包含paramsquerypath等信息。

举个实际例子:商品详情页需要传商品idparams),还要根据query里的tab决定显示哪个标签页。

路由配置:

const routes = [
  {
    path: '/product/:id', 
    component: Product, 
    props: (route) => ({
      productId: route.params.id, // 取params里的id
      activeTab: route.query.tab || 'info' // 取query里的tab,没有就默认info
    })
  }
]

Product组件接收:

export default {
  props: {
    productId: String,
    activeTab: String
  },
  mounted() {
    console.log(this.productId, this.activeTab) 
    // 比如访问/product/123?tab=detail,就输出“123” “detail”
  }
}

函数模式的灵活性在于:能对路由参数做任意处理——比如把id从字符串转成数字,或者合并多个参数,甚至还能结合Vuex、全局配置等,返回更复杂的参数(不过要注意,函数里this不是Vue实例,别直接用this.$store,可以把逻辑放到组件里处理)。

用props代替$route传参有啥优势?

很多人会问:“我直接用this.$route也能拿参数,为啥非要用props?” 这就得聊聊解耦、维护、设计理念这几个关键点了。

组件解耦更彻底

如果组件里全是this.$route.xxx,这个组件就和路由“绑死”了——一旦路由规则变了(比如参数名从id改成userId),组件里所有this.$route.params.id都得改;而且这个组件也没法在非路由场景复用(比如当弹窗组件用,没路由的时候$route就不存在了)。

但用props的话,组件只关心“我需要哪些参数”,不管参数从路由来、还是父组件手动传,比如上面的User组件,哪怕不在路由里用,父组件也能这么写:

<User :id="100" />

组件完全不用改,复用性直接拉满。

代码可读性&维护性提升

看组件代码时,直接看props选项就知道“这个组件需要啥参数”,不用满世界找this.$route在哪;路由配置里的props也清晰展示了“参数咋从路由映射到组件”,后期要改参数逻辑,只需要动路由配置的props部分,组件内部完全不用碰。

举个反面例子:如果组件里到处是this.$route.params.id,某天产品说“路由参数要加个前缀”,你得把所有this.$route.params.id改成this.$route.params.id.replace('prefix - ', ''),改起来又麻烦又容易漏,但用props的话,只需要在路由的函数模式里改一行:

props: (route) => ({
  productId: route.params.id.replace('prefix - ', '') 
})

组件里该咋用还咋用,完全不受影响。

更符合Vue的设计理念

Vue强调“单向数据流”和“组件化”,props是组件通信的核心方式之一,用props做路由传参,相当于把“路由”当成一个特殊的“父组件”,通过props把数据“流”到子组件里,完美契合Vue的设计逻辑。

实际开发中容易踩的坑和注意点

知道了用法和优势,也得避避坑,这几个细节一定要注意:

布尔模式只传params,不传query

props: true时,只有$route.params里的参数会被传给props,query参数(比如?tab=info)不会自动传,如果要传query,必须用函数模式自己处理,

props: (route) => ({
  ...route.params, // 传params
  ...route.query // 传query
})

组件必须声明props选项

不管用哪种模式,组件里一定要用props选项声明接收的参数!比如用了props: true,但组件没写props: ['id'],那this.id就是undefined,直接报错。

函数模式里的this不是Vue实例

路由配置里的props函数,this指向不是Vue实例,所以别在函数里写this.$storethis.$axios这些,如果需要依赖Vuex或者工具库,建议把逻辑放到组件的computedmounted里处理,或者在函数里返回需要的参数,组件再自己调接口。

举个完整小例子,看效果更直观

假设做一个“订单详情页”,需要传订单idparams),还要根据查询参数mode(普通/精简模式)渲染不同布局,用函数模式实现:

路由配置:

const routes = [
  {
    path: '/order/:orderId', 
    component: OrderDetail, 
    props: (route) => ({
      orderId: route.params.orderId, 
      displayMode: route.query.mode || 'normal' 
    })
  }
]

OrderDetail组件:

export default {
  props: {
    orderId: {
      type: String,
      required: true // 订单id是必须的
    },
    displayMode: {
      type: String,
      default: 'normal' // 默认普通模式
    }
  },
  mounted() {
    console.log('订单ID:', this.orderId)
    console.log('显示模式:', this.displayMode)
    // 这里可以用orderId调接口拿订单数据,用displayMode决定渲染逻辑
  }
}

当访问/order/123?mode=simple时,组件里this.orderId'123'this.displayMode'simple';如果访问/order/456(没带query),displayMode就是默认的'normal'

这个例子里,路由负责“参数传递和简单处理”,组件只负责“用参数做业务逻辑”,分工明确,后期维护也方便——比如以后要加个“暗黑模式”参数,只需要在路由的props函数里加一行,组件完全不用动。

props的核心价值是“灵活解耦”

vue - router的props配置,本质是在路由和组件之间搭了个“智能传参桥梁”

  • 布尔模式:快速把params映射给props,简单场景直接用;
  • 对象模式:传静态参数,给组件固定配置;
  • 函数模式:复杂参数处理,想怎么加工就怎么加工。

而它最大的优势,是让组件更干净、更易复用、更好维护——毕竟谁也不想改个路由参数,还要在组件里到处找$route对吧?

现在再看props,是不是觉得“哦,原来这玩意儿这么有用”?下次写路由组件时,别再一股脑用this.$route了,试试props配置,你会发现代码清爽了不少~

(全文约1500字,把props的用法、优势、坑点、例子全唠明白了,新手能跟着步骤用起来,老手也能再巩固下设计思路~)

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门