vue路由第二篇-路由传参之案例实现

14 篇文章 5 订阅

路由

1. 路由传参

1.1 环境准备

1.1.1 定义数据

我们在 src 目录创建 list.json 文件,在这文件中数据如下:

{
    "data": [
        {
            "id": 1,
            "name": "奥迪 Q7",
            "price": 650000
        },
        {
            "id": 2,
            "name": "宝马 X6",
            "price": 700000
        },
        {
            "id": 3,
            "name": "奔驰 S350",
            "price": 1200000
        }
    ]
}
1.1.2 定义类型

我们可以通过 json2ts 的网站来帮我们把 JSON 格式的数据转换为相应的类型。

export interface Datum {
        id: number;
        name: string;
        price: number;
    }

    export interface RootObject {
        data: Datum[];
    }
1.1.3 定义列表组件

在 components 目录中创建 Product.vue 组件。代码如下:

<template>
    <table cellspacing="0" class="table" border="1">
        <thead>
        <tr>
            <th>编号</th>
            <th>品牌</th>
            <th>价格</th>
            <th>操作</th>
        </tr>
        </thead>
    </table>
</template>

<script setup lang="ts">
import {ref} from 'vue'
// 引入数据
import { data } from '../list.json'
// 引入类型
import { Item, RootObject } from '../datatype'



</script>

<style scoped>

</style>
1.1.4 配置路由

在 src 目录下创建 router 目录,然后创建 index.ts 文件。

import {createRouter, createWebHashHistory, RouteRecordRaw} from "vue-router";

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        component: () => import('../components/Product.vue'),
    },
]

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

export default router
1.1.5 挂载路由

在 main.ts 入口文件中挂载路由。

import { createApp } from 'vue'
import App from './App.vue'

// 引入路由配置
import router from './router'

createApp(App).use(router).mount('#app')
1.1.6 在根组件中使用路由
<template>
    <router-link to="/">产品列表</router-link>
    <router-view></router-view>
</template>

<script setup lang="ts">

</script>

<style>

</style>

1.2 完整列表组件

<template>
    <table cellspacing="0" class="table" border="1">
        <thead>
        <tr>
            <th>编号</th>
            <th>品牌</th>
            <th>价格</th>
            <th>操作</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="item in data" :key="item.id">
            <td>{{ item.id }}</td>
            <td>{{ item.name }}</td>
            <td>{{ item.price }}</td>
            <td><button @click="toDetail(item)">详情</button></td>
        </tr>
        </tbody>
    </table>
</template>

<script setup lang="ts">
import {ref} from 'vue'
// 引入数据
import { data } from '../list.json'
// 引入类型
import { Item, RootObject } from '../datatype'

// 点击事件
const toDetail = (item: Item) => {

}
</script>

<style lang="less" scoped>
.table {
    width: 400px;
}
</style>

1.3 编写详情组件

在 components 目录下创建 Detail.vue 组件,用于显示产品的详情信息。

<template>
    <h3>产品详情</h3>
    <ul>
        <li>编号:</li>
        <li>名称:</li>
        <li>价格:</li>
    </ul>
</template>

<script setup lang="ts">
import {ref} from 'vue'

</script>

<style scoped>

</style>

1.4 配置详情组件的路由

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        component: () => import('../components/Product.vue'),
    },
    {
        path: '/detail',
        component: () => import('../components/Detail.vue')
    }
]

1.5 query传参

1.5.1 完善产品列表的点击事件
// 引入路由对象
import { useRouter } from 'vue-router'

const router = useRouter()

// 点击事件
const toDetail = (item: Item) => {
    router.push({
        path: '/detail',
        query: item,
    })
}

此时数据就可以成功的进行传递了。但是是在浏览器的地址栏中显示的。

1.5.2 接收参数

在详情组件中来接收从产品列表中传递过来的数据。

<template>
    <h3>产品详情</h3>
    <ul>
        <li>编号:{{ route.query.id }}</li>
        <li>名称:{{ route.query.name }}</li>
        <li>价格:{{ route.query.price }}</li>
    </ul>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
</script>

1.6 params传参

1.6.1 传递参数

我们修改 Product.vue 组件中点击事件中编程导航。

// 点击事件
const toDetail = (item: Item | RouteParamValueRaw | string) => {
    router.push({
        //path: '/detail',
        //query: item,
        name: 'Detail',
        params: item,
    })
}

注意:要使用 params 来传参时,需要使用命令路由。

1.6.2 接收参数

修改详情组件,来接收参数

