Vue3路由的props

Vue3路由的props

props的作用

它在路由里面的作用很简单,就是是把路由参数、或者自定义数据,直接喂给路由组件当作props使用,上面说的路由参数也就是我们之前使用params或者query传的参数;

props的写法

  • 布尔值

只传递params参数,参数名和组件的props一致,写法如:{ path: '/goods/:goodsId', component: GoodsDetail, props: true }

  • 对象

传递自定义的静态数据,与路由参数毫无关系,写法如:{ path: '/goods/:goodsId', component: GoodsDetail, props: { isHot: true } }

  • 函数

传递params/query参数,转换参数类型,拼接自定义数据,这个一般情况下是最常用的;写法如:{ path: '/goods/:goodsId', component: GoodsDetail, props: (route) => ({ goodsId: Number(route.params.goodsId), source: route.query.source }) }

小案例

比如我们以一个非常简单的校园社团系统作为例子

  • 首先我们先看路由配置
vue 复制代码
//引入vue-router相关函数,创建路由实例,并使用HTML5的history模式
import { createRouter, createWebHistory } from "vue-router";
import ClubDetailBool from "../components/ClubDetailBool.vue";
import ClubDetailFunc from "../components/ClubDetailFunc.vue";
import ClubDetailObj from "../components/ClubDetailObj.vue";

const routes = [{
    path: '/club/bool/:clubId',
    name: 'ClubDetailBool',
    component: ClubDetailBool,
    props: true
}]

const router = createRouter({
    history: createWebHistory(),
    routes
});

export default routes;
  • 现在我们先创建一个社团列表的组件
js 复制代码
<template>
    <div class="club-list">
        <h2>校园社团列表</h2>
        <button @click="goToBool(1)">查看【布尔值写法】篮球社详情</button>
    </div>
</template>
<script>
import { useRouter } from 'vue-router';
const router = useRouter();
const goToBool = (clubId) => {
    router.push(`/club/bool/${clubId}`);
};
</script>

<style scoped>
button {
    margin: 10px;
    padding: 8px 16px;
    cursor: pointer;
}
</style>
  • 我们先说第一个布尔值的案例
js 复制代码
//ClubDetailBool.vue
<template>
    <div class="club-detail">
        <h3>社团详情</h3>
        <!-- 这个只能拿到params里面的clubID,拿不到静态数据和query参数 -->
        <p>社团ID:{{ clubId }}</p>
    </div>
</template>

<script setup>
//接受props名称必须和路由参数名称一致
const props = defineProps({
    clubId: {
        type: String,
        required: true
    }
});
</script>
  • 对象和函数的案例
js 复制代码
import { createRouter, createWebHistory, RouteLocationNormalized } from 'vue-router'
// 导入三个组件,分别对应三种props写法(实际项目可复用一个组件,这里为了清晰分开)
import ClubDetailBool from '../components/ClubDetailBool.vue'
import ClubDetailObj from '../components/ClubDetailObj.vue'
import ClubDetailFunc from '../components/ClubDetailFunc.vue'

