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>



相关推荐
mldong4 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排5 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60615 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角6 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!7 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰7 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi8 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen9 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马10 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu10 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss