Vue Router 嵌套路由实例

效果如下:
在这里插入图片描述


前言

更新视图但不重新请求页面,是前端路由原理的核心之一。接下来实现一个简单嵌套路由的功能,并贴上代码。准备工作请参考前面几篇博客。共有五个路由组件,分别为:About.vue、Home.vue、News.vue、Message.vue、MessageDetail.vue。
其中App是根组件,包括About.vue和Home.vue两个路由组件,而Home组件又包括News.vue和Message.vue两个路由组件。在Message.vue组件中,使用按钮进行编程式导航,即页面跳转由点击按钮来实现。


一、目录

这个嵌套路由共包括如下目录文件
在这里插入图片描述

二、步骤

main.js

main.js是主入口文件,引入了vue框架,根组件,路由插件,并定义了vue的实例

代码如下:

/*
入口JS
 */
import Vue from 'vue'
import App from './App.vue'
import router from './router'
/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: {App}, // 映射组件标签
  template: '<App/>', // 指定需要渲染到页面的模板
  router  // 注册路由器
})

index.html

index.html可以理解为一个web页面容器,挂载main.js定义的根节点,内容由组件填充。
代码如下:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>vue_demo</title>
  <script>
  </script>
  <script src="src/main.js"></script>
</head>
<style>
  .router-link-active{
    color: red !important;
  }
</style>
<body>
<div id="app"></div>
</body>
</html>

App.vue

App.vue是根组件,组件标签需要导入此页面

<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Router Test</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!--生成路由链接-->
          <router-link to="/about" class="list-group-item">About</router-link>
          <router-link to="/home" class="list-group-item">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!--显示当前组件-->
            <keep-alive>
              <router-view msg="abc"></router-view>
            </keep-alive>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  export default {}
</script>
<style>
</style>

index.js

index.js位于router(路由器)文件夹下,用来注册应用中所有的路由

/*
路由器对象模块
 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import About from '../pages/About.vue'
import Home from '../pages/Home.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import MessageDetail from '../pages/MessageDetail.vue'
// 声明使用vue-router插件
/*
内部定义并注册了2个组件标签(router-link/router-view),
给组件对象添加了2个属性:
  1. $router: 路由器
  2. $route: 当前路由
 */
Vue.use(VueRouter)

export default new VueRouter ({
  // 注册应用中所有的路由
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home,
      children: [
        {
          path: '/home/news',
          component: News
        },
        {
          path: 'message',
          component: Message,
          children: [
            {
              path:'detail/:id',// 占位写法
              component: MessageDetail
            }
          ]
        },
        {
          path: '',
          redirect: '/home/news'
        }
      ]
    },
    {
      path: '/',
      redirect: '/about'
    }
  ]
})

五个路由组件

五个路由组件都放在一个文件page里.

  1. About.vue
<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Router Test</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!--生成路由链接-->
          <router-link to="/about" class="list-group-item">About</router-link>
          <router-link to="/home" class="list-group-item">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <!--显示当前组件-->
            <keep-alive>
              <router-view msg="abc"></router-view>
            </keep-alive>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  export default {}
</script>
<style>
</style>

  1. Home.vue
<template>
  <div>
    <h2>Home</h2>
    <div>
      <ul class="nav nav-tabs">
        <li><router-link to="/home/news">News</router-link></li>
        <li><router-link to="/home/message">Message</router-link></li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>
<script>
  export default {}
</script>
<style>
</style>
  1. News.vue
<template>
  <ul>
    <li v-for="(news, index) in newsArr" :key="index">{{news}}</li>
  </ul>
</template>

<script>
  export default {
    data () {
      return {
        newsArr: ['News001', 'News002', 'News003']
      }
    }
  }
</script>
<style>
</style>
  1. Message.vue
<template>
  <div>
    <ul>
      <li v-for="m in messages" :key="m.id">
        <router-link :to="`/home/message/detail/${m.id}`">{{m.title}}</router-link>
        <button @click="pushShow(m.id)">push查看</button>
        <button @click="replaceShow(m.id)">replace查看</button>
      </li>
    </ul>
    <button @click="$router.back()">回退</button>
    <hr>
    <router-view></router-view>
  </div>
</template>
<!--//$route代表当前的路由组件,$router代表当前路由器-->
<script>
  export default {
    data () {
      return {
        messages: [
         /* {id: 1, title: 'Message001'},
          {id: 3, title: 'Message003'},
          {id: 5, title: 'Message005'}*/
        ]
      }
    },


    mounted () {
      setTimeout(() => {
        const messages = [
          {id: 1, title: 'Message001'},
           {id: 3, title: 'Message003'},
           {id: 5, title: 'Message005'}
        ]
        this.messages = messages
      }, 1000)
    },

    methods: {
      //用按钮实现路由链接跳转,push和replace都可实现,但按push,再按回退键会回上一步链接,
      // 而replace,会回退到上一级链接
      pushShow (id) {
        this.$router.push(`/home/message/detail/${id}`)
      },

      replaceShow(id) {
        this.$router.replace(`/home/message/detail/${id}`)
      }
    }
  }
</script>

<style>

</style>

  1. MessageDetail.vue
<template>
  <ul>
    <!--//$route代表当前的路由组件,$router代表当前路由器-->
    <li>id: {{$route.params.id}}</li>
    <li>title: {{detail.title}}</li>
    <li>content: {{detail.content}}</li>
  </ul>
</template>

<script>
  const messageDetails = [
    {id: 1, title: 'Message001', content: 'message content00111....'},
    {id: 3, title: 'Message003', content: 'message content00222....'},
    {id: 5, title: 'Message005', content: 'message content00333....'}
  ]
  export default {
    data() {
      return {
        detail: {}
      }
    },
    mounted () {// 改变当前路由组件参数数据时, 不会重新创建组件对象, mounted不会重新执行
      const id = this.$route.params.id
      this.detail = messageDetails.find(detail => detail.id===id*1)
    },

    watch: {
      $route: function () { // 改变当前路由组件参数数据时自动调用
        console.log('$route()')
        const id = this.$route.params.id
        this.detail = messageDetails.find(detail => detail.id===id*1)
      }
    }
  }
</script>

<style>

</style>


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 2 的嵌套由可以帮助我们构建复杂的页面结构。在嵌套由中,一个由可以包含多个子由,而每个子由又可以再次包含自己的子由。 下面是一个示例,展示了如何在 Vue 2 中使用嵌套由: 首先,我们需要设置主由(父由),这可以在 `router/index.js` 文件中完成: ```javascript import Vue from 'vue' import Router from 'vue-router' Vue.use(Router) export default new Router({ routes: [ { path: '/', component: Home, children: [ { path: 'about', component: About, children: [ { path: 'contact', component: Contact }, // 其他子由... ] }, // 其他子由... ] } ] }) ``` 在上面的示例中,我们定义了一个主由 `/`,它的组件是 `Home`。然后,我们定义了一个子由 `/about`,它的组件是 `About`。在 `About` 组件中,又定义了一个子由 `/contact`,它的组件是 `Contact`。 现在,我们可以在 `Home` 组件的模板中添加一个 `<router-view>` 标签来展示嵌套由的内容: ```html <template> <div> <h1>Home</h1> <router-view></router-view> </div> </template> ``` 同样地,在 `About` 组件的模板中也要添加一个 `<router-view>` 标签: ```html <template> <div> <h2>About</h2> <router-view></router-view> </div> </template> ``` 这样,当我们访问 `/about` 径时,`Home` 组件会显示出来,并且在其中展示 `About` 组件。 当访问 `/about/contact` 径时,`Home` 和 `About` 组件都会显示出来,并且在 `About` 组件中展示 `Contact` 组件。 希望这个示例对你有所帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值