使用Vue Router 及配置路由文件  以上範例,你可以看到它們都是停留在index的網址上, 但是,會因為我們在#後面所接入的內容不同,來呈現不同元件的內容。 像上面圖片是#/user,所以,此時是呈現 user 元件。 像下面圖片是#/product,所以,此時是呈現 product 元件。
故本節是紀錄怎麼建立Vue Router
Router會包含幾個檔案
首先,進入點 包含它會注入src資料夾中的元件檔和其他的component檔案。
第二,新增路由的配置檔案 這個配置檔案會決定在哪個路由中呈現哪個元件檔案。 那它執行的路徑會在router/index.js 中。
第三,分頁內容
Vue Components 就是一些元件的檔案,例如專案檔中的Hellowolrd.vue檔。
接下來,介紹安裝vue 的router步驟 step1. 先輸入 npm install vue-router --save 指令
step2. 在src資料夾中,新建一個叫router的資料夾 在router下再新增一個叫index.js的檔案,這個檔案就是要放整個路由的配置檔。
step3. 在index.js檔案中輸入import Vue from 'vue'import VueRouter from 'vue-router'
以上這兩行呢,是將官方提供的元件給引入進來。
接下來,在這兩行之後就是引入我們自己的元件囉。import Home from '@/component/HelloWorld' 引入在src資料夾中的HelloWorld元件檔,並將它命名為Home
step4. 在你引入完官方元件 和你自己的元件檔之後, 就是要輸入啟用的指令, 那你就在同一個index.js檔案中,在引入程式碼的後方輸入Vue.use(VueRouter) ex:
1 2 3 4 5 6 7 import Vue from 'vue' import VueRouter from 'vue-router' // 以上為官方提供的元件 import Home from '@/component/HelloWorld' Vue.use(VueRouter)  // 啟用指令 
 
 
step5. 因為這個檔案,我們必須匯出給entry使用, 所以,我們要再加上以下的程式碼
1 2 3 4 5 6 7 8 9 10 import Vue from 'vue' import VueRouter from 'vue-router' // 以上為官方提供的元件 import Home from '@/components/HelloWorld' Vue.use(VueRouter) export default new VueRouter({ }); 
 
你可以看到我們在最下面,輸入了export的相關內容。
step6. 在main.js檔案中,匯入你的router檔案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ---main.js檔案--- // The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import axios from 'axios' import VueAxios from 'vue-axios' import router from './router'  // 匯入router檔案 Vue.use(VueAxios, axios) Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({   el: '#app',   components: { App },   template: '<App/>',   router,                          // 新增router屬性 }) 
 
你可以看到我們在main.js檔案中匯入了router檔案, 並在vue物件新增了一個router屬性
step7. 運行npm run dev 來執行vue的環境吧 此時,你運行http://localhost:8080  應該會發現你的網址後面新增了#,而這個#後面就是你的虛擬路由器
step8. 接著,你就去index.js中的export default new VueRouter內容新增以下的內容 ex:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import Vue from 'vue'; import VueRouter from 'vue-router'; // 以上為官方提供的元件 import Home from '@/components/HelloWorld' Vue.use(VueRouter); export default new VueRouter({     routes:[         {             name:'首頁',//元件呈現名稱             path:'/', //對應虛擬的路徑             component:Home , //它所對應的原件         }         ] }); 
 
step9. 接著你去App.vue檔案中的template部分, 新增以下的<router-view></router-view> 並把原本的<Helloworld>元件的部分註解掉
1 2 3 4 5 6 7 8 <template>   <div id="app">     <img src="./assets/logo.png">     <!--<HelloWorld/>-->     <router-view></router-view>     <button class="btn btn-danger">按鈕</button>     </div> </template> 
 
