一.介绍

1.路由

路由其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的about 按钮,页面中就要显示about 的内容。Home按钮  => home 内容, about按钮 => about 内容,也可以说是一种映射. 

2.vue-router

当你要把 vue-router  添加到项目。我们需要将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们

二.基本使用

(一).动态路由匹配

//2.user.vue
 <router-link to="/user/foo">/user/foo</router-link>

//2.router.js
const User = {
  template: `<div>User {{ $route.params.id }}</div>`
}
  /*新增user路径,配置了动态的id*/
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

const app = new Vue({ router }).$mount('#app')

注意:

复用组件时,路由参数的变化作出响应,可以简单地 watch(监测变化) $route 对象

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 对路由变化作出响应...
    }
  }
}

在组件中使用

export default {  
  	watch:{
	    $route(){
	    	//重复使用操作
	        this.addViewTags();
	    }
  	},
  	methods: {
  		addViewTags(){
			if(this.$route.name){
				const route = this.$route
				this.$store.dispatch('addVisitedViews',route);
			}
	    }
  	}
}

(二).嵌套路由

简单的语法:

配置嵌套路由 message父页面 嵌套着news页面
path: '/message',
component: message,
children: [
  {
    path: 'news',
    component: news
  }
]
在message页面
<router-link to="/message/news">Message</router-link>
<router-view></router-view>

1.实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如:

const User = {
  template: `
    <div class="user">
      <h2>User {{ $route.params.id }}</h2>
      <router-view></router-view>
    </div>
  `
}
const UserHome = { template: '<div>Home</div>' }
const UserProfile = { template: '<div>Profile</div>' }
const UserPosts = { template: '<div>Posts</div>' }

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
 					// 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome },
				
         // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
        { path: 'profile', component: UserProfile },

        // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
        { path: 'posts', component: UserPosts }
      ]
    }
  ]
})
const app = new Vue({ router }).$mount('#app')

移步这里

2.vue项目中路由配置小案例

配置路由router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index'

import about from '@/components/about'
import message from '@/components/message'


import news from '@/components/news'

Vue.use(Router)

export default new Router({
	routes: [
		{
			path: '/',
			redirect:'about'
		},
		{
			path: '/',
			name: 'index',
			component: index,
			children: [  
				{path: '/about',component: about},
				{
					path: '/message',
					component: message,
					children: [ 
						{path: 'news',component: news},
					]
				}
			]
		}
	]
})

index.vue

<template>
	<div>
		<router-link to="/about">关于我们</router-link>  
		<router-link to="/message">新闻资讯</router-link> 
		<div class="indexcnt">
		<keep-alive> <router-view></router-view></keep-alive>
		</div>
	</div>
</template>
<script>export default {}</script>
<style lang="scss">
.indexcnt{
	border:1px solid #ccc;
	background-color: #ccc;
	color: #fff;
}
</style>

about.vue

<template>
	<div><h1>关于我们页面</h1><input type="tetx" name="name">
	</div>
</template>
<script>export default {}</script>
<style scoped lang="scss">
</style>

message.vue

<template>
	<div>
		<h1>新闻资讯页面</h1>
		<router-link to="/message/news">新闻信息</router-link>
		<div class="messagecnt">
			<router-view></router-view>
		</div>
	</div>
</template>
<script>
export default {}
</script>
<style lang="scss">
.messagecnt{
	background-color: #fff;
	color: #333;
}
</style>

news.vue

<template>
	<div>
		<h2>新闻列表</h2> 
		<ul class="ulSty">  <li v-for="item in news">{{item.title}}</li></ul>
	</div>
</template>

<script>
export default {
	data () {
		return {
			news:[
				{"id":"01","title":'新闻列表1'},
				{"id":"02","title":'新闻列表2'},
				{"id":"03","title":'新闻列表3'},
				{"id":"04","title":'新闻列表4'}
			]
		}
	}
}
</script>
<style lang="scss">
.ulSty{
	li{
		list-style-type: none;
	}
}
</style>

(三).缓存路由<keep-alive> 

语法:

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

1.router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index'
import about from '@/components/about'
import user from '@/components/user'

Vue.use(Router)

export default new Router({
	routes: [
		{
			path: '/',
			redirect:'about'
		},
		{
			path: '/',
			name: 'index',
			component: index,
			children: [  
				{path: '/about',name: '关于我们',component: about},
				{path: '/user',name: '用户信息',component: user}
			]
		}
	]
})

2.user.vue

<template>
	<div>
		<h1>User:</h1>
		用户信息
	</div>
</template>

<script>
export default {
}
</script>

<style scoped lang="scss">
</style>

3.about.vue

<template>
	<div>
		<h1>about:</h1>
		<input type="tetx" name="name">
	</div>
</template>

<script>
export default {
}
</script>

