JavaScript框架Vue中的路由的一点总结

SPA应用的理解

单页面的应用(single page web application , SPA)
整个项目 只有一个完整的页面
点击页面中的 导航 不会导致页面的刷新,只有做页面的局部刷新
数据需要通过异步请求获取

路由

什么是路由 一个路由就是一组映射关系(key-value)
key:是路径 , value:function component (函数、组件)

前端路由
value component (组件) 用于显示页面的内容
后端路由
value function (函数) 用于处理用户端提交的请求

r o u t e 和 route和 routerouter的区别详解

$ router是用来操作路由的,$ route是用来获取路由信息的。

  1. $router是VueRouter的一个实例,他包含了所有的路由,包括路由的跳转方法,钩子函数等,也包含一些子对象(例如history)

    1. 在这里插入图片描述
  2. $ route是一个跳转的路由对象(路由信息对象),每一个路由都会有一个$route对象,是一个局部的对象。

    1. 在这里插入图片描述

    2. 主要属性

      1. $route.path 字符串,等于当前路由对象的路径,会被解析为绝对路径,如/home/ews
      2. $route.params 对象,包含路由中的动态片段和全匹配片段的键值对,不会拼接到路由的url后面
      3. $route.query 对象,包含路由中查询参数的键值对。会拼接到路由url后面
      4. $route.router 路由规则所属的路由器
      5. $route.name 当前路由的名字,如果没有使用具体路径,则名字为空

使用步骤

基本使用
  1. 安装vue-router npm i vue-router@3.2.0
  2. 在 src 目录下创建 index.js 文件
  3. 在main.js 中
    1. 导入
      1. import VueRouter from “vue-router”;
        import router from “./router”;
    2. 应用插件
      1. Vue.use(VueRouter)
    3. 在Vue 创建实例中添加 router 属性
      1. new Vue({
        // render: h => h(App),
        // 完整的写法
        render(createElement){
        return createElement(App)
        },
        store,
        router
        }).$mount(’#app’)
  4. 在 router / index.js 文件中
    1. 引入VueRouter
      1. import VueRouter from “vue-router”;
    2. 导入组件
      1. import About from “@/components/About”;
        import Home from “@/components/Home”;
    3. 创建 并 暴露 router实例对象,去管理一组一组的路由规则
      1. export default new VueRouter({
        routes:[
        {
        path:’/被请求的路径’,
        component: 引入组件的名称****_ **},
        {
        path: ‘/home’,
        component: **Home
        _**}
        ]
        })
  5. 在App.vue 中注册
    1. 指定组件显示的位置
    2. 触发路由的跳转 这个标签 效果 相当于a标签

      1. About

案例
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
import VueRouter from "vue-router";
// 引入 组件
import About from "@/components/About";
import Home from "@/components/Home";
// 创建 并 暴露 router实例对象,去管理一组一组的路由规则
export default new VueRouter({
    routes:[
        {
          // path /被请求的路径
            path:'/about',
          // 引入组件的名称
            component: About
        },
        {
            path: '/home',
            component: Home
        }
    ]
})
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')

<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>VUE 路由 案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about.html">About</a>
          <a class="list-group-item active" href="./home.html">Home</a>-->

        <!-- 在VUE中借助router-link 实现路由的切换 -->
        <router-link class="list-group-item active"  to="/about">
          About
        </router-link>
          <router-link class="list-group-item active"  to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
          <!--  指定组件的展示位置  -->
          <router-view></router-view>
        </div>
      </div>
    </div>

  </div>
</template>
<script>

export default {
  name: 'App',
  components: {}
}
</script>
<style scoped>

</style>

命名路由

作用:简化路由的跳转路径

命名

{name:‘xq’,
path: ‘detail/:id/:title’,
component: Detail}

使用


多级路由
  1. 配置路由规则,使用 children 配置项
    1. {
      path: ‘/home’,
      component: Home,
      children:[
      {
      path:‘news’,
      component: News
      _ _
      }
      ]
      }
  2. 触发路由的跳转(要写完整路径)

    1. {{ m.title }}
  3. 指定组件显示的位置

注意: 子路径前不加 “/” 跳转时 需要写完整路径 /home/news

案例
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">
            News
          </router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">
            Message
          </router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <ul>
    <li>news001<input/></li>
    <li>news002<input/></li>
    <li>news003<input/></li>
  </ul>
</template>

<script>
export default {
  name: "News"
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
          {{ m.title }}
      </li>
    </ul>
    <hr/>
  </div>
</template>

<script>
export default {
  name: "Message",,
  data(){
    return{
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  }
}
</script>

<style scoped>

</style>
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About,
        },
        {
            path:'/home',
            component:Home,
            children:[ //通过children配置子级路由
                {
                    path:'news', //此处一定不要写:/news
                    component:News
                },
                {
                    path:'message',//此处一定不要写:/message
                    component:Message
                }
            ]
        }
    ]

})

