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>



相关推荐
last demo1 小时前
grep和sed
linux·运维·前端·chrome
-曾牛1 小时前
深入解析 XSS 漏洞:原理、分类与攻防实战
前端·安全·web安全·网络安全·渗透测试·xss·原理解析
JK凯1 小时前
前端调试技巧
前端·visual studio code·前端工程化
开源之眼1 小时前
github star 基础IO 文件在内核中是怎么被管理的 重定向的含义 在自定义shell中加入重定向
前端
JZXStudio1 小时前
独立开发者亲测:MLX框架让我的App秒变AI原生!15年iOS老兵的2025新感悟
前端·ios
cindershade1 小时前
Vue 3:我在真实项目中如何用事件委托
前端
我叫黑大帅1 小时前
存储管理在开发中有哪些应用?
前端·后端·全栈
鲨叔1 小时前
zustand 从原理到实践 - 原理篇(2)
前端·react.js
之恒君1 小时前
PromiseResolveThenableJobTask 的在Promise中的使用
javascript·promise