<style scoped lang="scss">
</style>

4.index.vue

<template>
	<div>
		<router-link to="/about">关于我们</router-link>  
		<router-link to="/user">用户信息</router-link> 
		<keep-alive> 
			<router-view></router-view>
		</keep-alive>
	</div>
</template>

<script>
export default {
}
</script>
<style lang="scss"></style>

(三).命名路由

通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候

const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

以下这两种方式都会把路由导航到 /user/123 路径。

要链接到一个命名路由,可以给 router-link 的 to 属性传一个对象:
     <router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

这跟代码调用 router.push() 是一回事:
     router.push({ name: 'user', params: { userId: 123 }})

(四).命名视图----多个<router-view></router-view>

例如创建一个布局,有 sidebar(侧导航) 和 main(主内容) 两个视图,这个时候命名视图就派上用场了。

注意:在<router-view></router-view>要加 class="view"   还要标志a ,b  

1.app.vue
<div id="app">
  <router-link to="/">点击显示多个内容</router-link>
  <router-view class="view one"></router-view>
  <router-view class="view two" name="a"></router-view>
  <router-view class="view three" name="b"></router-view>
</div>

2.router.js
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
const Baz = { template: '<div>baz</div>' }
const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '/',
      components: {
        default: Foo,//默认显示
        a: Bar,
        b: Baz
      }
    }
  ]
})

new Vue({
	router,
  el: '#app'
})

查看列子

(五).编程式的导航

实例中定义一个方法,这个方法绑定在标签上,然后就设置路由跳转。

语法 this.$router.history.push('要跳转路由的地址')

小小demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .active{
            color:red;
        }
    </style>
</head>
<body>
<div id="app">
    <!--编程时导航-->
    <button @click="goHome">去首页</button>
    <button @click="goList">去列表</button>
    <router-view></router-view>
</div>
</body>
<script src="node_modules/vue/dist/vue.js"></script>
<script src="node_modules/vue-router/dist/vue-router.js"></script>
<script>
    let home={
        template:'<div>home</div>'
    };
    let list={
        template:'<div>list</div>'
    }
    const routes=[
        {path:'/home',component:home},
        {path:'/list',component:list}
    ]

    let router=new VueRouter({
        routes:routes,
        linkActiveClass:'active'
    });
    //默认加载第一个路径
    router.push("/home");
    let vm=new Vue({
        el:"#app",
        methods:{
            //编程时导航
            goHome(){
                //页面跳转,push是增加到历史管理
               this.$router.history.push('/home')
                //go表示前进后退
                //this.$router.history.go(-1)
            },
            goList(){
                this.$router.history.push('/list')
                //将当前历史管理替换成list
                //this.$router.history.replace('/list')
            }
        },
        // 会在实例中提供两个属性this.$route(属性),this.$router(方法);
        router:router,


    })
</script>
</html>

(六).重定向和别名

1.重定向:重定向也是通过 routes 配置来完成,
  意思是,当用户访问 /a时,URL 将会被替换成 /b,然后匹配路由为 /b

1.下面例子是从 /a 重定向到 /b:
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

2.重定向的目标也可以是一个命名的路由:
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

3.动态返回重定向目标:
const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

注意动态返回重定向目标--》首先参数解构,获取hash、params、query,然后根据获取值进行逻辑判断之后动态路由重定向。这里的return值是path值,而不是params值,必须是一个已经存在的path才能进行路由重定向。而且这个path不能使自身,因为作为一个重定向路由跳转到自身还要继续重定向,就会进行一个死循环。

2.别名:是为让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

(七).路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性。使用 props 将组件和路由解耦

1.props 配置:

    1.布尔模式
		如果 props 被设置为 true,route.params 将会被设置为组件属性。
		{ path: '/user/:id', component: User, props: true },

   2.对象模式
		如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。
		
	const router = new VueRouter({
	  routes: [
		{ path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
	  ]
	})
	
	3.函数模式
    你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。
	
	const router = new VueRouter({
	  routes: [
		{ path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
	  ]
	})
	URL /search?q=vue 会将 {query: 'vue'} 作为属性传递给 SearchUser 组件。

2.路由路径携带参数

1.配置路由
  children: [
    {
      path: 'mdetail/:id',
      component: messageDetail
    }
  ]
2.路由路径
  <router-link :to="'/home/message/mdetail/'+m.id">{{m.title}}</router-link>
3.路由组件中读取请求参数
  this.$route.params.id

实例:基于嵌套路由:vue项目中路由配置小案例

补充:

router/index.js

import Vue from 'vue'
import Router from 'vue-router'
import index from '@/components/index'

import about from '@/components/about'
import message from '@/components/message'


import news from '@/components/news'
import newdetail from '@/components/newdetail'

Vue.use(Router)

export default new Router({
	routes: [
		{
			path: '/',
			redirect:'about'
		},
		{
			path: '/',
			name: 'index',
			component: index,
			children: [  
				{path: '/about',component: about},
				{
					path: '/message',
					component: message,
					children: [ 
						{
							path: 'news',
							component: news,
							children:[
								{path: 'newdetail/:id',component: newdetail}
							]
						},
					]
				}
			]
		}
	]
})

news.vue:

<template>
	<div>
		<h2>新闻列表</h2> 
		<ul class="ulSty">  
            <li v-for="item in news">
            	<router-link :to="'/message/news/newdetail/'+item.id">{{item.title}}</router-link>
            </li>
        </ul>
        <div class="mewscnt">
			<router-view></router-view>
		</div>
	</div>
</template>
<script>
export default {
	data () {
		return {
			news:[
				{"id":"01","title":'新闻列表1'},
				{"id":"02","title":'新闻列表2'},
				{"id":"03","title":'新闻列表3'},
				{"id":"04","title":'新闻列表4'}
			]
		}
	}
}
</script>
<style lang="scss">
.ulSty li{
	list-style-type: none;
}
.mewscnt{
	background-color: #f00;
	color: #fff;
}
</style>

newdetail.vue

<template>
	<div>
		<p>新闻详情:id为:{{this.$route.params.id}}</p>  
	</div>
</template>
<script>
export default {
}
</script>

<style scoped lang="scss">
</style>

vue-router 路由组件传参

(八). 用 vue-route实现导航守卫

导航守卫表示路由正在发生改变。正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

 用 vue-route实现导航守卫

(九).路由元信息

定义路由的时候可以配置 meta 字段:
routes: [
    {
      path: '/foo',
      component: Foo,
      children: [
        {
          path: 'bar',
          component: Bar,
          // a meta field
          meta: { requiresAuth: true }
        }
      ]
    }
  ]

 routes 配置中的每个路由对象为 路由记录。路由记录可以是嵌套的,因此,当一个路由匹配成功后,他可能匹配多个路由记录。

一个路由匹配到的所有路由记录会暴露为 $route 对象(还有在导航守卫中的路由对象)的 $route.matched 数组。因此,我们需要遍历 $route.matched 来检查路由记录中的 meta 字段。

下面例子展示在全局导航守卫中检查元字段:
router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.requiresAuth)) {
    // this route requires auth, check if logged in
    // if not, redirect to login page.
    if (!auth.loggedIn()) {
      next({
        path: '/login',
        query: { redirect: to.fullPath }
      })
    } else {
      next()
    }
  } else {
    next() // 确保一定要调用 next()
  }
})

(十).过渡动效

<transition>
  <router-view></router-view>

</transition>

<transition> 的所有功能 

(十 一).滚动行为

使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。 vue-router 能做到,而且更好,它让你可以自定义路由切换时页面如何滚动。

注意: 这个功能只在支持 history.pushState 的浏览器中可用

(十 二).路由懒加载

当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

(1).异步组件模式

const Foo = resolve => {
  // require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
  // (代码分块)
  require.ensure(['./Foo.vue'], () => {
    resolve(require('./Foo.vue'))
  })
}

(2).Amd风格的require模式

(代码分块的语法)

const routes = [
    {
        path: '',
        component: resolve => require(['./index.vue'],resolve),
    }, {
        path: '/user',
        component: resolve => require(['./user.vue'],resolve),
    }];
ensure模式写起来有点繁琐,我更倾向于后面一种写法。

(3).amd 与 ensure 区别

1.require-amd
	说明: 同AMD规范的require函数,使用时传递一个模块数组和回调函数,模块都被下载下来且都被执行后才执行回调函数
	语法: require(dependencies: String[], [callback: function(…)])
	参数
	dependencies: 模块依赖数组
	callback: 回调函数

2.require-ensure
	说明: require.ensure在需要的时候才下载依赖的模块,当参数指定的模块都下载下来了(下载下来的模块还没执行),便执行参数指定的回调函数。require.ensure会创建一个chunk,且可以指定该chunk的名称,
		如果这个chunk名已经存在了,则将本次依赖的模块合并到已经存在的chunk中,最后这个chunk在webpack构建的时候会单独生成一个文件。
	语法: require.ensure(dependencies: String[], callback: function([require]), [chunkName: String])
	dependencies: 依赖的模块数组
	callback: 回调函数,该函数调用时会传一个require参数
	chunkName: 模块名,用于构建时生成文件时命名使用

注意点:requi.ensure的模块只会被下载下来,不会被执行,只有在回调函数使用require(模块名)后,这个模块才会被执行。

(十 三).API

vue-router 常用API

(十 四).注意点

1.默认路由 redirect   


2.缓存路由<keep-alive>

在<keep-alive> 里面放<router-view>。

Logo

前往低代码交流专区

更多推荐