接著,你在畫面上應該是看不出來有啥差別,此時,你就打開vue開發者工具, 你去看App底下的HelloWolrd元件的標籤旁邊,應該就會跟著一個router-view的標籤喔。
接下來我們要新增另一個元件, step1. 接著,我們先偷懶在最外層的index.html引入bootstrap的CSS的CDN。
step2. 我們在components資料夾中,新增一個pages的資料夾 在這個pages資料夾中新增一個pages.vue的元件檔
step3. 我們去bootstrap中的card元件內容複製,並貼到pages.vue的template中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <template>   <div>     <div class="card" style="width: 18rem;">       <img src="" class="card-img-top" alt="...">       <div class="card-body">         <h5 class="card-title">Card title</h5>         <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>         <a href="#" class="btn btn-primary">Go somewhere</a>       </div>     </div>   </div> </template> <script> export default {   name: 'pages',   data () {     return{              }   } } </script> 
 
以上的內容你就可以看到,我們在pages中的template加入了card元件的內容。
注意,元件外面要再包一個div 老師建議,你在創任何元件的template的時候,它們的內容外面都要再包一層div, 是因為Vue 最外層的元素不能直接使用 vue 的指令。 ex:
1 2 3 <template>   <div v-for="..."></div> </template> 
 
像上面這樣,如果你直接對最外層使用v-for指令的話,就會出錯喔。
step4. 接著,你去index.js檔案裡面,新增引入pages元件的相關設定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from '@/components/HelloWorld' import Page from '@/components/pages/pages'  // 引入pages.vue元件 Vue.use(VueRouter); export default new VueRouter({   routes:[     {       name:'首頁',       path:'/index',        component:Home ,      },     { // 新增pages元件的相關設定       name:'分頁',       path:'/page',        component:Page ,     }        ] }); 
 
step5. 接著,你將你的vue的網址的#號後面,加入Page 即:http://localhost:8080/#/Page 
此時,你應該就可以看到在網頁上看到新增的 Page 元件的內容。
製作分頁的切換 接下來要接分頁的切換 step1. 首先我們先為 App.vue 元件檔引入 bootstrap 的 navbar 內容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ---App.vue 元件檔--- <template>   <div id="app">     <!--navbar開始-->     <nav class="navbar navbar-expand-lg navbar-light bg-light">       <div class="container-fluid">         <a class="navbar-brand" href="#">Navbar</a>         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">           <span class="navbar-toggler-icon"></span>         </button>         <div class="collapse navbar-collapse" id="navbarSupportedContent">           <ul class="navbar-nav me-auto mb-2 mb-lg-0">             <li class="nav-item">               <a class="nav-link active" href="#">Home</a>             </li>             <li class="nav-item">               <a class="nav-link" href="#">Page</a>             </li>           </ul>         </div>       </div>     </nav>     <!--navbar結束-->     <img src="./assets/logo.png">     <router-view></router-view>     <button class="btn btn-danger">按鈕</button>     </div> </template> 
 
你可以看到,我們在template中,加入了navbar樣式,此時,你刷新網頁後, 應該就會出現navbar的樣式了。
step2. 接著,我們修改在App.vue的檔案中,連動到Home和Page的a標籤,將其改成router-link標籤,並在這些標籤內分別加入to="/index"和to="/Page"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ---APP.vue檔案--- <template>   <div id="app">     <nav class="navbar navbar-expand-lg navbar-light bg-light">       <div class="container-fluid">         <a class="navbar-brand" href="#">Navbar</a>         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">           <span class="navbar-toggler-icon"></span>         </button>         <div class="collapse navbar-collapse" id="navbarSupportedContent">           <ul class="navbar-nav me-auto mb-2 mb-lg-0">             <li class="nav-item">               <router-link class="nav-link active" to="/index">Home</router-link>  // 轉換到 Home 的按鈕             </li>             <li class="nav-item">               <router-link class="nav-link" to="/Page">Page</router-link>          // 轉換到 Page 的按鈕             </li>           </ul>         </div>       </div>     </nav>     <img src="./assets/logo.png">     <router-view></router-view>     <button class="btn btn-danger">按鈕</button>     </div> </template> 
 