const routes = [
    // 写法1:布尔值 ------ 只传递params参数(clubId),参数名和组件props名一致
    {
        path: '/club/bool/:clubId',
        name: 'ClubDetailBool',
        component: ClubDetailBool,
        props: true // 布尔值写法:自动把params里的clubId传给组件的props
    },

    // 写法2:对象 ------ 传递静态数据(和路由参数无关)
    {
        path: '/club/obj/:clubId', // 路径仍带clubId,但对象写法拿不到,仅做演示
        name: 'ClubDetailObj',
        component: ClubDetailObj,
        props: {
            recruitStatus: '招新中', // 静态数据:不管路由参数是什么,组件都能拿到这个值
            maxMember: 50 // 静态数据:社团最大人数50
        }
    },

    // 写法3:函数(最常用)------ 混合传递params/query/静态数据,还能处理参数类型
    {
        path: '/club/func/:clubId',
        name: 'ClubDetailFunc',
        component: ClubDetailFunc,
        props: (route: RouteLocationNormalized) => ({
            clubId: Number(route.params.clubId), // 把params的clubId(字符串)转数字
            source: route.query.source || '首页', // 拿query参数(比如/club/func/1?source=社团列表)
            recruitStatus: '招新中', // 静态数据
            maxMember: 50 // 静态数据
        })
    }
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

export default router
  • 创建对象案例的组件
vue 复制代码
//ClubDetailObj.vue
<template>
    <div class="club-detail">
        <h3>【对象写法】社团详情</h3>
        <p>招新状态:{{ recruitStatus }}</p>
        <p>最大人数:{{ maxMember }}</p>
        <p>备注:只能拿到静态数据,拿不到clubId/query参数</p>
    </div>
</template>

<script setup>
// 接收props:名称和路由props对象里的键一致
const props = defineProps({
    recruitStatus: String,
    maxMember: Number
})
</script>
  • 父组件
js 复制代码
<template>
    <div class="club-list">
        <h2>校园社团列表</h2>
        <!-- 跳转布尔值写法的详情页 -->
        <button @click="goToBool(1)">查看【布尔值写法】篮球社详情</button>
        <!-- 跳转对象写法的详情页 -->
        <button @click="goToObj(1)">查看【对象写法】篮球社详情</button>
        <!-- 跳转函数写法的详情页(带query参数) -->
        <button @click="goToFunc(1)">查看【函数写法】篮球社详情</button>
    </div>
</template>

<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()

// 跳转布尔值写法
const goToBool = (clubId) => {
    router.push({
        name: 'ClubDetailBool',
        params: { clubId }
    })
}

// 跳转对象写法
const goToObj = (clubId) => {
    router.push({
        name: 'ClubDetailObj',
        params: { clubId } // 虽然传了clubId,但对象写法拿不到
    })
}

// 跳转函数写法(带query参数)
const goToFunc = (clubId) => {
    router.push({
        name: 'ClubDetailFunc',
        params: { clubId },
        query: { source: '社团列表' }
    })
}
</script>

<style scoped>
button {
    margin: 10px;
    padding: 8px 16px;
    cursor: pointer;
}
</style>
  • App.vue也需要样式,让其好看一点
js 复制代码
<template>
    <!-- 页面整体布局 -->
    <div id="app">
        <!-- 导航栏:快速切换不同路由(三种 props 写法) -->
        <nav class="nav">
            <h2>Vue3 路由 props 三种写法演示</h2>
            <div class="nav-buttons">
                <!-- 跳转布尔值写法路由 -->
                <router-link to="/club/bool/1" class="nav-link" active-class="active">
                    布尔值写法(仅传 params)
                </router-link>
                <!-- 跳转对象写法路由 -->
                <router-link to="/club/obj/1" class="nav-link" active-class="active">
                    对象写法(仅传静态数据)
                </router-link>
                <!-- 跳转函数写法路由(带 query 参数) -->
                <router-link to="/club/func/1?source=导航栏" class="nav-link" active-class="active">
                    函数写法(混合传参+类型处理)
                </router-link>
                <!-- 回到社团列表页 -->
                <router-link to="/" class="nav-link" active-class="active">
                    社团列表(跳转测试)
                </router-link>
            </div>
        </nav>

        <!-- 路由出口:所有路由组件都会渲染到这里 -->
        <main class="content">
            <router-view />
        </main>
    </div>
</template>

<script setup>
// App.vue 作为根组件,这里无需额外逻辑,只需要提供路由出口即可
// 若需要全局样式/全局逻辑,可在这里写
</script>

<style scoped>
/* 全局样式(scoped 仅作用于 App.vue,也可抽离到全局样式文件) */
#app {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
    font-family: Arial, Helvetica, sans-serif;
}

/* 导航栏样式 */
.nav {
    padding: 20px;
    background-color: #f5f5f5;
    border-radius: 8px;
    margin-bottom: 20px;
}

.nav h2 {
    margin: 0 0 15px 0;
    color: #333;
}

.nav-buttons {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

/* 路由链接样式 */
.nav-link {
    padding: 8px 16px;
    text-decoration: none;
    color: #42b983;
    /* Vue 主题色 */
    border: 1px solid #42b983;
    border-radius: 4px;
    transition: all 0.2s;
}

.nav-link:hover {
    background-color: #42b983;
    color: white;
}

/* 激活的路由链接样式 */
.nav-link.active {
    background-color: #42b983;
    color: white;
    font-weight: bold;
}

/* 内容区域样式 */
.content {
    padding: 20px;
    border: 1px solid #eee;
    border-radius: 8px;
}
</style>



相关推荐
passerby60619 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了9 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅9 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅10 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅10 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment10 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅10 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊10 小时前
jwt介绍
前端
爱敲代码的小鱼11 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax
吹牛不交税11 小时前
admin.net-v2 框架使用笔记-netcore8.0/10.0版
vue.js·.netcore