VueRouter系列的文章示例编写时,项目是使用vue-cli脚手架搭建。html
项目搭建的步骤和项目目录专门写了一篇文章:点击这里进行传送vue
后续VueRouter系列的文章的示例编写均基于该项目环境。web
VueRouter系列文章连接vue-router
《VueRouter爬坑第一篇》-简单实践vue-cli
阅读目录app
一.前言-从需求出发布局
二.需求实现url
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
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同样的路由配置数组,同时还支持屡次的嵌套。