此時,你點擊 Home 和 Page 按鈕的時候,應該就跳轉到 Home 或 Page 的頁面囉,所以,在 index.js 中,各物件的 path 屬性,就是用在跳轉分頁路徑做使用。
除了to以外,還有其他跳轉頁面的方法 就是使用在index.js中,你為那些元件檔所加入的name的屬性名稱。 所以,就將App.vue中的navbar做以下的修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <template>   <div id="app">     <nav class="navbar navbar-expand-lg navbar-light bg-light">       <div class="container-fluid">         <a class="navbar-brand" href="#">Navbar</a>         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">           <span class="navbar-toggler-icon"></span>         </button>         <div class="collapse navbar-collapse" id="navbarSupportedContent">           <ul class="navbar-nav me-auto mb-2 mb-lg-0">             <li class="nav-item">               <router-link class="nav-link active" :to="{name:'首頁'}">Home</router-link>  // 換成name的屬性名稱             </li>             <li class="nav-item">               <router-link class="nav-link" to="/Page">Page</router-link>             </li>           </ul>         </div>       </div>     </nav>     <img src="./assets/logo.png">     <router-view></router-view>     <button class="btn btn-danger">按鈕</button>     </div> </template> 
 
你可以看到,在首頁的router-link標籤部分,我們把to的屬性用v-bind去動態綁定name屬性,並將這個屬性名稱改成這個元件的name的名稱,如此,就可以跟原本的to達成一樣的切換頁面效果囉。
製作巢狀路由頁面 首先,我們在pages同一層的目錄中,分別建立三個元件檔child.vue, child2.vue, child3.vue 接著,你要特別注意一點, 在這三個元件檔child.vue, child2.vue, child3.vue中的card元件是不包含最外層的card。 那在pages檔案中,就只有保留最外層的.card的div, 因為,我們希望透過切換child.vue, child2.vue, child3.vue 來變換pages.vue中,.card裡面的內容。 所以,要改成像下面這樣 即:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ---child.vue檔案--- <template>   <div>     <img src="" class="card-img-top" alt="...">     <div class="card-body">       <h5 class="card-title">Card 1</h5>       <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>       <a href="#" class="btn btn-primary">Go somewhere</a>     </div>   </div> </template> ---pages.vue檔案--- <template>   <div>     <div class="card" style="width: 18rem;">       <router-view><router-view>     </div>   </div> </template> 
 
你可以看到,我們在pages的元件裡面,在想要替換內容的部分,加入<router-view></router-view>,藉此,透過router的方式,來變換card.vue, card2.vue, card3.vue的內容。
step2. 我們回到index.js檔案中, 我們先將child.vue, child2.vue, child3.vue 這三個元件檔引入到index.js檔案裡面。
1 2 3 import child_1 from '@/components/pages/child'  import child_2 from '@/components/pages/child2'  import child_3 from '@/components/pages/child3'  
 
