/src/assets/a.json

{
    "data": [
        {
            "id":1,
            "name": "hello",
            "price": 20
        },
        {
            "id":2,
            "name": "vite",
            "price": 30
        },
        {
            "id":3,
            "name": "pinia",
            "price": 14
        }
    ]
}

vscode插件: JSON to TS

json文件的ts代码如何生成:

1、选中json文件的内容

2、windows: ctrl+shift+alt+s

mac: control+shift+option+s

得到的内容:

/src/router/index.ts

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

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

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

export default router;

1、query传参: url会带参数

/src/App.vue

<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";

const router = useRouter();

type Datum = {
  id: number;
  name: string;
  price: number;
}

const toAction = (item: Datum) => {

  // query传参,和path搭配或者和name搭配,都可以,二选一

  // 和path搭配
  // router.push({
  //  path: '/detail',
  //  query: item
  // });

  // 和name搭配
  router.push({
    name: 'detail',
    query: item
  });
}

</script>

<template>
  <div class="page">
    <table cellspacing="0" border="1">
      <thead>
        <tr>
          <th>姓名</th>
          <th>年龄</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in data" :key="item.name">
          <td>{{ item.name }}</td>
          <td>{{ item.price }}元</td>
          <td>
            <button @click="toAction(item)">点击一下</button>
          </td>
        </tr>
      </tbody>

    </table>
  </div>
  <router-view></router-view>
</template>

<style>
html,
body,
#app,
.page {
  width: 100%;
  height: 100%;
}

.page {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

a {
  margin-left: 20px;
}

td {
  padding: 10px;
}

tbody tr td {
  padding: 20px;
}
</style>

/src/components/Detail.vue

<script setup lang="ts">

import { useRoute, useRouter } from "vue-router";

// 当前路由的信息
const route = useRoute();

// vue路由对象
const router = useRouter();

</script>
<template>
    <div class="page">
        <h1>detail</h1>
        <!-- router.back():🔙返回到上一页 -->
        <button @click="router.back();">回退</button>
        <!-- 通过route.query获取url的参数值,这种方式传参,刷新页面数据不会消失 -->
        <!-- 举例url:http://localhost:5174/#/detail?id=1&name=hello&price=20 -->
        <p>id:{{ route.query.id }}</p>
        <p>姓名:{{ route.query.name }}</p>
        <p>价格:{{ route.query.price }}</p>
    </div>
</template>
<style scoped>
.page {
    background: pink;
}
</style>

2、params传参+动态路由传参: url会带参数

/src/router/index.ts改造成下面这样:

{
    // 动态路由
    path: '/detail/:id',
    name: 'detail',
    component: () => import('../components/Detail.vue'),
}

/src/App.vue的<script>部分改造成下面这样:

<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";

const router = useRouter();

type Datum = {
  id: number;
  name: string;
  price: number;
}

const toAction = (item: Datum) => {

  // params传参
  router.push({
    name: 'detail',
    params: {
      id: item.id
    }
  });

}

</script>

/src/components/Detail.vue改造成下面这样:

<script setup lang="ts">

import { data } from "../assets/a.json";
import { useRoute, useRouter } from "vue-router";

const route = useRoute();

const router = useRouter();

// 通过route.params.id找到data里符合的数据
const itemData = data.find(item => item.id === Number(route.params.id));

</script>
<template>
    <div class="page">
        <h1>detail</h1>
        <button @click="router.back();">回退</button>
        <!-- 得到的url是这样的,3是id值:http://localhost:5174/#/detail/3 -->
        <!-- 刷新页面数据不会消失 -->
        <!-- 加❓问号是因为会提示:ts对象可能为未定义ts(18048) -->
        <p>id:{{ itemData?.id }}</p>
        <p>姓名:{{ itemData?.name }}</p>
        <p>价格:{{ itemData?.price }}</p>
    </div>
</template>
<style scoped>
.page {
    background: pink;
}
</style>

3、params传参: 如果没有和动态路由一起使用,详情页❌不可以通过route.params来获取参数值了

上图是Vue Router官网编程式导航的name和params的组合传参,如果没有和动态路由一起使用,详情页通过route.params来获取参数值,控制台会报警告⚠️,并且详情页得到的route.params是个空对象{}。

vue-router.js?v=5791c9af:42 [Vue Router warn]: Discarded invalid param(s) "id", "name", "price" when navigating. See https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22 for more details.

这是于2022年8月22日4.1.4版本的路由开始设置的,这样做的原因是“刷新页面获取到的参数会丢失”,详见https://github.com/vuejs/router/blob/main/packages/router/CHANGELOG.md#414-2022-08-22

修改方案:见路由传参的其他方式

4、可以用History API的state传参: url不会带参数

/src/App.vue的<script>部分改造成下面这样:

<script setup lang="ts">
import { data } from "./assets/a.json";
import { useRouter } from "vue-router";

const router = useRouter();

type Datum = {
  id: number;
  name: string;
  price: number;
}

const toAction = (item: Datum) => {

 // history api的state传参
  router.push({
    name: 'detail',
    state: item
  });
  
}
</script>

/src/components/Detail.vue改造成下面这样:

<script setup lang="ts">

import { useRouter } from "vue-router";

const router = useRouter();

const state = history.state;

</script>
<template>
    <div class="page">
        <h1>detail</h1>
        <button @click="router.back();">回退</button>
        <!-- 通过History API的state获取参数值,刷新页面数据不会消失 -->
        <p>id:{{ state.id }}</p>
        <p>姓名:{{ state.name }}</p>
        <p>价格:{{ state.price }}</p>
    </div>
</template>
<style scoped>
.page {
    background: pink;
}
</style>

5、将参数作为一个新属性传递给to.meta

这是已知的瞬间状态,并且由于它在导航守卫中,因此在重新加载页面时将被保留

router.beforeEach(async to => {
  if (to.meta.shouldFetch) {
    // name `data` whatever you want
    to.meta.data = await fetchSomething()
  }
})
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