vue使用:VueRouter
目录:
VueRouter实现原理
原来的页面切换是通过a标签的href再次发起http请求实现实现
VueRouter的页面切换是window.onhashchange实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<a href="#/home">首页</a>
<a href="#/login">登录</a>
<a href="#/register">注册</a>
</div>
<script>
let oDiv = document.getElementById("app");
window.onhashchange = function () {
console.log(location.hash);
// vue-router的实现原理是根据锚点值的改变
// 对页面进行切换
switch (location.hash) {
case "#/login":
oDiv.innerHTML = `<h3 class='login'>这是登录页面</h3>`;
break;
case "#/register":
oDiv.innerHTML = `<h3 class='register'>这是注册页面</h3>`;
break;
default:
oDiv.innerHTML = `<h3 class='home'>这是首页</h3>`;
break;
}
};
</script>
</body>
</html>
VueRouter安装和使用
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app">
</div>
<script>
let Home = {
template: `
<div>这是首页</div>
`
};
let Login = {
template: `
<div>登录页面</div>
`
};
let Register = {
template: `
<div>注册页面</div>
`
};
let App = {
template: `
<div>
<router-link to="/home">首页</router-link>
<router-link to="/login">登录</router-link>
<router-link to="/register">注册</router-link>
<router-view></router-view>
</div>
`
};
// 2. 在vue中中使用vue-router对象
Vue.use(VueRouter);
// 3. 创建一个vue-router对象
let router = new VueRouter({
// 此处要特别注意是routes,不是routers
routes: [
{
path: '/home',
component: Home,
},
{
path: "/login",
component: Login
},
{
path: "/register",
component: Register,
}
]
});
// 4. 在vue实例中使用新创建的vue-router对象
new Vue({
el: "#app",
template: `<app></app>`,
components: {
"app": App,
},
router: router
})
</script>
</body>
</html>
跳转之后会有
<a href="#/login" class="router-link-exact-active router-link-active">登录</a>
显示的组件会有router-link-exact-active和router-link-active
VueRouter命名路由
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let Login = {
template: `
<div>登录页面</div>
`
};
let Register = {
template: `
<div>注册页面</div>
`
};
let App = {
template: `
<div>
<router-link :to="{ name: 'login'}">登录</router-link>
<router-link :to="{ name: 'register'}">注册</router-link>
<router-view></router-view>
</div>
`
};
// 在vue中中使用vue-router对象
Vue.use(VueRouter);
// 创建一个vue-router对象
let router = new VueRouter({
// 此处要特别注意是routes,不是routers
routes: [
{
name: 'login',
path: "/login",
component: Login
},
{
name: 'register',
path: "/register",
component: Register,
}
]
});
// 在vue实例中使用新创建的vue-router对象
new Vue({
el: "#app",
template: `<app></app>`,
components: {
"app": App,
},
router: router
})
</script>
</body>
</html>
VueRouter路由参数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
// 常用的两种查询方式
// xxx.html/user/1
// xxx.html/user/id=1
let userParams = {
template: `
<div>用户一信息</div>
`
};
let userQuery = {
template: `
<div>用户二信息</div>
`
};
let App = {
template: `
<div>
<router-link :to="{ name: 'userParams', params: { userId: 1} }">用户一</router-link>
<router-link :to="{ name: 'userQuery', query: { userId: 2 } }">用户二</router-link>
<router-view></router-view>
</div>
`,
};
// 在vue中使用vue-router
Vue.use(VueRouter);
// 创建一个VueRouter对象
let router = new VueRouter({
routes: [
{
name: 'userParams',
path: '/users/:userId',
component: userParams
},
{
name: 'userQuery',
path: '/users',
component: userQuery,
}
]
});
// 在vue中使用vue-router
new Vue({
el: "#app",
template: `<app></app>`,
components: {
'app': App,
},
router: router
})
</script>
</body>
</html>
params会将参数以uri的方式拼接
<a href="#/users/1" class="router-link-exact-active router-link-active">用户一</a>
userQuery会将参数以参数的方式传入
<a href="#/users?userId=2" class="">用户二</a>
VueRouter路由参数的实现
在每个组件都添加一个created来看一下
created () {
console.log('this: ', this);
console.log(this.$route);
console.log(this.$route.params.userId);
}
浏览器console显示
this: ft {_uid: 0, _isVue: true, $options: {…}, _renderProxy: ft, _self: ft, …}
{name: "userParams", meta: {…}, path: "/users/1", hash: "", query: {…}, …}
fullPath: "/users/1"
hash: ""
matched: Array(1)
0: {path: "/users/:userId", regex: /^\/users\/((?:[^\/]+?))(?:\/(?=$))?$/i, components: {…}, instances: {…}, name: "userParams", …}
length: 1
__proto__: Array(0)
meta: {}
name: "userParams"
params: {userId: "1"}
userId: "1"
__proto__: Object
path: "/users/1"
query: {}
__proto__: Object
1
this: a {_uid: 4, _isVue: true, $options: {…}, _renderProxy: a, _self: a, …}
{name: "userParams", meta: {…}, path: "/users/1", hash: "", query: {…}, …}
fullPath: "/users/1"
hash: ""
matched: Array(1)
0: {path: "/users/:userId", regex: /^\/users\/((?:[^\/]+?))(?:\/(?=$))?$/i, components: {…}, instances: {…}, name: "userParams", …}
length: 1
__proto__: Array(0)
meta: {}
name: "userParams"
params: {userId: "1"}
userId: "1"
__proto__: Object
path: "/users/1"
query: {}
__proto__: Object
1
this: a {_uid: 4, _isVue: true, $options: {…}, _renderProxy: a, _self: a, …}
{name: "userQuery", meta: {…}, path: "/users", hash: "", query: {…}, …}
fullPath: "/users?userId=2"
hash: ""
matched: Array(1)
0: {path: "/users", regex: /^\/users(?:\/(?=$))?$/i, components: {…}, instances: {…}, name: "userQuery", …}
length: 1
__proto__: Array(0)
meta: {}
name: "userQuery"
params: {}
path: "/users"
query: {userId: 2}
__proto__: Object
undefined
VueRouter子路由
使用children关键字
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let Home = {
template: `
<div class="home">这是首页</div>
`
};
let Courses = {
template: `
<div class="courses">课程页面
<div class="details">
<router-link to="details">课程详情</router-link>
<router-link to="students">学员故事</router-link>
<router-view></router-view>
</div>
</div>
`
};
let Details = {
template: `
<div>课程详情页</div>
`
};
let Students = {
template: `
<div>学员故事</div>
`
};
let App = {
template: `
<div>
<router-link to="/">首页</router-link>
<router-link to="/courses">课程页面</router-link>
<router-view></router-view>
</div>
`
};
let routes = [
{
path: '/',
component: Home
},
{
path: '/courses',
component: Courses,
children: [
{
path: 'details',
component: Details,
},
{
path: 'students',
component: Students
}
]
}
];
Vue.use(VueRouter);
let router = new VueRouter({
routes: routes,
});
new Vue({
el: "#app",
template: `<app></app>`,
router: router,
components: {
'app': App,
}
})
</script>
</body>
</html>
可以点击课程详情,发现到了/details
,什么显示都没有,如果直接访问/courses/details
就有组件的数据了,这样写uri没有添加到上一级uri后边,而是单独生成uri,这里就需要append来实现
VueRouter子路由append
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let Home = {
template: `
<div class="home">这是首页</div>
`
};
let Courses = {
template: `
<div class="courses">课程页面
<div class="details">
<router-link :to="{ name: 'details' }">课程详情</router-link>
<router-link :to="{ name: 'students' }">学员故事</router-link>
<router-view></router-view>
</div>
</div>
`
};
let Details = {
template: `
<div>课程详情页</div>
`
};
let Students = {
template: `
<div>学员故事</div>
`
};
let App = {
template: `
<div>
<router-link to="/">首页</router-link>
<router-link to="/courses">课程页面</router-link>
<router-view></router-view>
</div>
`
};
let routes = [
{
path: '/',
component: Home
},
{
path: '/courses',
component: Courses,
children: [
{
name: 'details',
path: 'details',
component: Details,
},
{
name: 'students',
path: 'students',
component: Students
}
]
}
];
Vue.use(VueRouter);
let router = new VueRouter({
routes: routes,
});
new Vue({
el: "#app",
template: `<app></app>`,
router: router,
components: {
'app': App,
}
})
</script>
</body>
</html>
如果使用append会造成一个问题就是会一直加
VueRouter路由重定向redirect
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let Home = {
template: `
<div class="home">这是首页</div>
`
};
let Courses = {
template: `
<div class="courses">课程页面
<div class="details">
<router-link :to="{ name: 'details' }">课程详情</router-link>
<router-link :to="{ name: 'students' }">学员故事</router-link>
<router-view></router-view>
</div>
</div>
`
};
let Details = {
template: `
<div>课程详情页</div>
`
};
let Students = {
template: `
<div>学员故事</div>
`
};
let App = {
template: `
<div>
<router-link to="/">首页</router-link>
<router-link to="/courses">课程页面</router-link>
<router-view></router-view>
</div>
`
};
let routes = [
{
path: '/',
component: Home
},
{
path: '/courses',
component: Courses,
children: [
{
name: 'details',
path: 'details',
component: Details,
},
{
name: 'students',
path: 'students',
redirect: '/courses/details',
component: Students
}
]
}
];
Vue.use(VueRouter);
let router = new VueRouter({
routes: routes,
});
new Vue({
el: "#app",
template: `<app></app>`,
router: router,
components: {
'app': App,
}
})
</script>
</body>
</html>
在student的路由里,增加一个redirect: '/courses/details'
,点击就直接被路由到/courses/details对应的组件了,那个path就不会被生效
VueRouter手动路由
手动路由其实是直接绑定方法,将router对象进行修改,使用this.$router.push('/uri')
let App = {
template: `
<div>
<router-link to="/">首页</router-link>
<button @click="myClick">点击跳转到课程详情页面</button>
<router-view></router-view>
</div>
`,
methods: {
myClick: function () {
this.$router.push('/details');
}
}
};
VueRouter路由钩子函数
路由钩子在路由前生效
router.beforeEach(function (to, from, next) {
next();
}
- 如果next的参数是具体的路径,则跳转到该路径
- 如果next没有被传入参数,则什么都不做,保持原来不变
- 如果next的参数是一个error实例,跳转终止
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
<script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
<div id="app"></div>
<script>
let Home = {
template: `
<div class="home">这是首页</div>
`
};
let Courses = {
template: `
<div class="courses">课程页面
<div class="details">
<router-link :to="{ name: 'details' }">课程详情</router-link>
<router-link :to="{ name: 'students' }">学员故事</router-link>
<router-view></router-view>
</div>
</div>
`
};
let Details = {
template: `
<div>课程详情页</div>
`
};
let Students = {
template: `
<div>学员故事</div>
`
};
let App = {
template: `
<div>
<router-link to="/">首页</router-link>
<router-link to="/courses">课程页面</router-link>
<router-view></router-view>
</div>
`
};
let routes = [
{
path: '/',
component: Home
},
{
path: '/courses',
component: Courses,
children: [
{
name: 'details',
path: 'details',
component: Details,
},
{
name: 'students',
path: 'students',
meta: { redirect_index: true },
component: Students
}
]
}
];
Vue.use(VueRouter);
let router = new VueRouter({
routes: routes,
});
router.beforeEach(function (to, from, next) {
if ( to.meta.redirect_index ) {
next('/');
} else {
next();
}
})
new Vue({
el: "#app",
template: `<app></app>`,
router: router,
components: {
'app': App,
}
})
</script>
</body>
</html>
可以在router的meta中添加变量,也可以使用vuex进行变量的存储
VueRouter在路径中去掉#号
创建的时候指定即可mode为history即可
let router = new VueRouter({
routes: routes,
mode: 'history',
});