step3. 在pages的元件內容中,加入children的屬性,並把child.vue, child2.vue, child3.vue的路徑相關設定塞進去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 export default new VueRouter({   routes:[     {       name:'首頁',       path:'/index',       component:Home     },     {       name:'分頁',       path:'/page',       component:Page,       children:[  // 插入巢狀路由內容         {           name:'child1',           path:'',           component:child_1            },         {           name:'child2',           path:'child2',           component:child_2              },         {           name:'child3',           path:'child3',           component:child_3             }       ]     }        ] }); 
 
你可以看到,我們對Page又加了一個children屬性,並在裡面加了要引入的元件。 而你可以特別注意到,我們沒有對child1的path設值,這是因為,我們把它當為Page內容的預設值,也就是說Page元件<router-view>裡面的內容,預設會是card1的內容。
step4. 製作切換card1, card2, card3的內容 首先,我們就到pages.vue檔案中,加入<router-link></router-link>的元件,並透過to的方式來切換它們之間的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <template>   <div>     <router-link to="/page">卡片一</router-link>     <router-link to="/page/child2">卡片二</router-link>     <router-link to="/page/child3">卡片三</router-link>     <div class="card" style="width: 18rem;">       <router-view></router-view>     </div>   </div> </template> <script> export default {   name: 'HelloWorld',   data () {     return{     }   } } </script> 
 
你可以看到,我們新增了三個router-link,並在這些標籤裡面,加入了to屬性,也就是它要跑去哪個頁面的路徑。
注意,元件檔絕對路徑的引用 你看上面router-link是直接用/page/child2 ,是用絕對路徑來引用元件檔。 不要用相對路徑來引入元件,即page/child2,這樣容易造成路徑檔案引用錯誤,要特別小心。
使用動態路由切換頁面 Ajax 結果 這個動態路由的功用就在於 透過動態路由來載入不同的內容,並將這些內容加到固定的版型中。
加入動態路由 首先,我們先到index.js檔案中,對card3的元件內容的path屬性做調整
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 export default new VueRouter({   routes:[     {       name:'首頁',       path:'/index',       component:Home     },     {       name:'分頁',       path:'/page',       component:Page,       children:[         {           name:'child1',           path:'',           component:child_1          },         {           name:'child2',           path:'child2',           component:child_2              },         {           name:'child3',           path:'child/:id',  // 動態路由           component:child_3         }       ]     }        ] }); 
 
接著,你去按頁面上卡片三的按鈕,此時,頁面應該是會失效的。 那你就把原本的卡片三路徑http://localhost:8080/#/page/child3  改成http://localhost:8080/#/page/child/ffff 
這個時候,頁面應該就會呈現 child3 的內容囉。
取得動態路由內容 step1. 我們先取得我們剛剛修改的動態路由的id。 你先去child3.vue的元件檔中,新增created的hook,並透過log來看看它的id是什麼
1 2 3 4 5 6 7 8 9 10 11 12 13 <script> export default {   name: 'HelloWorld',   data () {       return{       }   },   created:function(){       console.log(this.$route.params.id);  // 取得它的id內容   } } </script> 
 
透過以上的語法,我們可以在 child3.vue 元件創建的時候,取得該元件路由中的 id 屬性值。
搭配vue.axios的功能 那為什麼要取得這個router的id呢,因為,要把它跟axios一起使用。 以下內容為 child3.vue 加入 axios 來取得 api 的內容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ---child3.vue元件檔--- <script> export default {   name: 'HelloWorld',   data () {     return{     }   },   created:function(){     console.log(this.$route.params.id);     this.$http.get('https://randomuser.me/api/').then((response) => {       console.log(response)     })   } } </script> 
 
如此,就能取得api的結果。
那在這個random產出api的網址中,有一個seeds的功能,它可以產出固定api的內容。 那我們就可以藉由動態路由的方式,來存取同一份資料囉。 修改一下 child3.vue 的內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ---child3.vue元件檔--- <script> export default {   name: 'HelloWorld',   data () {     return{     }   },   created:function(){     var id = this.$route.params.id;     this.$http.get(`https://randomuser.me/api/?seed=${id}`).then((response) => {       console.log(response)     })   } } </script> 
 
你用以上的寫法,就可以藉由console.log中的data裡面的內容,在每一次頁面刷新的時候, 都是相同的喔。
命名路由,同一個路徑載入兩個頁面元件 假設在同一個畫面下,要執行兩個router-view。
在App.vue檔案中, 我們在新增的.container的裡面跟外面分別加入<router-view></router-view>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <template>   <div id="app">     <nav class="navbar navbar-expand-sm navbar-light bg-light">       <div class="container-fluid">         <a class="navbar-brand" href="#">Navbar</a>         <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">           <span class="navbar-toggler-icon"></span>         </button>         <div class="collapse navbar-collapse" id="navbarSupportedContent">           <ul class="navbar-nav me-auto mb-2 mb-lg-0">             <li class="nav-item">               <router-link class="nav-link active" :to="{name:'首頁'}">Home</router-link>             </li>             <li class="nav-item">               <router-link class="nav-link" to="/Page">Page</router-link>             </li>           </ul>         </div>       </div>     </nav>     <router-view name="menu"></router-view> // 新增 router-view     <div class="container">       <router-view></router-view>           // 新增 router-view     </div>     </div> </template> 
 
你可以看到在.container裡面有一個router-view,它是吃預設的樣式。 外層也有一個router-view,我們特別為它的name屬性命名為menu。
step2. 接著,我們在page.vue的同一層目錄中,新增另一個menu.vue的元件檔。 並且,我們將原本寫在App.vue的router-link內容,都移到menu.vue元件檔中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ---menu.vue元件檔--- <template>   <div>     <nav aria-label="breadcrumb">       <ol class="breadcrumb">         <li class="breadcrumb-item">           <router-link to="/page">卡片一</router-link>         </li>         <li class="breadcrumb-item">           <router-link to="/page/child2">卡片二</router-link>         </li>         <li class="breadcrumb-item active" aria-current="page">           <router-link to="/page/child3">卡片三</router-link>         </li>       </ol>     </nav>   </div> </template> <script> export default {   name: 'menu',   data () {     return{     }   } } </script> 
 
你可以看到,我們把那些router-link從page.vue檔案中,抓來menu.vue檔。 所以,此時,page.vue元件檔,只會剩下.card的部分。
step3. 接著,我們到index.js檔案中,去匯入剛剛新增的menu.vue元件檔 並在routes使用components,來同時匯入Page和menu這兩個元件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 import Vue from 'vue'; import VueRouter from 'vue-router'; import Home from '@/components/HelloWorld' import Page from '@/components/pages/pages' import child_1 from '@/components/pages/child'  import child_2 from '@/components/pages/child2'  import child_3 from '@/components/pages/child3'  import Menu from '@/components/pages/menu'    // 匯入Menu元件 Vue.use(VueRouter); export default new VueRouter({   routes:[     {       name:'首頁',       path:'/index',       component:Home     },     {       name:'分頁',       path:'/page',       //component:Page, // 原本只有引用 Page 元件       components:{         default: Page,         menu: Menu,   // 加入 Menu 元件       },       children:[         {           name:'child1',           path:'',           component:child_1         },         {           name:'child2',           path:'child2',           component:child_2              },         {           name:'child3',           path:'child3',           component:child_3         }       ]     }        ] }); 
 
你可以看到components屬性是一個物件,然後它裡面有兩個屬性default的值是Page,也就是Page元件, 而menu的值是Menu,也就是我們剛剛製作的Menu元件囉, 那要注意一下,這個menu的屬性名稱,要跟你在App.vue元件中, 你為那個在.container外層的router-view所加入的name屬性的值menu一樣喔。
經過以上的步驟,你應該就可以成功地在Page頁面上,同時呈現兩個不同的router-view元件囉。
修正小錯誤 以上的範例你可以知道,page元件的內容預設是吃到child1的內容, 但是,瀏覽器上會跳以下這個錯誤
它是說 page 分頁中,已經有預設的元件了,就是 child1 元件,會造成 child1 元件的內容不會被渲染出來。 所以,要移除 page 元件的name 的屬性內容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 ---router資料夾中的index.js檔案--- export default new VueRouter({   routes:[     {       name:'首頁',       path:'/index',       component:Home     },     {       //name:'分頁',     // 元件呈現名稱 -- 註解掉       path:'/page',       //component:Page , // 它所對應的原件       components:{         default: Page,         menu: Menu,       },       children:[         {           name:'child1',           path:'',           component:child_1            },         {           name:'child2',           path:'child2',           component:child_2          },         {           name:'child3',           path:'child3',           component:child_3           }       ]     }        ] }); 
 
你看,我們將 page 元件檔的 name:’分頁’的部分註解掉,之後,上面那個錯誤就不會再出現囉~~