vue 路由、嵌套路由、动态路由

本文详细介绍了如何在Vue.js项目中配置和使用路由,包括相对路径与绝对路径的区别,路由和嵌套路由的设置,以及vue-router的引入和组件的创建。在HelloWorld组件中,创建了子路由One和Two,并通过router-link进行导航。同时,展示了如何实现动态路由,通过Three组件获取文章列表并展示,以及如何通过Article组件显示单篇文章详情。最后,调整了路由配置以支持动态路由。
摘要由CSDN通过智能技术生成

简介

路由就是一套映射规则,当url中的哈希值(#hash)改变时,路由会根据制定好的规则,展示对应的视图组件。

vue中的路由路径分为:相对路径(不带 ‘/’,会拼接父级路由)和 绝对路径(带 ‘/’,是完整的路由)

路由和嵌套路由

引入 vue-router

使用 vue init webpack <project-name> 创建vue项目模板时,默认会引入如下三个组件

  • vue
  • vuex
  • vue-router

确认在 main.js 中已将 vue-router 传递给 vue 的构造函数,vue 的构造函数会自动将router绑定到 vue 的全局,后面使用 this.$router 引用

import router from './router'

new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>'
})

添加组件

在 components 目录下构造 3 个 vue视图组件

  • One.vue
  • Two.vue
  • Three.vue

第三个组件与 HelloWorld 同级,而前两个组件为 HelloWorld 的子路由

src/components/One.vue,data 里的数据才是页面可以引用的变量(data上面的是组件名)

<template>
  <div>
    <h1>{{this.name}}</h1>
    <div>{{msg}}</div>
  </div>
</template>

<script>
export default {
  name: 'One',
  data () {
    return {
      name: '第1个页面',
      msg: 'Welcome to First Page'
    }
  }
}
</script>

src/components/Two.vue

<template>
  <div>
    <h1>{{this.name}}</h1>
    <div>{{msg}}</div>
  </div>
</template>

<script>
export default {
  name: 'Two',
  data () {
    return {
      name: '第2个页面',
      msg: 'Welcome to Second Page'
    }
  }
}
</script>

src/components/Three.vue 其中 $router.back(-1) 表示返回上一级

<template>
  <div>
    <h1>{{this.name}}</h1>
    <div>{{msg}}</div>
    <p>
      <button v-on:click="$router.back(-1)">返回上一级</button>
    </p>
  </div>
</template>

<script>
export default {
  name: 'Three',
  data () {
    return {
      name: '第3个页面',
      msg: 'Welcome to Third Page, This is a single Page'
    }
  }
}
</script>

配置路由规则

src/router/index.js

  • @符号标识基于src目录
  • 如果几个路由使用的是同一个组件,使用 redirect 重定向,而非重复配置
  • 绝对路径使用 ‘/’ 打头,相对路径直接以路径名起头
  • children 表示嵌套的子路由,将会渲染至当前vue组件的 router-view 中
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import One from '@/components/One'
import Two from '@/components/Two'
import Three from '@/components/Three'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      redirect: 'hello'
    },
    {
      path: '/hello',
      name: 'HelloWorld',
      component: HelloWorld,
      redirect: 'hello/one',
      children: [
        {
          path: 'one',
          component: One
        },
        {
          path: 'two',
          component: Two
        }
      ]
    },
    {
      path: '/three',
      name: 'Three',
      component: Three
    }
  ]
})

添加路由切换组件

src/components/HelloWorld.vue,以 ‘/’ 打头表示绝对路径

<template>
()
  <div>
      <ul>
        <li><router-link to=one>子页面1</router-link></li>
        <li><router-link to=two>子页面2</router-link></li>
        <li><router-link to=/three>独立页面3</router-link></li>
      </ul>
      <router-view />
    </div>
()
</template>

实验截图

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

动态路由

修改 src/components/Three.vue 设置文章列表

<template>
  <div>
    <h1>Hello World</h1>
    <h2>{{this.name}}</h2>
    <div>{{msg}}</div>
    <p>
      <button v-on:click="$router.back(-1)">返回上一级</button>
    </p>
    <p v-if="err != null">获取数据失败:{{err}}</p>
    <p v-else class="articles">
      <ul>
        <li v-for='article in articles' v-bind:key='article.id'>
          <router-link v-bind:to="'/article/' + article.id">{{article.title}}</router-link>
        </li>
      </ul>
    </p>
  </div>
</template>

<script>
export default {
  name: 'Three',
  data () {
    return {
      name: '第3个页面',
      msg: 'Welcome to Third Page, This is a single Page',
      articles: [],
      err: null
    }
  },
  mounted () {
    this.getArticle()
  },
  methods: {
    getArticle () {
      this.$fetch.get('api/article').then(res => {
        console.log('fetch article', res)
        this.articles = res.data
      }).catch(_err => {
        console.log('axios err', _err)
        this.err = _err
      })
    }
  }
}
</script>

<style scoped>
ul {
  list-style-type: none;
  padding: 0;
  text-align: justify;
}
li {
  display: block;
  margin: 10px;
}
.articles {
  display: inline-block;
}
</style>

新建 src/components/Article.vue 用来显示单条文章

<template>
  <div>
    <h1>Article {{ $route.params.id }}</h1>
    <p>{{content}}</p>
  </div>
</template>

<script>
export default {
  name: 'Article',
  data () {
    return {
      content: ''
    }
  },
  mounted () {
    this.getArticle()
  },
  methods: {
    getArticle () {
      this.$fetch.get('api/article/' + this.$route.params.id).then(res => {
        console.log('fetch article', res, res.data)
        if (res.code === 0) {
          this.content = res.data.title
        } else {
          this.content = res.msg
        }
      }).catch(_err => {
        console.log('axios err', _err)
      })
    }
  }
}
</script>

最后对路由进行修改,配置 article 的动态路由

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import One from '@/components/One'
import Two from '@/components/Two'
import Three from '@/components/Three'
import Article from '@/components/Article'

Vue.use(Router)
// function getAbsolutePath () {
//   let path = location.pathname
//   console.log(path)
//   // 输出为/xxx/dist/index.html
//   console.log(path.substring(0, path.lastIndexOf('/') - 5))
//   return path.substring(0, path.lastIndexOf('/') - 5)
// }

export default new Router({
  mode: history,
  // base: getAbsolutePath(),
  routes: [
    {
      path: '/',
      redirect: 'hello'
    },
    {
      path: '/hello',
      name: 'HelloWorld',
      component: HelloWorld,
      redirect: 'hello/one',
      children: [
        {
          path: 'one',
          component: One
        },
        {
          path: 'two',
          component: Two
        }
      ]
    },
    {
      path: '/three',
      name: 'Three',
      component: Three
    },
    {
      path: '/article/:id',
      name: 'Article',
      component: Article
    }
  ]
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值