<template>
    <h3>产品详情</h3>
    <ul>
        <li>编号:{{ route.params.id }}</li>
        <li>名称:{{ route.params.name }}</li>
        <li>价格:{{ route.params.price }}</li>
    </ul>
</template>

<script setup lang="ts">
import { useRoute } from 'vue-router'
const route = useRoute()
</script>

1.7 动态路由传参

很多时候,我们传递的参数不需要把整个对象都以参数的方式来进行传递,而只传递 id,因为 id 是唯一的,不会重复。
大部分情况下,地址栏的信息都是相同的,唯一不同的就可能是 id 这值了,这时我们就可以把这个 id 值设置为动态参数进行传递。
可以在路由中使用冒号(:)来表示,当一个路由被匹配时,它的 params 的值就会将在组件中显示。

1.7.1 修改路由

修改路由配置文件 router/index.ts

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        component: () => import('../components/Product.vue'),
    },
    {
        path: '/detail/:id', // 动态路由
        name: 'Detail',
        component: () => import('../components/Detail.vue')
    }
]
1.7.2 传递参数

修改 Product.vue 组件中点击情况的事件代码:

const toDetail = (item: Item) => {
    router.push({
        name: 'Detail',
        params: {
            id: item.id
        }
    })
}
1.7.3 接收参数

修改 Detail.vue 组件,代码如下:

<template>
    <h3>产品详情</h3>
    <ul>
        <!-- 接收动态参数 -->
        <li>编号:{{ item.id }}</li>
        <li>名称:{{ item.name }}</li>
        <li>价格:{{ item.price }}</li>
    </ul>
    <button @click="router.back()">返回</button>
</template>

<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'
import { data } from '../list.json'

const route = useRoute()
const router = useRouter()
// 在 JSON 数据中查询传递过来的 id 对象的产品
const item = data.find(v => v.id === Number(route.params.id))
</script>

2. 嵌套路由

2.1 环境准备

我们在 components 目录下新建一个 Footer.vue 组件

<template>
    <h3>我是父路由</h3>
</template>

<script setup lang="ts">
</script>

<style scoped>
</style>

2.2 定义路由

在 router/index.ts 文件中添加父路由配置。

const routes: Array<RouteRecordRaw> = [
    {
        path: '/',
        component: () => import('../components/Product.vue'),
    },
    {
        path: '/detail/:id', // 动态路由
        name: 'Detail',
        component: () => import('../components/Detail.vue')
    },
    {
        path: '/footer',
        component: () => import('../components/Footer.vue')
    }
]

2.3 创建子组件

在 components 目录下创建 Login.vue 和 Register.vue 组件。
Login.vue

<template>
    <div class="container">
        <h3>Login</h3>
    </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.container {
    width: 100%;
    height: 100%;
    background-color: #0a53be;
    color: #FFFFFF;
}
</style>

Register.vue

<template>
    <div class="container">
        <h3>Register</h3>
    </div>
</template>

<script setup lang="ts">
</script>

<style scoped>
.container {
    width: 100%;
    height: 100%;
    background-color: #0f5132;
    color: #FFFFFF;
}
</style>

2.4 配置子路由

我们给 Footer 父组件路由两个子路由。

    {
        path: '/footer',
        component: () => import('../components/Footer.vue'),
        // 配置子路由——嵌套路由
        children: [
            {
                path: 'login',
                component: () => import('../components/Login.vue'),
            },
            {
                path: 'register',
                component: () => import('../components/Register.vue'),
            },
        ]
    }

2.5 在根组件中添加链接

App.vue

<template>
    <router-link to="/">产品列表</router-link> | <router-link to="/footer">有账号?</router-link>
    <hr>
    <router-view></router-view>
</template>

2.6 修改Footer.vue组件

在这个组件中添加 <router-view>来显示子组件,同时指定链接地址。

<template>
    <h3>我是父路由</h3>
    <router-link to="/footer/login">登录</router-link> | <router-link to="/footer/register">注册</router-link>
    <hr>
    <router-view></router-view>
</template>
<script setup lang="ts">
</script>

3. 命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。

3.1 环境准备

我们在 components 目录下新建 A.vue、B.vue、C.vue 和 Root.vue 四个组件。
A.vue

<template>
    <h3>A组件</h3>
</template>
<script setup lang="ts">
</script>

B.vue

<template>
    <h3>B组件</h3>
</template>
<script setup lang="ts">
</script>

C.vue

<template>
    <h3>C组件</h3>
</template>
<script setup lang="ts">
</script>

Root.vue

<template>
    <h3>Root组件</h3>
