1. 程式人生 > >VueRouter爬坑第三篇-巢狀路由

VueRouter爬坑第三篇-巢狀路由


VueRouter系列的文章示例編寫時,專案是使用vue-cli腳手架搭建。

專案搭建的步驟和專案目錄專門寫了一篇文章:點選這裡進行傳送

後續VueRouter系列的文章的示例編寫均基於該專案環境。


 VueRouter系列文章連結

  《VueRouter爬坑第一篇》-簡單實踐

  《VueRouter爬坑第二篇》-動態路由

  《VueRouter爬坑第三篇》-巢狀路由


 閱讀目錄

一.前言-從需求出發

二.需求實現

  1.選單

  2.產品列表

  3.產品詳情

三.主角-巢狀路由

四.總結


一.前言-從需求出發

  假設我們有這樣一個需求和介面佈局:   

 

  左邊是選單區域,點選選單欄的【產品】,右邊內容區上面顯示產品列表,點選某個產品名稱下面顯示產品詳情。

  emmmm,突然想想這個需求造的有點雞肋,但是也是為了從一個問題出發好去理解接下來的內容。

 

  仔細想一想,大致的思路如下:

  1.選單是公共內容,我們放入App.vue元件中實現邏輯和頁面佈局,點選選單欄的選單名稱使用<router-link>和<router-view>去顯示產品列表。

  2.產品列表需要新建元件:Content.vue。該元件中編寫產品列表的程式碼,點選產品名稱展示產品詳情使用<router-link>和<router-view>去顯示產品詳情。

  3.產品詳情需要新建元件:ProductDetail.vue元件。該元件中,展示相應的產品詳情。

 

  前面兩篇VueRouter文章中的主要知識點就是url對映元件和動態路由,接下來我們結合前兩篇VueRouter文章的知識點,按照這個思路去實現需求。

  感覺已經摩拳擦掌迫不及待想去實現這個小需求了 let's go go go

      

二.需求實現

1.選單實現-App元件

E:\MyStudy\test\VueDemo\src\App.vue

<template>
  <div id="app">
    <!-- 選單  -->
    <ul>
      <li v-for='(item,index) in menuList' v-bind:key='index' >
          <router-link v-bind:to='item.url'>{{item.name}}</router-link>
      </li>
    </ul>
    <!-- 內容區 -->
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      menuList: [
        {
          url: 'index',
          name: '首頁'
        },{
          url: 'products',
          name: '產品'
        }
      ]
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
ul {
    display: inline-block;
    width: 100px;
    border: 1px solid #ddd;
    padding: 100px 0px 100px 20px;
    position: fixed;
    top: -10px;
    bottom: 0px;
}
a{
  text-decoration: none;
}
</style>  

  App元件主要就是三點:

    1.迴圈資料menuList展示選單列表,並且每個選單需要使用<router-link>新增連結

    2.使用<router-view>告訴vue-router把菜單鏈接匹配到的元件渲染到那個位置

    3.選單的佈局:使用fiex定位將選單固定在瀏覽器左邊,同時設定top和bottom使選單垂直方向上鋪滿瀏覽器

 

  我們看下App元件的效果:   

2.產品列表-Content元件

  我們需要新建一個元件來編寫產品列表的程式碼:Content.vue

E:\MyStudy\test\VueDemo\src\components\Content.vue

<template>
    <div class='productContent'> 
        <div class="productList">
            <!-- 產品列表  -->
            <h1>產品列表</h1>
            <p v-for="(item,index) in productsList" v-bind:key='index'> 
                <router-link v-bind:to="item.url">{{item.name}}</router-link>
            </p> 
        </div>
        <!-- 產品詳情 -->
        <router-view />
    </div>
</template>
<script>
export default {
    name: 'Content',
    data() {
        return {
            productsList: [
                {
                    url: '/productDetail/1',
                    name: '產品1'
                },{
                    url: '/productDetail/2',
                    name: '產品2'
                }
            ]
        }
    }

}
</script>
<style scoped>
    .productContent{
        margin-left: 150px;
    }
    .productList{
        border:1px solid #ddd;
        margin: 10px;
    }
</style>

 

  Content元件主要就是三點:

    1.迴圈資料productsList展示產品列表,並且每個產品名稱使用<router-link>新增連結

    2.使用<router-view>告訴vue-router把產品名稱匹配到的元件渲染到哪個位置

    3.內容頁的佈局:需要設定左邊距 margin-left:150px,這樣就不會和選單產生覆蓋。

 

  接著我們配置選單中的【產品】連結渲染到產品列表的路由。