export default router;
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')
<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue 路由案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about">About</a>-->
<!--          <a class="list-group-item active" href="./home">Home</a>-->

          <!-- 在Vue中借助router-link 实现路由的切换 -->
          <router-link class="list-group-item active" to="/about">
            About
          </router-link>
          <router-link class="list-group-item active" to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
<!--          指定组件的展示位置-->
          <router-view></router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

传参

query参数 传递
  1. 传递参数
    1. 路由并携带query参数 字符串

      1. {{ m.title }}
    2. 路由并携带query参数 对象

      1. {{ m.title }}
  2. 接收参数
    1. $route.query.参数名
      1. {{$route.query.id}}
案例
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">
            News
          </router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">
            Message
          </router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <ul>
    <li>news001<input/></li>
    <li>news002<input/></li>
    <li>news003<input/></li>
  </ul>
</template>

<script>
export default {
  name: "News"
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
<!-- 路由 并 携带query 参数  字符串 -->
<!--        <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">
          {{ m.title }}
        </router-link>-->
<!-- 路由 并 携带query 参数  对象 -->
       <router-link :to="{
          path:'/home/message/detail',
          query:{
            id: m.id,
            title: m.title
          }
        }">
          {{ m.title }}
        </router-link>
<!-- query: 通过路由的name属性 简化请求路径-->
<!--        <router-link :to="{
          name: 'xq',
          query:{
            id: m.id,
            title: m.title
          }
        }">
          {{ m.title }}
        </router-link>-->
      </li>
      <input/>
    </ul>
    <hr/>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "Message",
  data(){
    return{
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  }
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li>
        消息编号:{{$route.query.id}}
      </li>
      <li>
        消息标题:{{$route.query.id}}
      </li>
    </ul>
  </div>
</template>

<script>

export default {
  name: "Detail"
}
</script>

<style scoped>

</style>
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name:'xq',
                            path: 'detail',
                            component: Detail,
                        }
                    ]
                }
            ]
        }
    ]
})

export default router;
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')
<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue 路由案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about">About</a>-->
<!--          <a class="list-group-item active" href="./home">Home</a>-->

          <!-- 在Vue中借助router-link 实现路由的切换 -->
          <router-link class="list-group-item active" to="/about">
            About
          </router-link>
          <router-link class="list-group-item active" to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
<!--          指定组件的展示位置-->
          <router-view></router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

params参数传递

需要在路由配置文件中,在路由后面加上占位符

  1. index.js 中的 path中使用 /:参数名/:参数名…
    1. path: ‘detail/:id/:title’
  2. 传参

    1. {{ m.title }}
  3. 使用 {{$route.params.参数名}}
    1. {{$route.params.id}}

特别注意:路由携带params参数时,若使用to的对象写法,则不能使用path配置项,必须使用name配置!

案例
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">
            News
          </router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">
            Message
          </router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <ul>
    <li>news001<input/></li>
    <li>news002<input/></li>
    <li>news003<input/></li>
  </ul>
</template>

<script>
export default {
  name: "News"
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
				<!-- params 传参-->
        <router-link :to="{
          name: 'xq',
          params: {
            id: m.id,
            title: m.title
          }
        }">
          {{ m.title }}
        </router-link>
      </li>
      <input/>
    </ul>
    <hr/>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "Message",
  data(){
    return{
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  }
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li>
        消息编号:{{$route.params.id}}
      </li>
      <li>
        消息标题:{{$route.params.id}}
      </li>
    </ul>
  </div>
</template>

<script>

export default {
  name: "Detail"
}
</script>

<style scoped>

</style>
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name:'xq',
                            path: 'detail/:id/:title',// params传参 在路径中先占位
                            component: Detail,
                        }
                    ]
                }
            ]
        }
    ]
})

export default router;
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')
<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue 路由案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about">About</a>-->
<!--          <a class="list-group-item active" href="./home">Home</a>-->

          <!-- 在Vue中借助router-link 实现路由的切换 -->
          <router-link class="list-group-item active" to="/about">
            About
          </router-link>
          <router-link class="list-group-item active" to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
<!--          指定组件的展示位置-->
          <router-view></router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

路由的props配置

作用

让路由组件更方便的接收到 参数

使用方式有三种

传值:

  1. props 值为 对象 该对象中所有的key-value的组合最终都会通过props传给Detail组件
    1. props: {
      userName: ‘张三’,
      age: 18
      }
  2. props值为布尔值_,布尔值为true,则把路由收到的所有params参数通过props传给Detail组件_
    1. props: true
  3. props值为函数_,该函数返回的对象中每一组key-value都会通过props传给Detail组件_
    1. props($route){
      return {
      id: $route.params.id,
      title: $route.params.title
      }
      }

接收、使用:

  1. props:[‘id’,‘title’]

    • 消息编号:{{ id }}

    • 消息标题:{{ title }}

案例
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">
            News
          </router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">
            Message
          </router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <ul>
    <li>news001<input/></li>
    <li>news002<input/></li>
    <li>news003<input/></li>
  </ul>
</template>

<script>
export default {
  name: "News"
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
				<!-- params 传参-->
        <router-link :to="{
          name: 'xq',
          params: {
            id: m.id,
            title: m.title
          }
        }">
          {{ m.title }}
        </router-link>
      </li>
      <input/>
    </ul>
    <hr/>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "Message",
  data(){
    return{
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  }
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li>
        消息编号:{{ id }}
      </li>
      <li>
        消息标题:{{ title }}
      </li>
    </ul>
  </div>
</template>

<script>

export default {
  name: "Detail",
  props:['id','title']
}
</script>

<style scoped>

</style>
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    // props: {
                    //     userName: '张三',
                    //     age: 18
                    // },
                    children: [
                        {
                            name:'xq',
                            path: 'detail/:id/:title',// params 传参 /:id/:title  在路径中先占位
                            component: Detail,
                            // props: {
                            //     userName: '张三',
                            //     age: 18
                            // }
                            props: true
                            // props($route){
                            //     return {
                            //         id: $route.params.id,
                            //         title: $route.params.title
                            //     }
                            // }
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')
<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue 路由案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about">About</a>-->
<!--          <a class="list-group-item active" href="./home">Home</a>-->

          <!-- 在Vue中借助router-link 实现路由的切换 -->
          <router-link class="list-group-item active" to="/about">
            About
          </router-link>
          <router-link class="list-group-item active" to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
<!--          指定组件的展示位置-->
          <router-view></router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

router-link的replace属性 和 push属性

  1. 作用:控制路由跳转时操作浏览器历史记录的模式
  2. 浏览器的历史记录有两种写入方式:分别为push和replace,push追加历史记录replace替换当前记录。路由跳转时候默认push
  3. 如何开启replace模式:

<router-link **replace **:to="{
name: ‘xq’,
params: {
id: m.id,
title: m.title
}
}">
{{ m.title }}

push 本质是向history栈中添加一个路由,在我们看来是切换路由,但本质是在添加一个history记录

案例
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
        <!-- params 传参-->
        <router-link replace :to="{
          name: 'xq',
          params: {
          id: m.id,
          title: m.title
          }
          }">
          {{ m.title }}
        </router-link>

        <button @click="showPush(m)">push查看</button>
        <button @click="showReplace(m)">replace查看</button>

      </li>
      <input/>
    </ul>
    <hr/>
    <router-view></router-view>
  </div>
</template>

<script>
  export default {
    name: "Message",
    props: ['userName','age'],
    data(){
      return{
        messageList:[
          {id:'001',title:'消息001'},
          {id:'002',title:'消息002'},
          {id:'003',title:'消息003'}
        ]
      }
    },
    methods:{
      showPush(m){
        this.$router.push({
          name:'xq',
          params: {
            id: m.id,
            title: m.title
          }
        })
      },
      showReplace(m){
        this.$router.replace({
          name:'xq',
          params:{
            id: m.id,
            title: m.title
          }
        })
      }
    }
  }
</script>

<style scoped>

</style>

编程式路由导航

作用:不借助 实现路由跳转,让路由跳转更加灵活

  • this.$router.back() 浏览器历史记录后退-1
  • this.$router.forward() 浏览器历史记录前进1
  • this.$router.go(- + x) 正 前进x 负数 后退-x
案例
<template>
  <div class="col-xs-offset-2 col-xs-8">
    <div class="page-header">
      <button @click="back">后退</button>
      <button @click="forWard">前进</button>
      <button @click="go">后退 * 3</button>
    </div>
  </div>
</template>

<script>
export default {
  name: "Banner",
  methods:{
    back(){
      this.$router.back();
    },
    forWard(){
      this.$router.forward();
    },
    go(){
      this.$router.go(-3);
    }
  }
}
</script>

<style scoped>

</style>
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <div>
    <h2>我是Home组件的内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">
            News
          </router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">
            Message
          </router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

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

<style scoped>

</style>
<template>
  <ul>
    <li>news001<input/></li>
    <li>news002<input/></li>
    <li>news003<input/></li>
  </ul>
</template>

<script>
export default {
  name: "News"
}
</script>

<style scoped>

</style>
<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
				<!-- params 传参-->
        <router-link :to="{
          name: 'xq',
          params: {
            id: m.id,
            title: m.title
          }
        }">
          {{ m.title }}
        </router-link>
      </li>
      <input/>
    </ul>
    <hr/>
    <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: "Message",
  data(){
    return{
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  }
}
</script>

<style scoped>

</style>
<template>
  <div>
    <Banner/>
    <ul>
      <li>
        消息编号:{{ id }}
      </li>
      <li>
        消息标题:{{ title }}
      </li>
    </ul>
  </div>
</template>

<script>
import Banner from "@/components/Banner";

export default {
  name: "Detail",
  components:{Banner},
  props:['id','title']
}
</script>

<style scoped>

</style>
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News
                },
                {
                    path: 'message',
                    component: Message,
                    // props: {
                    //     userName: '张三',
                    //     age: 18
                    // },
                    children: [
                        {
                            name:'xq',
                            path: 'detail/:id/:title',// params 传参 /:id/:title  在路径中先占位
                            component: Detail,
                            // props: {
                            //     userName: '张三',
                            //     age: 18
                            // }
                            props: true
                            // props($route){
                            //     return {
                            //         id: $route.params.id,
                            //         title: $route.params.title
                            //     }
                            // }
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;
import Vue from 'vue'
import App from './App.vue'
import store from "./store";
import VueRouter from "vue-router";
import router from "./router";

Vue.config.productionTip = false

Vue.use(VueRouter)

new Vue({
  // render: h => h(App),
  // 完整的写法
  render(createElement){
    return createElement(App)
  },
  store,
  router
}).$mount('#app')
<template>
  <div id="app">
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header">
          <h2>Vue 路由案例</h2>
        </div>
      </div>
    </div>

    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- 原始的HTML 实现页面的跳转 -->
<!--          <a class="list-group-item active" href="./about">About</a>-->
<!--          <a class="list-group-item active" href="./home">Home</a>-->

          <!-- 在Vue中借助router-link 实现路由的切换 -->
          <router-link class="list-group-item active" to="/about">
            About
          </router-link>
          <router-link class="list-group-item active" to="/home">
            Home
          </router-link>
        </div>
      </div>
    </div>

    <div class="col-xs-6">
      <div class="panel">
        <div class="panel-body">
<!--          指定组件的展示位置-->
          <router-view></router-view>
        </div>
      </div>
    </div>
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {

  }
}
</script>

<style>

</style>

缓存路由组件

  1. 作用:让不展示的路由组件保持挂载,不被销毁。
  2. include 中写 想要缓存 的组件名称 不写 表示 缓存所有,写了则表示这组件开启了缓存
    1. include=“组件名” 表示这个组件启用了 缓存组件
    2. include="[‘组件名1’,‘组件名2’,…]" 表示多个组件启用了 缓存组件

缓存组件

<!--   缓存组件   -->
<keep-alive include="News">
  	<router-view></router-view>
</keep-alive>

两个生命周期钩子

当页面被keep-alive缓存下来的时候,vuet提供两个钩子函数

activated
被 keep-alive 缓存的组件激活时调用。
deactivated
被 keep-alive 缓存的组件失活时调用。

注:这两个状态不算在直接的生命周期里,这两个生命周期钩子需要配合前面的缓存路由组件使用(没有缓存路由组件不起效果)
当keep-alive页面缓存,有activated钩子和created钩子函数时

这两个函数会被同时触发,此时应该使用activated代替created,因为created只会触发一次

页面被缓存下来的时候,就不会触发destroyed生命钩子

取而代之触发的是deactivated钩子

然后引出我们keep-alive里边的两个属性

include 字符串或正则表达,只有匹配的组件会被缓存
exclude 字符串或正则表达式 ,任何匹配的组件都不会被缓存

路由守卫

  1. 作用:对路由进行权限控制
  2. 分类:全局守卫、独享守卫、组件内守卫
    1. 全局路由守卫
    • 由于在任何组件中都能使用this.$router,所以全局路由守卫可以在任意组件中调用(可以放在任意组件中,放main.js中也可以)
      1. beforeEach() 前置路由守卫
// 如果想限制所有路由的跳转,可以使用router对象调用全局路由守卫
router.beforeEach(function(to, from, next){
  // 任何一个路由跳转都会经过这个路由守卫
  console.log("全局路由进入之前", to.fullPath, from.fullPath);
  next()
})
  2.    afterEach()	后置路由守卫
// 路由跳转之后的守卫,next不调用也无所谓
router.afterEach(function(to, from, next){
  // 任何一个路由跳转都会经过这个路由守卫
  console.log("全局路由进入之后", to.fullPath, from.fullPath);
})
  1. 独享守卫
    1. beforeEnter()
{
    path: '/',
    name: 'Home',
    component: Home,
    // 路由配置对象中可添加路由守卫函数,只监听单个路由
    beforeEach: (to, from, next) => {
      console.log("单个路由守卫进入之前", to.fullPath, from.fullPath);
      next()
    }
  }
  1. 组件内的路由守卫
    1. beforeRouteEnter()
// 路由守卫:判断路由能否跳转,可控制路由跳转(多做登录认证)
beforeRouteEnter (to, from, next) {
  /* 路由守卫有三个参数,
  to表示即将跳转的路由信息对象(到哪去,跳到当前页的路由对象),
  from是路由跳转的来源信息对象(从哪来,从哪里调到此页面的路由对象),
  next函数,调用时允许路由进入 */
  console.log("路由进入之前", to, from, next);
  /* 此时,to的路径必定是/about,如果from的路由路径也是about,会报错,
  此时需要禁止路由跳转,防止报错
  next(); // 是否允许被跳转
  使用场景:这个路由守卫,常用于做登录认证,在这里判断用户是否已经登录,
  如果已经登录,调用next()允许进入,如果没有登录,不调用next(),禁止进入。
  主要针对些需要登录状态才能访问的页面,如:个人信息页 */
  console.log(this);
  // 路由进入之前,组件还未创建,打印this是undefined,this是不能调的,
  // 那么如何在这个路由守卫中获取组件对象this?
  next((vm)=>{
    // next()的参数是一个回调函数,当组件创建完成后调用,回调的函数就是组件对象this
    console.log(vm);
  })
},

  2. beforeRouterUpdate()
// 路由守卫:当路由路径来源和目标相同时(当前页跳转当前页),
// 参数不同时,执行这个路由守卫,不会报错(如果参数相同,会直接报错,不会进入路由守卫)
    beforeRouteUpdate (to, from, next){
      console.log("路由更新之前", to, from, this.$route); 
      // 此时这里的this.$route和from里的page一直是不变的是旧的信息,
      // to对象里的数据才是最新值,所以用to.query.page拿到最新的数据
      this.$axios.get("/douyu/api/room/list", {
        params: { page: to.query.page }
      }).then(res => {
        console.log(res.data.data.list);
        this.list = res.data.data.list
      })
      next();
      // 使用场景:这个路由守卫,常用于写搜索页,当搜索关键词更新时,
      // 组件并没有重置也没有显示隐藏,所以普通的生命周期钩子并不会触发,只能在这里更新数据
    },

  3.  beforeRouteLeave()
// 路由守卫:路由离开前,从当前页跳转到其它页之前调用
    beforeRouteLeave (to, from, next) {
      console.log("路由离开之前", to.path, from.path, next);
      next()
      // 使用场景,比如我们网站中遇到的关不掉的广告页面
      // 比如我们在这个函数中能够不掉用next函数,当前页面就不能跳转到其它页面了
    }
  1. 路由守卫的参数有三个: to, from , next
    1. to: 表示即将跳转的路由信息对象(到哪去,跳到当前页的路由对象)
    2. from: 是路由跳转的来源信息对象(从哪来,从哪里调到此页面的路由对象)
    3. next: 回调函数, 表示是否允许路由跳转, 调用允许, 不调用则禁止(表示是否放行)
全局守卫
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News,
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name:'xq',
                            path: 'detail/:id/:title',// params 传参 /:id/:title  在路径中先占位
                            component: Detail,
                            props: true
                        }
                    ]
                }
            ]
        }
    ]
})
// 全局 路由首位
router.beforeEach((to,from,next)=>{
    console.log("前置路由守卫",to,from,next);
    next(); // 放行
});
router.afterEach((to, from,)=>{
    console.log("后置路由守卫",to,from)
})

export default router;

独享守卫
import VueRouter from "vue-router";

import About from "@/components/About";
import Home from "@/components/Home";
import News from "@/components/News";
import Message from "@/components/Message";
import Detail from "@/components/Detail";

const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component: About
        },
        {
            path: '/home',
            component: Home,
            children:[
                {
                    path:'news',
                    component: News,
                  // 独享守卫
                    beforeEnter(to,from,next){
                        console.log("独享路由守卫");
                        next();
                    }
                },
                {
                    path: 'message',
                    component: Message,
                    children: [
                        {
                            name:'xq',
                            path: 'detail/:id/:title',// params 传参 /:id/:title  在路径中先占位
                            component: Detail,
                            props: true
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;

组件内守卫
<template>
  <div>
    <h2>我是About组件的内容</h2>
  </div>
</template>

<script>
export default {
  name: "About",
  beforeRouteEnter(to,from,next){
    console.log("组件内路由守卫 beforeRouterEnter");
    next();
  },
  beforeRouteLeave(to,from,next){
    console.log("组件内路由守卫 beforeRouterLeave");
    next()
  }
}
</script>

<style scoped>

</style>

最后页面效果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值