Vue.js路由跳转至组件时如何传递非URL包含的参数?
Vue.js侧边栏跳转时URL参数传递失败的解决方法
问题背景
开发了一个Vue.js的SideBar组件,通过获取JSON数据生成侧边栏按钮,JSON结构为键名(如applicants)对应资源URL的映射:
{ "applicants": "url1", "applications": "url2", "companies": "url3", "employees": "url4", "jobs": "url5", "recruiters": "url6", "reviews": "url6", ..... }
点击按钮可正常跳转到目标页面,但无法将对应的URL传递到跳转后的MenuItem组件,尝试过props、Vuex等方式均未解决。
现有代码
SideBar组件代码
<template> <aside> <h3>Menu</h3> <div v-for="(key, value) in menu_items" :key="key" class="menu"> <button @click="push_to(value, key)" name="value" class="button"> <span class="text">{{ value.toString().charAt(0).toUpperCase() + value.toString().slice(1) }}</span> </button> </div> </aside> </template> <script> const URL = "https://groep35.webdev.ilabt.imec.be" export default { data() { return { menu_items: [] } }, mounted() { fetch(URL) .then(res => res.json()) .then(data => this.menu_items = data) .catch(err => console.log(err)) }, methods: { push_to(name, url){ this.$router.push({ name: "menu-item", params: { link: name, url: url} }) } } } </script>
路由配置代码
import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' import MenuItem from '../views/MenuItem.vue' const router = createRouter({ history: createWebHistory(), routes: [ { path: '/', component : Home, props: true }, { path: '/:link', name: 'menu-item', component: MenuItem, props: true } ] }) export default router
MenuItem组件代码
<template> <div> <h1>{{this.$route.params.link}}</h1> <h1>{{this.$route.params.url}}</h1> </div> </template> <script> export default { } </script>
问题分析
- v-for参数顺序错误:遍历对象时,Vue的
v-for="(value, key) in obj"中第一个参数是对象的值,第二个是键名。现有代码中v-for="(key, value) in menu_items"搞反了,导致传递给push_to的name和url参数完全颠倒,实际传的是键名当URL,值当name。 - 路由参数未持久化:路由配置中仅定义了
:link作为路径参数,url通过params传递但未包含在路径中,刷新页面后该参数会丢失。
解决方案
步骤1:修正v-for参数顺序
将SideBar组件中的v-for循环参数调整为正确的顺序,同时简化按钮文本的处理:
<div v-for="(url, name) in menu_items" :key="name" class="menu"> <button @click="push_to(name, url)" class="button"> <span class="text">{{ name.charAt(0).toUpperCase() + name.slice(1) }}</span> </button> </div>
步骤2:选择合适的参数传递方式
方式一:使用query参数传递(刷新不丢失)
修改SideBar的push_to方法,通过query传递URL:
push_to(name, url){ this.$router.push({ name: "menu-item", params: { link: name }, query: { url: url } }) }
然后在MenuItem组件中获取query参数:
<template> <div> <h1>{{ $route.params.link }}</h1> <h1>{{ $route.query.url }}</h1> </div> </template>
方式二:使用props传递(组件化最佳实践)
修改路由配置,通过函数式props传递参数:
{ path: '/:link', name: 'menu-item', component: MenuItem, props: route => ({ link: route.params.link, url: route.query.url }) }
在MenuItem组件中声明props,无需直接访问$route:
<template> <div> <h1>{{ link }}</h1> <h1>{{ url }}</h1> </div> </template> <script> export default { props: ['link', 'url'] } </script>
步骤3:验证效果
完成上述修改后,点击侧边栏按钮,跳转后的MenuItem组件即可正确显示对应的link和url,且刷新页面后参数不会丢失。
内容的提问来源于stack exchange,提问作者Timon Coucke
相关产品推荐
相关产品推荐