E:\MyStudy\test\VueDemo\src\router\router.js

import Vue from "vue"
import Router from "vue-router"
Vue.use(Router)

// 引入路由需要對映的元件
import Content from '@/components/Content.vue'
const routes = [
    {
        path: '/products',  // 具體的路由
        component: Content  // 路由對映的元件
    },
]

const router = new Router({
    routes: routes
})

export default router

 

  現在在看下效果:

  

 

  可以看到點選選單欄的【產品】已經可以成功的渲染出Content.vue元件並展示產品列表了。

3.產品詳情-ProductDetail元件

  新建元件:ProductDetail.vue

E:\MyStudy\test\VueDemo\src\components\Content.vue

<template>
    <div class='productDetail'> 
        <p>
            名稱:產品{{$route.params.id}}
        </p>
        <p>
            詳細資訊:這是產品{{$route.params.id}}的詳細資訊......
        </p>
    </div>
</template>
<script>
export default {
    name: 'ProductDetail',
}

</script>
<style scoped>
.productDetail{
    border:1px solid #ddd;
    margin-left: 150px;
}
</style>

 

  產品詳情元件比較簡單,主要有下面幾點:

  1.點選不同的產品名稱需要渲染到產品詳情元件,因此產品名稱到產品詳情的路由會採用動態路由去實現。

  2.使用了$route.parmas獲取了動態路由中的引數並在模板中展示。

 

  接著就需要配置從產品名稱到產品詳情的動態路由了

E:\MyStudy\test\VueDemo\src\router\router.js

import Vue from "vue"
import Router from "vue-router"
Vue.use(Router)

// 引入路由需要對映的元件
import Content from '@/components/Content.vue'
import ProductDetail from '@/components/ProductDetail.vue'
const routes = [
    {
        path: '/products',  // 具體的路由
        component: Content, // 路由對映的元件
    },
    {
        path: '/productDetail/:id', //這裡使用了動態路由
        component: ProductDetail    // 路由對映的元件
    }
]

const router = new Router({
    routes: routes
})

export default router

 

   程式碼完成,大概能想到的結果就是:當點選產品名稱時,產品列表下方就會出現產品詳情。

      那麼我懷著雞凍的心情看下了結果:

  

  emmmmmm,跟我們想要的效果咋不一樣:產品詳情覆蓋了產品列表。但是在Content.vue頁面,我們明明使用<router-view>已經告知了產品詳情元件應該渲染的位置。

    

 

  到這裡呢,我們這節的主角巢狀路由就要登場了。

     

三.主角-巢狀路由

  在回到我們的需求和我們前面實現的程式碼,App元件、Content元件和ProductDetail元件這三者的關係是一層一層往下巢狀並且結合vue-router、router-view顯示的:

    

   因為元件之間是這樣巢狀的關係,所以對應路由也需要按照這個結構去巢狀。

   那路由巢狀呢,就是在單條路由配置中新增children選項,children選項就是和routes一樣的路由配置陣列,同時還支援多次的巢狀。

  話不多少,我們將產品詳情這條路由巢狀到產品列表路由配置下。

  備註:App元件是根元件,所有的元件都是巢狀在該元件下的,預設路由也都是巢狀在根元件下。

E:\MyStudy\test\VueDemo\src\router\router.js

 

import Vue from "vue"
import Router from "vue-router"
Vue.use(Router)

// 引入路由需要對映的元件
import Content from '@/components/Content.vue'
import ProductDetail from '@/components/ProductDetail.vue'
const routes = [
    {
        path: '/products',  // 具體的路由
        component: Content, // 路由對映的元件
        // 產品詳情需要使用路由巢狀才能實現
        children:[
            {
                path: '/productDetail/:id', //這裡使用了動態路由
                component: ProductDetail    // 路由對映的元件
            }
        ]
    }   
]

const router = new Router({
    routes: routes
})

export default router

 

 

  這裡還需要把ProductDetail.vue元件中的介面佈局修改一下:

.productDetail{
    border:1px solid #ddd;
    margin: 10px;
}

 

  現在就沒啥問題了,我們在看下效果:

 

  現在這個效果就是我們想要的效果了。是不是也很簡單呢 hahahahaha

        

四.總結

  

1.是否需要使用巢狀路由是要根據元件之前是否存在巢狀關係。

2.路由巢狀就是在單條路由配置中新增children選項,children選項就是和routes一樣的路由配置陣列,同時還支援多次的巢狀。