第五章-嵌套路由

120 阅读2分钟

嵌套路由

嵌套路由就是父子关系或者是更深层次的爷孙关系...

嵌套路由的结构如下:

image.png

根据上图可以看出,每一个路由配置项都有一个children属性, 子路由配置项是在children属性中进行声明的,children是一个数组类型,也就是说可以有多个子路由,当然子路由下面还可以有多个子路由。

我们都知道,URL地址栏中的路由地址对应的组件是通过router-view组件渲染的。就是说当我输入一个存在的路由地址后,这个路由地址所对应的组件就会被渲染在router-view所在的位置。

那么,这种嵌套的路由是怎么进行渲染的呢?我们来尝试一下:

  1. 只在App.vue组件中放置一个router-view组件:

    App.vue:

    <template>
      <router-view></router-view>
    </template>
    
    <script setup lang="ts"></script>
    
    <style lang="scss" scoped>
    a {
      margin: 0 10px;
    }
    </style>
    

    list.vue:

    <template>
      <div>
        <table border cellspacing="0">
          <thead>
            <tr>
              <th>商品id</th>
              <th>商品名称</th>
              <th>商品价格</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="product in data" :key="product.id">
              <td>{{ product.id }}</td>
              <td>{{ product.name }}</td>
              <td>{{ product.price }}</td>
              <td><button @click="toDetail(product)">详情</button></td>
            </tr>
          </tbody>
        </table>
      </div>
    </template>
    
    <script setup lang="ts">
        import { useRouter } from 'vue-router'
        import { data } from '@/assets/data.json'
    
        const router = useRouter()
    
        interface Product extends Record<string, any> {
          id: number
          name: string
          price: number
        }
    
        const toDetail = (product: Product) => {
          router.push({
            name: 'detail',
            params: product,
          })
        }
        </script>
    
        <style scoped>
        table {
          border-collapse: collapse;
        }
        </style>
    

    detail.vue:

        <template>
          <div>
            <div>
              <span>商品名称:</span>
              <span>{{ name }}</span>
            </div>
            <div>
              <span>商品价格:</span>
              <span>{{ price }}</span>
            </div>
            <div>
              <span>商品id:</span>
              <span>{{ id }}</span>
            </div>
          </div>
        </template>
    
        <script setup lang="ts">
        import { useRoute } from 'vue-router'
        const route = useRoute()
        console.log(route.params)
        const { id, name, price } = route.params
        </script>
    
        <style lang="scss" scoped></style>
    

    路由结构:

      const routes: RouteRecordRaw[] = [
        {
          path: '/', // router-link组件默认展示path为'/'对应的组件
          component: () => import('@/views/list.vue'),
          children: [
            {
              path: 'detail/:id?/:name?/:price?', // router-view组件默认展示path为'/'对应的组件
              name: 'detail',
              component: () => import('@/views/detail.vue'),
            },
          ],
        },
      ]
    

    image.png 可以看见,我们虽然在URL地址栏中输入了子路由地址detail,却没有渲染出来对应的组件。

  2. 给父路由对应的组件添加router-view组件:

    <template>
      <div>
        <table border cellspacing="0">
          <thead>
            <tr>
              <th>商品id</th>
              <th>商品名称</th>
              <th>商品价格</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="product in data" :key="product.id">
              <td>{{ product.id }}</td>
              <td>{{ product.name }}</td>
              <td>{{ product.price }}</td>
              <td><button @click="toDetail(product)">详情</button></td>
            </tr>
          </tbody>
        </table>
        <!-- 路由视图组件 -->
        <router-view></router-view>
      </div>
    </template>
    

    image.png 在父路由模板中添加router-view后,我们发现子路由对应的组件就正常的渲染出来了。

由此可以得出一个结论:嵌套路由中,父路由对应的组件内必须添加router-view组件,当URL地址跳转到子路由时才能够正常的渲染出子路由对应的组件