指路明灯VueRouter

@vuerouter,指引前进的方向

纲要

  • 什么是路由
  • VueRouter的两种使用方式
  • 基于Vue-cli(脚手架)的vuerouterj简单实例

路由的概念

说到什么是路由,我们就得把前端路由和后台路由区分开来。后端路由:对于普通的网站,所有的超链接都是URL地址,所有的URL地址都对应服务器上对应的资源,这个对应关系就是后端中的路由。前端路由:对于单页面应用程序来说,主要通过URL中的hash(#号)来实现不同页面之间的切换,同时,hash有一个特点:HTTP请求中不会包含hash相关的内容;所以,单页面程序中的页面跳转主要用hash实现;这种通过hash改变来切换页面的方式,称作前端路由。
使用Vue构建的单页面应用程序,需要路由来显示组间的相互跳转。

VueRouter的两种使用方式

  • 声明式使用
    使用标签创建连接,to属性中传入路径,然后在指定显示的位置使用标签接收显示,link默认解析为a标签,但可以使用tag属性进行更改。声明式使用的基本流程如下:
    html中键入代码
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <!-- 使用 router-link 组件来导航. -->
    <!-- 通过传入 `to` 属性指定链接. -->
    <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
  </p>
  <!-- 路由出口 -->
  <!-- 路由匹配到的组件将渲染在这里 -->
  <router-view></router-view>
</div>

-----摘录自官方网站

-编程式使用
除了使用 创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现。在 Vue 实例内部,你可以通过 r o u t e r 访 问 路 由 实 例 。 因 此 你 可 以 调 用 t h i s . router 访问路由实例。因此你可以调用 this. router访this.router.push or replace or go。想要导航到不同的 URL,则使用 router.push 方法。这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。当你点击 时,这个方法会在内部调用,所以说,点击 等同于调用 router.push(…)

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

------摘录自官方网站
replace方法类似,go(n)方法表示回退n步,replace和push的区别在于push每次操作记录会存入记录栈中,而replace会重新创建一个记录栈,英文好的同学甚至可以从它们的英文释义中找到这个区别。

基于Vue-cli的VueRouter简单实例

  • 构建步骤
    1 明确路由组件有哪些 并将路由组件在views文件中定义出来
    2 在routers文件中配置映射所有路由组件并向外暴露配置对象
    3 在mian.js中配置路由器
    4 在相应位置写标签router-link,router-view使用路由

  • 实例说明

子路由
子路由
子路由
Home.vue
News.vue
Messages.vue
MessageDetail.vue
About.vue

About和Home为同级路由
home可跳转到News显示4个新闻,也可跳转到messages显示四条消息,同时四条消息都有详细的内容,点击每一条消息可以跳转显示每一条消息的详细内容,那么问题来了,用户的操作是不规律的,如何确定用户点击的是哪一条消息从而实现指定消息的跳转呢?这就是路由的动态匹配,我可以使用路径参数达成目标,你可以在一个路由中设置多段“路径参数”,对应的值都会设置到 $route.params 中。例如:

模式匹配路径$route.params
/user/:username/user/evan{ username: ‘evan’ }
/user/:username/post/:post_id/user/evan/post/123{ username: ‘evan’, post_id: ‘123’ }

$route表示当前路由,$router表示当前组件,两者都可以通过this引用

  • 目录结构
    在这里插入图片描述

实例代码

About.vue

<template>
    <div>
      About
    </div>
</template>

<script>
  export default {
    name: 'About'
  }
</script>

<style>

</style>

Home.vue

<template>
  <div>
    <h1>Home</h1>
    <router-link to="/home/news">News</router-link>
    <router-link to="/home/messages">Messages</router-link>

    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: 'Home'
  }
</script>

<style>

</style>

News.vue

<template>
  <div>
   <h1>News</h1>
    <ul>
      <!--按照规范,这里应该使用new来表示每一个消息的,但可惜new是保留字,不行-->
      <li v-for="(n,index) in news" :key="index">{{n}}</li>
    </ul>
  </div>
</template>

<script>
  export default {
    name: 'News',
    data(){
      return{
        news:['我是消息1','我是消息2','我是消息3']
      }
    }
  }
</script>

<style>

</style>

Messages.vue

<template>
  <div>
    <ul>
      <li v-for="message in messages" :key="messages.id">
        <router-link :to="`/home/messages/detail/${message.id}`">{{message.title}}</router-link>
        <button @click="pushShow(message.id)">push查看</button>
        <button @click="replaceShow(message.id)">replace查看</button>
      </li>
    </ul>
    <button @click="$router.back()">回退</button>
    <router-view></router-view>
  </div>

</template>

<script>
  export default {
    name: 'Messages',
    data(){
      return{
        messages:[]
      }
    },
    mounted () {
      setTimeout( ()=>{
        const messages = [
          {title:'message-001',id:1},
          {title:'message-002',id:2},
          {title:'message-003',id:3},
          {title:'message-004',id:4}
        ]
        this.messages = messages
      },1000)
    },
    methods:{
      pushShow(id){
        this.$router.push(`/home/messages/detail/${id}`)
      },
      replaceShow(id){
        this.$router.replace(`/home/messages/detail/${id}`)
      }
    }
  }
</script>

<style scoped>

</style>

MessageDetail.vue

<template>
 <div>
   <div>
     <p>ID:{{$route.params.id}}</p>
     <ul>
       <li>id:{{message.id}}</li>
       <li>title:{{message.title}}</li>
       <li>content:{{message.content}}</li>
     </ul>
 </div>
 </div>
</template>

<script>
  export default {
    name: 'MessageDetail',
    data(){
      return{
        message:{}
      }
    },
    mounted(){
      setTimeout(() =>{
        const allMessages = [
          {title:'message-001',content:'001content.....',id:1},
          {title:'message-002',content:'002content.....',id:2},
          {title:'message-003',content:'003content.....',id:3},
          {title:'message-004',content:'004content.....',id:4}
        ]
        this.allMessages = allMessages
        //将字符串变成数字
        const id = this.$route.params.id * 1
        this.message = this.allMessages.find(detail=>detail.id === id)
      },1000)
    },
    //这里涉及到一个问题,就是用户点击触发路由的时候,路由路径并没有变化,一直都是'/home/message/detail'
    //发生变化的只是后面的参数,这是不会触发路由的,解决的办法就是使用watch监视路由路径的改变,进行路由的跳转
    watch:{
      //$route表示路由对象
      $route:function (value) { //路由路径发生了改变,实际上是param发生了改变,value是改变的最新的route值
        //一旦发生了改变,就执行这个函数
        const id =   value.params.id * 1
        this.message = this.allMessages.find(detail=>  detail.id === id)
      }
    }
  }
</script>

<style>

</style>

App.vue

<template>
<div>
  <div><h2>Router Basic -01</h2></div>
  <div class="row">
    <div class="row-left">
      <div class="content">
        <!--vue-router使用的第一种方式:声明式使用   link声明 view显示-->
        <router-link to="/about">About</router-link>
        <router-link to="/home">Home</router-link>
      </div>
    </div>
    <div class="row-right">
      <keep-alive>
        //通过属性携带向路由组件传递参数,msg在about和home中声明接收之后均可使用
        <router-view></router-view>
      </keep-alive>
    </div>
  </div>
</div>
</template>

<script>
export default {
  name:'App',

}
</script>

<style  scoped>
  .row{
    width:400px;
    height:300px;
    margin: 0 auto;
    border:1px solid red;
  }
  .row-left{
    width:30%;
    height: 100%;
    float: left;
    border:1px solid blue;
  }
  .row-right{
    width:68%;
    height:100%;
    float: left;
  }
</style>

main.js

import Vue from 'vue'
import App from './App'
//注册配置对象
import router from './routers'

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

index.js

/*路由器模块*/

//1引入vue和vue-router
import Vue from 'vue'
import VueRouter from 'vue-router'

//2.声明使用路由
Vue.use(VueRouter)

//3.引入路由组件
import About from '../views/About'
import Home from '../views/Home'
import News from '../views/News'
import Messages from '../views/Messages'
import MessageDetail from '../views/MessageDetail'

//4.向外暴露路由配置对象 并配置路由
export default new VueRouter({
  routes:[
    {
      //路径 以'/'开头表示根路径
      path:'/about',
      //组件名
      component:About,
    },
    {
      path:'/home',
      component:Home,
      children:[
        {
          path:'/home/news',
          component:News,
        },
        {
          //子路由路径前面的根目录可以不写
          path:'messages',
          component:Messages,
          children:[
            {
              //传入id参数,使其匹配到指定的消息细节上显示
              path:'/home/messages/detail/:id',
              component:MessageDetail,
            }
          ]
        },
        {
          path:'',
          redirect:'/home/news',
        },
      ]
    },
    {
      //设置默认路径为'/about',就是不触发路由的时候,定位到/about这个组件
      path:'/',
      redirect:'/about'
    },
  ]
})

关于vuerouter的知识还有很多,我只是抛砖引玉,大家要想了解关于vuerouter的更细致的东西,请点击进入官方API进行阅读:Vue-router
我的分享就到这里了,感谢大家阅读。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值