</template>
<script setup lang="ts">
</script>

3.2 定义路由

在 router/index.ts 文件中添加上面四个组件的路由配置。

    {
        path: '/root',
        component: () => import('../components/Root.vue'),
        children: [
            {
                path: 'user1',
                components: {
                    default: () => import('../components/A.vue'), // 默认视图
                }
            },{
                path: 'user2',
                components: {
                    bb: () => import('../components/B.vue'), // 命名视图
                    cc: () => import('../components/C.vue'), // 命名视图
                },
            }
        ]
    },

3.3 使用视图

在 Root.vue 组件中来使用命名视图,需要给 <router-view></router-view> 标签指定 name 属性。

<template>
    <h3>Root组件</h3>

    <router-link to="/root/user1">user1</router-link> |
    <router-link to="/root/user2">user2</router-link>
    <hr>

    <!-- 显示默认视图 -->
    <router-view></router-view>
    <router-view name="bb"></router-view>
    <router-view name="cc"></router-view>
</template>

<script setup lang="ts">
</script>

4. 重定向和别名

4.1 重定向

重定向也是通过 routes 配置来完成,需要使用 redirect 来实现。可以通过以下三种方式来实现重定向。

4.1.1 字符串
    {
        path: '/root',
        redirect: '/root/user1', // 重定向
        component: () => import('../components/Root.vue'),
        children: [
            {
                path: 'user1',
                components: {
                    default: () => import('../components/A.vue'), // 默认视图
                }
            },{
                path: 'user2',
                components: {
                    bb: () => import('../components/B.vue'), // 命名视图
                    cc: () => import('../components/C.vue'), // 命名视图
                },
            }
        ]
    },

通过指定 redirect 属性来进行重定向的配置。

4.1.2 对象

重定向还可以是一个对象,动态返回重定向目标:

    {
        path: '/root',
        //redirect: '/root/user1', // 重定向——字符串
        redirect: {
            //path: '/root/user1',
            name: 'user1',
        },
        component: () => import('../components/Root.vue'),
        children: [
            {
                path: 'user1',
                name: 'user1',
                components: {
                    default: () => import('../components/A.vue'), // 默认视图
                }
            },{
                path: 'user2',
                components: {
                    bb: () => import('../components/B.vue'), // 命名视图
                    cc: () => import('../components/C.vue'), // 命名视图
                },
            }
        ]
    },

使用对象时,可以使用 path,也可以使用 name 来进行命名路由重定向配置。

4.1.3 函数
   {
        path: '/root',
        //redirect: '/root/user1', // 重定向——字符串
        /*redirect: { // 重定向——对象
            //path: '/root/user1',
            name: 'user1',
        },*/
        redirect: () => { // 重定向——函数
            return {
                path: '/root/user1',
                query: {
                    name: '天子'
                }
            }
        },
        component: () => import('../components/Root.vue'),
        children: [
            {
                path: 'user1',
                name: 'user1',
                components: {
                    default: () => import('../components/A.vue'), // 默认视图
                }
            },{
                path: 'user2',
                components: {
                    bb: () => import('../components/B.vue'), // 命名视图
                    cc: () => import('../components/C.vue'), // 命名视图
                },
            }
        ]
    },

使用函数配置的重定向,还可以传递参数。

4.2 别名

/ 别名为 /root,意味着当用户访问 /root 时,URL 仍然是 /user,但会被匹配为用户正在访问 /

   {
        path: '/root',
        //redirect: '/root/user1', // 重定向——字符串
        /*redirect: { // 重定向——对象
            //path: '/root/user1',
            name: 'user1',
        },*/
        redirect: () => { // 重定向——函数
            return {
                path: '/root/user1',
                query: {
                    name: '天子'
                }
            }
        },
        alias: ['/root', '/root2', '/root3'], // 别名
        component: () => import('../components/Root.vue'),
        children: [
            {
                path: 'user1',
                name: 'user1',
                components: {
                    default: () => import('../components/A.vue'), // 默认视图
                }
            },{
                path: 'user2',
                components: {
                    bb: () => import('../components/B.vue'), // 命名视图
                    cc: () => import('../components/C.vue'), // 命名视图
                },
            }
        ]
    },

使用别名:

<template>
    <router-link to="/">产品列表</router-link> | <router-link to="/footer">嵌套路由</router-link> |
    <router-link to="/root">命名视图</router-link> | <router-link to="/root2">命名视图——别名</router-link>
    <hr>
    <router-view></router-view>
</template>

使用别名和使用 path 路由的效果一样。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值