用法
vue-router CDN
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
快速开始
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="./js/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<!-- router-link标签默认会被渲染成一个a标签 -->
<router-link to="/home">home</router-link>
<router-link to="/subpage">Subpage</router-link>
<router-view></router-view>
</div>
<script>
const Home = {
template: '<div>首页</div>'
}
const News = {
template: '<div>子页</div>'
}
var router = new VueRouter({
// mode: 'hash',
mode: 'history',
routes: [{
path: '/home',
component: Home
}, {
path: '/subpage',
component: Subpage
}
]
});
var vm = new Vue({
el: '#app',
// 将路由添加到Vue中
router,
});
</script>
</body>
</html>
vue-router 示例
src/components/Content.vue
<template>
<h1>内容页</h1>
</template>
<script>
export default {
name: "Content"
}
</script>
<style scoped>
</style>
src/components/Main.vue
<template>
<h1>首页</h1>
</template>
<script>
export default {
name: "Main"
}
</script>
<style scoped>
</style>
src/router/index.js
import Vue from 'vue'
import VueRouter from "vue-router";
import Content from "../components/Content";
import Main from "../components/Main";
//安装VueRouter
Vue.use(VueRouter);
//配置导出路由
export default new VueRouter({
routes:[
{
//路由的路径,相当于后端的 @RequestMapping
//路由只要生效,就会跳到指定的组件
path:'/content',
name:'content',
//跳转的组件,组件也要导入
component:Content
},{
path:'/main',
name:'main',
component: Main
}
]
});
src/App.vue
<template>
<div id="app">
<h1>Vue-Router</h1>
<router-link to="/main">首页</router-link>
<router-link to="/content">内容页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
}
</script>
<style>
</style>
src/main.js
import Vue from 'vue'
import App from './App'
import router from './router' //定位到路径,自动扫描index.js路由配置文件
Vue.config.productionTip = false;
new Vue({
el: '#app',
//配置路由
router,
components: { App },
template: '<App/>'
})
路由嵌套
可以结合 ElementUI
实现侧边栏的一二级菜单
export default new VueRouter({
routes:[
{
path:'/',
name:'',
conponents:,
children:[
{
path:'/',
name:'',
conponents:,
}
]
}
]
})
注意:所有的元素都不能在根节点下
代码示例
实际应用界面,通常由多层嵌套的组件组合而成。 比如,我们 新闻
组件中,还嵌套着 国内
和 国外
组件,那么URL对应就是 /news/guonei
和 /news/guowai
。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<!-- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> -->
<script src="./js/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<!-- 使用 router-link 组件来导航. to属性指定导航地址-->
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
</p>
<!-- 路由出口(路由匹配到的组件将渲染在这里) -->
<router-view></router-view>
</div>
<script>
// 1. 定义(路由)组件。
const Home = {
template: `<div>首页</div>`
}
const News = {
template: `<div>
<p>
<router-link to="/news/guonei">国内新闻</router-link>
<router-link to="/news/guoji">国际新闻</router-link>
</p>
<router-view></router-view>
</div>`
}
const GuoNeiNews = {
template: `<div>上海最美公厕:室内长大树,墙壁会发光</div>`
}
const GuoJiNews = {
template: `<div>在英国旅游坐巴士,“return ticket”真..</div>`
}
// 2. 定义路由规则对象(每个路由应该映射一个组件)
const routes = [{
path: '/home',
component: Home,
}, {
path: '/news',
component: News,
children: [{
path: '/news/guonei',
component: GuoNeiNews
}, {
path: '/news/guoji',
component: GuoJiNews
}
]
},
]
// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
//如果路由规则对象名也为routes,那么就可以简写为 routes
routes: routes
})
var vm = new Vue({
el: '#app',
data: {},
// 将路由添加到Vue中
router,
});
</script>
</body>
</html>
重定向
{
path:'路径',
redirect:'路径'
}
或
{
path:'路径'
redirect:{
name:'路由名'
}
}
传递参数
类似于post方式,参数不会在路由中显示,页面刷新后参数将不存在。利用路由规则中的name跳转。
使用v-bind绑定to属性。to属性的值是一个json对象,此对象有两个属性:name属性和params属性。
name属性就是要路由的对象。所以,在路由规则列表中,每一个路由规则都应用有一个name值。
params属性就是要传递的参数。也是一个json对象。
组件接收参数时,使用 this.$route.params.参数名 的形式。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<router-link :to="{name:'Hello',params:{msg:'mahe666'}}">链接</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Hello = {
data(){
return {
msg:''
}
},
template: `<div>hello {{msg}}</div>`,
created(){
this.msg = this.$route.params.msg;
console.log(this.$route.params)
}
}
// 2. 定义路由规则对象(每个路由应该映射一个组件)
const routes = [
{
path: '/hello',
name: 'Hello',
component: Hello,
}
]
// 3. 创建 router 实例,然后传 `routes` 配置
const router = new VueRouter({
//如果路由规则对象名也为routes,那么就可以简写为 routes
routes: routes
})
var vm = new Vue({
el: '#app',
data: {},
// 将路由添加到Vue中
router,
});
</script>
</body>
</html>
类似于get方式,参数会在路由中显示,可以用做刷新后仍然存在的参数。利用路由规则中的path跳转。
to属性的值仍然是一个json对象,但是两个属性变了,一个是path,一个是query。
path属性就是路由地址,对应路由规则中的path值。
query属性就是要传递的参数。也是一个json对象。
组件接收参数时,使用 this.$route.query.参数名
的形式。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
<p>
<router-link :to="{path:'/home',query:{msg:'hello world!'}}">home</router-link>
</p>
<router-view></router-view>
</div>
<script type="text/javascript">
const Home = {
data(){
return{
msg:''
}
},
template: '<div>{{msg}}</div>',
created(){
this.msg = this.$route.query.msg
}
}
const routes = [{
path: '/home',
component: Home
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {},
router
})
</script>
</body>
</html>
编程式路由
利用JS实现路由跳转
<div id="app">
<p>
<button @click="toHome">首页</button>
<button @click="toNews">新闻</button>
<button @click="toLogin">登陆</button>
<button @click="doForward1">前进</button>
<button @click="doForward2">前进</button>
<button @click="doBack1">后退</button>
<button @click="doBack2">后退</button>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首页</div>'
}
const News = {
template: '<div>新闻:</div>'
}
const Login = {
template: '<div>登陆</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes
})
var vm = new Vue({
el: '#app',
data: {},
router,
methods:{
toHome(){
//无参数时,push方法中直接写路由地址
this.$router.push('/home');
},
toNews(){
//有参数时,push方法中写一个json对象
this.$router.push({path:'/news',query:{name:'zhangsan'}});
},
toLogin(){
this.$router.push('/login');
},
doForward1(){
this.$router.forward();
},
doForward2(){
this.$router.go(1);
},
doBack1(){
this.$router.back();
},
doBack2(){
this.$router.go(-1);
}
}
})
</script>
通过watch实现路由监听
通过watch属性设置监听 $route
变化,达到监听路由跳转的目的。
在上面代码中添加watch监听:
watch: {
// 监听路由跳转。
$route(newRoute, oldRoute) {
console.log('watch', newRoute, oldRoute)
}
}
导航守卫
路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。
对此,vue-router
提供了实现导航守卫(navigation-guards)的功能。
你可以使用 router.beforeEach
注册一个全局前置守卫:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
每个守卫方法接收三个参数:
to
:即将要进入的目标路由对象(去哪里),可以使用to.path
获取即将要进入路由地址。from
:当前导航正要离开的路由对象(从哪来),可以使用from.path
获取正要离开的路由地址。next
:一个函数,表示继续执行下一个路由。(如果没有next,将不会进入到下一个路由)
下面例子中实现了如下功能:
- 列举需要判断登录状态的 “路由集合”,当跳转至集合中的路由时,如果是
未登录状态
,则跳转到登录页面 - 当直接进入登录页面
LoginPage
时,如果是已登录状态
,则跳转到首页HomePage
;
<div id="box">
<p>
<router-link to="/home">home</router-link>
<router-link to="/news">news</router-link>
<router-link to="/music">music</router-link>
<router-link to="/login">login</router-link>
</p>
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router/dist/vue-router.js"></script>
<script type="text/javascript">
const Home = {
template: '<div>首页</div>'
}
const News = {
template: '<div>新闻</div>'
}
const Music = {
template: '<div>音乐</div>'
}
const Login = {
template: '<div>登录</div>'
}
const routes = [{
path: '/',
component: Home
}, {
path: '/home',
component: Home
}, {
path: '/news',
component: News
}, {
path: '/music',
component: Music
}, {
path: '/login',
component: Login
}]
const router = new VueRouter({
routes // (缩写)相当于 routes: routes
})
var vm = new Vue({
el: '#box',
data: {},
router
})
// 添加全局路由守卫
router.beforeEach((to, from, next) => {
//创建守卫规则集合(这里表示'/news'与'/music'路径是需要权限验证的)
const nextRoute = ['/news', '/music'];
// 使用isLogin来模拟是否登录
let isLogin = false;
// 判断to.path(要跳转的路径)是否是需要权限验证的
if (nextRoute.indexOf(to.path) >= 0) {
if (!isLogin) {
router.push({
path: '/login'
})
location.reload(); //必须要有
}
}
// 已登录状态;当路由到login时,跳转至home
if (to.path === '/login') {
if (isLogin) {
router.push({
path: '/home'
});
location.reload();
}
}
next(); //必须要有
});
</script>
路由模式
路由模式有两种
hash
:路径带#,如http://localhost/#/login
history
:路径不带#,如http://localhost/login
修改路由配置,代码如下
export default new Router({
mode:'history',
routes:[
]
})
通配页
{
path:'*', //除了定义好的,就走这里
component:
}