vue-----路由
使用vue-cli安装不需要另外安装路由,只需要在安装时候选择Manually select features,然后选到router按下空格就行**
- vue路由分为前端路由和后端路由
路由配置
Router
Views
import router from "./router"
new Vue({
router,
render: h => h(App)
}).$mount('#app')```
初始化路由
在路由模块的入口文件index.js配合router
```//引入vue
import Vue from 'vue';
//引入router
import VueRouter from 'vue-router'
//引入组件
import Home from "../xxx/Home.vue";
import About from "../xxx/About.vue"
//全局配置路由
Vue.use(VueRouter)
//集成路由
const routes = [
{
//路径
path:"/",
//路由名称
name:"home",
//路由加载的组件
component:Home
},
{
path:"/about",
name:"about",
component:About,
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router```
#### 嵌套路由
嵌套路由用到了children属性,实现嵌套
```//引入vue
import Vue from 'vue';
//引入router
import VueRouter from 'vue-router'
//引入组件
import Home from "../xxx/Home.vue";
import Hot from "../views/Hot.vue";
//全局配置路由
Vue.use(VueRouter)
//集成路由
const routes = [
{
//路径
path:"/",
//路由名称
name:"home",
//路由加载的组件
component:Home,
//嵌套路由
children:[
{
path: "/hot",
name: "hot",
component: Hot
}
]
},
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router```
路由管理下的组件都会加载到一个router-view标签中,在app.vue中有一个最大的router-view标签管理所有组件
```
```
home.vue
```
```
#### 编程式导航
* 在vue实力内部,你可以通过$router访问路由实例,因此你可以调用this.$router.push跳转,这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。
* this.$router.push有两种跳转方式,一个是path+query,另一个是name+params
**path+query**
```this.$router.push({
path:'/hello',
query:{
name:'word',
age:'11'
}
})```
**name+params**
```this.$router.push({
name:'hello',
params:{
name:'word',
age:'11'
}
})```
一般推荐使用path+query进行路由传参
* 使用params带参数,需要对应使用name来指明路径,query带参数,则path,name都可以
* .params带参数跳转,在跳转后页面再进行跳转或刷新都有可能导致数据丢失,建议使用query带参数
* query相当于get请求,页面跳转的时候,可以在地址栏看到请求参数,而params相当于post请求,参数不会再地址栏中显示
* params是路由的一部分,必须要有。query是拼接在url后面的参数,没有也没关系
* params一旦设置在路由,params就是路由的一部分,如果这个路由有params传参,但是在跳转的时候没有传递这个参数,会导致跳转失败或者页面没有内容,比如跳转router1/:id
```正确
错误 ```
#### 命名视图
有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 `sidebar` (侧导航) 和 `main` (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 `router-view` 没有设置名字,那么默认为 `default`。
```
一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components配置 (带上 s):
routes: [
{
path: '/',
components: {
default: Foo,
a: Bar,
b: Baz
}
}
]
})
在这个默认路由下面,
第一个非未命名视图显示Foo组件
第二个name名为a的视图显示Bar组件
name名为b的视图显示Baz组件
下面这个是一个示例
默认视图
a视图
b视图
router配置:
{
path: '/',
name: 'HelloWorld',
component: HelloWorld,
children:[
{
path:'',
components:{
default:List1,
a:List2,
b:List3
}
},
{
path:'list1',
components:{
default:List1,
a:List2,
b:List3
}
},
{
path:'list2',
components:{
default:List2,
a:List1,
b:List3
}
},
{
path:'list3',
components:{
default:List3,
a:List1,
b:List2
}
}
]
}
]
嵌套命名视图
我们也有可能使用命名视图创建嵌套视图的复杂布局。这时你也需要命名用到的嵌套 router-view
组件
path: '/',
// 你也可以在顶级路由就配置命名视图
component: name,
//嵌套路由
children: [{
path: '/emails',
component: UserEmailsSubscriptions
},
{
path: 'profile',
//命名视图
components: {
default: UserProfile,
helper: UserProfilePreview
}
}]
}
重定向
重定向也是通过 routes
配置来完成,下面例子是从 /a
重定向到 /b
:
routes: [
{ path: '/a', redirect: '/b' }
]
})
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }}
]
const router = new VueRouter({
routes: [
{ path: '/a', redirect: to => {
// 方法接收 目标路由 作为参数
// return 重定向的 字符串路径/路径对象
}}
]
})
代码示例:
redirect: to => {
const { hash, params, query } = to
if (query.to === 'foo') {
return { path: '/foo', query: null }
}
if (hash === '#baz') {
return { name: 'baz', hash: '' }
}
if (params.id) {
return '/with-params/:id'
} else {
return '/bar'
}
}
}
导航守卫
vue-router
提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。
全局前置守卫beforeEach
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之
前一直处于 等待中。
你可以使用 router.beforeEach
注册一个全局前置守卫:
let loginStatus = false
const router = [
{
path: '/',
name: 'Home',
component: Home,
//设置meta前往路由是否需要通过守卫
meta: {
isLogin: false
}
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue'),
meta: {
isLogin: false
}
},
{
path: "/mine",
name: "mine",
component: () => import("../views/Mine.vue"),
meta: {
isLogin: true
}
}
]
// 参数分别是 即将进入的页面 正要离开的路由 一定要调用next才能生效
router.beforeEach((to, from, next) => {
// 如果要进入的页面需要登录
if (to.meta.isLogin === true) {
// 如果登录状态为未登录
if (loginStatus === false) {
// 则去登录
next("/login")
} else {
// 否则直接跳转
next()
}
} else {
next()
}
})
路由独享守卫beforeEnter
const routes = [
{
path: "/shoppinglist",
name: "shoppinglist",
component: ShoppingList,
// 设置路由独享守卫
beforeEnter: (to, from, next) => {
// 判断登录状态
if (loginStatus === false) {
next("/login")
} else {
next()
}
}
}
]
组件内守卫beforeRouteLeave
export default {
// 设置组件内守卫beforeRouteLeave
beforeRouteLeave (to, from, next) {
window.console.log(to)
window.console.log(from)
window.alert("真的要离开吗")
next()
}
}
每个守卫方法接收三个参数:
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
-
next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next
方法的调用参数。
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from
路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next
传递任意位置对象,且允许设置诸如 replace: true
、name: 'home'
之类的选项以及任何用在 router-link
的 to
prop 或 router.push
中的选项。
next(error): (2.4.0+) 如果传入 next
的参数是一个 Error
实例,则导航会被终止且该错误会被传递给 router.onError()
注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved。