Vue路由

vue-router

vue-router 4版本支持vue3

vue-router 3版本支持vue2

npm i vue-router@3

路由使用

首先在main.js中引入vuerouter

import Vue from 'vue'
import App from './App.vue'
//引入VueRouter
import VueRouter from 'vue-router'
import router from './router'
Vue.config.productionTip = false
//应用插件
Vue.use(VueRouter)

new Vue({
  render: h => h(App),
  router:router,
}).$mount('#app')

在src文件夹中创建router文件夹,同时创建index.js文件

//改文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
//引入相关的组件需要进行跳转的
import About from "@/components/About";
import Home from "@/components/Home";

//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',8
            component:About
        },
        {
            path:'/home',
            component: Home
        }
    ]
})
export default router;

App.vue文件中使用router-link进行页面跳转 to 参数填入跳转地址

<router-view>标签插入组件的显示

代码如下:

<template>
  <div id="app">
    <div class="col-xs-offset-2 col-xs-8">
      <div class="page-header"><h2>Vue Router Demo</h2></div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
<!--         原始html中我们使用<a>标签进行实现页面跳转 -->
<!--          <a class="list-group-item active" href="./about.html">About</a>-->
<!--          <a class="list-group-item" href="./home.html">Home</a>-->
          <router-link class="list-group-item" active-class="active" to="/about">About</router-link>
          <router-link class="list-group-item" active-class="active" to="/home">Home</router-link>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
<!--            指定组件的显示位置-->
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>


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

  }
}
</script>

<style>

</style>

routerouter属性不一样,每个应用只有一个router属性。

route是组件不同的配置项

嵌套路由/多级路由

在pages中添加New文件和Message文件

message文件内容如下:

<template>
  <div>
    <ul>
      <li>
        <a href="/message1">message001</a>&nbsp;&nbsp;
      </li>
      <li>
        <a href="/message2">message002</a>&nbsp;&nbsp;
      </li>
      <li>
        <a href="/message3">message003</a>&nbsp;&nbsp;
      </li>
    </ul>
  </div>
</template>

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

New文件内容如下:

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

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

Home文件内容

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

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

router中index配置文件内容

//改文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from "@/pages/About";
import Home from "@/pages/Home";
import New from "@/pages/New";
import Message from "@/pages/Message";

//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:New,
                },
                {
                    path:'message',
                    component:Message,
                }
            ]
        }
    ]
})
export default router;

路由传参

query参数

创建detail.vue文件

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

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

}
</script>

<style>

</style>

修改message.vue文件

<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
<!--        跳转路由并携带query参数,to的字符串写法-->
<!--        <router-link :to="`/home/message/detail?id=${m.id}&title=${m.title}`">{{ m.title }}</router-link>&nbsp;&nbsp;-->

<!--      跳转路由并携带query参数,to的对象写法-->
        <router-link :to="{
          path:'/home/message/detail',
          query:{
            id:m.id,
            title:m.title,
          }
        }">{{ m.title }}</router-link>
      </li>
    </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>

修改路由文件index

//改文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from "@/pages/About";
import Home from "@/pages/Home";
import New from "@/pages/New";
import Message from "@/pages/Message";
import Detail from "@/pages/Detail";

//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:New,
                },
                {
                    path:'message',
                    component:Message,
                    children:[
                        {
                            path:'detail',
                            component:Detail,
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;

命名路由

在路由配置中添加name属性给路由命名。

路由的params参数

需要在message文件中修改传参方式

<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
<!--        跳转路由并携带query参数,to的字符串写法-->
<!--        <router-link :to="`/home/message/detail/666/你好啊`">{{ m.title }}</router-link>&nbsp;&nbsp;-->

<!--      跳转路由并携带query参数,to的对象写法-->
<!--        <router-link :to="{-->
<!--          path:'/home/message/detail',-->
<!--          query:{-->
<!--            id:m.id,-->
<!--            title:m.title,-->
<!--          }-->
<!--        }">{{ m.title }}</router-link>-->
                <router-link :to="{
                  name:'xiangqing',
                  params:{
                    id:m.id,
                    title:m.title,
                  }
                }">{{ m.title }}</router-link>
      </li>
    </ul>
    <hr>
    <router-view></router-view>
  </div>
</template>

修改index文件中的路由配置

//改文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from "@/pages/About";
import Home from "@/pages/Home";
import New from "@/pages/New";
import Message from "@/pages/Message";
import Detail from "@/pages/Detail";

//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:New,
                },
                {
                    path:'message',
                    component:Message,
                    children:[
                        {
                            path:'detail/:id/:title',
                            name:'xiangqing',
                            component:Detail,
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;

修改detail文件中的数据访问方式

路由props配置

在index文件中的配置项

//改文件用于创建整个应用的路由器
import VueRouter from 'vue-router'
import About from "@/pages/About";
import Home from "@/pages/Home";
import New from "@/pages/New";
import Message from "@/pages/Message";
import Detail from "@/pages/Detail";

//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About
        },
        {
            path:'/home',
            component:Home,
            children:[
                {
                    path:'news',
                    component:New,
                },
                {
                    path:'message',
                    component:Message,
                    children:[
                        {
                            path:'detail/:id/:title',
                            name:'xiangqing',
                            component:Detail,
                            //props的第一种写法,对象写法,该对象中的所有key-value都会以props的形式传给Detail组件
                            // props:{a:1,b:'hello'}
                            //props第二种写法,值为布尔值,若布尔值为真
                            // 就会把该路由组件收到的所有params参数,以props的形式传给Detail组件,不能接受query所传递的参数
                            // props:true
                            //props第三种写法,值为函数
                            // props($route){
                            //     return {id:$route.query.id,title:$route.query.title}
                            // }
                            //以下为解构赋值写法
                            props({query:{id,title}}){
                                return {id,title}
                            }
                        }
                    ]
                }
            ]
        }
    ]
})
export default router;

detail文件中的写法

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

<script>
export default {
  name:'Detail',
  //第一种写法
  // props:['a','b'],
  //第二种写法、第三种写法
  props:['id','title']
}
</script>

<style>

</style>

router-link的replace属性

为解决浏览器回退问题

浏览器回退记录默认为push模式,每操作一条都会压入栈中。更改为replace模式后,操作会替换掉当前栈顶的记录,即替换掉当前的记录。

<router-link :replace="true" class="list-group-item" to="/home/news" active-class="active">News</router-link>

编程式路由导航

this.$router是VueRouter的实例对象

push操作\replace操作

methods:{
    pushShow(m){
 		this.$router.push({
			name:'xiangqing',
            query:{
                id:m.id,
                title:m.title
            }
		})       
    }
    replaceShow(m){
        this.$router.replace({
			name:'xiangqing',
            query:{
                id:m.id,
                title:m.title
            }
		})
    }
}

回退与前进

back操作与forward操作

back(){
	this.%router.back()
},
forward(){
	this.$router.forward()
}

缓存路由组件

<keep-alive>标签进行标记。被标记的组件在不显示时保持挂载,不会被销毁。

include属性添加需要被标记的组件。

<keep-alive>
	<router-view></router-view>
</keep-alive>

两个新的生命周期函数

//当组件被激活时触发
activated{

}
//当组件失活时触发
deactivated{

}

全局前置-路由守卫

权限控制,在路由index文件中配置

//在每次路由切换之前执行函数。全局前置路由守卫
router.beforeEach((to,from,next)=>{
    //to是要去的目标路由、from是来的路由、next放行
    //判断在本地localStorage中是否有school且值为atguigu
    if(to.path==='/home/news' || to.path==='/home/message'){
        if(localStorage.getItem('school')==='atguigu'){
    	    next()
    	}
    }
    else{
        next()
    }
})

使用meta属性可以在路由配置中添加自定义参数。其中isAuth就是自定义参数


//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About,
            meta:{
            	isAuth:false,
        	}
        },
   
    ]
})
export default router;

全局后置-路由守卫

//初始化的时候被调用、每次路由切换之后被调用
router.afterEach((to,from)=>{
    console.log('后置路由守卫',to,from)
    document.title = to.meta.title || 'lanlan'
})

独享路由守卫

单个路由独享的路由守卫

在路由配置文件中设置,beforeEnter参数

只有前置路由守卫,没有后置路由守卫。


//创建一个路由器
const router = new VueRouter({
    routes:[
        {
            path:'/about',
            component:About,
            meta:{
            	isAuth:false,
        	},
        	beforeEnter:(to,from,next)=>{
    			//....
			}
        },
   
    ]
})
export default router;

组件内路由守卫

在组件中配置路由守卫

beforeRouteEnter\beforeRouteLeave

<script>
export default {
  name:'Message',
  data(){
    return {
      messageList:[
        {id:'001',title:'消息001'},
        {id:'002',title:'消息002'},
        {id:'003',title:'消息003'}
      ]
    }
  },
      //通过路由规则进入该组件时被调用
  beforeRouteEnter(to,from,next){
      //...
  },
      //通过路由规则,离开该组件时被调用
  beforeRouteLeave(){
      //...
  }
}
</script>

history模式和hash模式

hash模式就是#。默认hash。兼容性好

history模式没有#。

项目上线。项目文件需要打包将项目文件转换为html、js、css文件。

npm run build

//在路由文件中配置
mode:'hash'