vue学习笔记05(vue-router)

目录

一、安装路由

二、在项目中引入

三、使用路由

四、路由组件传参

1、动态路由

2、props路由组件传参

五、嵌套路由配置

六、别名

七、History模式

八、编程式导航

1、不带参数

2、带参数(params和query)

 九、路由导航守卫

 1、全局前置守卫

2、全局后置钩子

3、路由独享守卫

4、组件内的守卫(3个)

5、路由元信息


在vue中,对页面的管理用到的是路由(vue-router)

路由作用:完成页面的跳转,来管理页面

在项目中安装路由可以通过vue脚手架安装,也可以手动进行安装配置,这里展示的是手动安装

一、安装路由

npm install --save vue-router

二、在项目中引入

1、在src目录下,创建router文件夹,里面写入路由相关的配置

// 引入vue
import Vue from 'vue'
// 引入路由
import VueRouter from 'vue-router'
// 引入需要跳转的页面
import Home from '@/views/Home.vue'

// 通过.use()方法使用路由
Vue.use(VueRouter)

// routes:对页面的管理(通过数组中套对象的形式)
const routes = [
  {
    // 跳转的路径
    path: '/home',
    // 路由组件的名字
    name: 'Home',
    // 跳转的组件
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // 异步加载
    component: () => import('@/views/About.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

2、在main.js入口文件中引入router,并挂载到vue原型上

import Vue from 'vue'
import App from './App.vue'
// 引入配置的路由文件
import router from './router'

Vue.config.productionTip = false

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

三、使用路由

1、<router-view></router-view>

只配置完路由信息后,在地址栏输入需要跳转的路径,页面是跳转不过去的,需要在组件中写上路由的出口:<router-view></router-view>,有了出口,路由就能正常跳转显示了

2、<router-link to="/xxx">xxx</router-link>

router-link标签和a标签的作用是一样的,用于页面跳转,to属性写的是需要跳转的路径

四、路由组件传参

路由组件传参分两种:动态路由和props

1、动态路由

在页面跳转中,是可以携带参数的

在router目录下的index.js中的路径参数要写成动态的

const routers = [
    {
        // 动态路径参数,以冒号开头
        path: '/home/:name/:id',
        name: 'home',
        component: () => import('./xxx')
    }
]

组件中的router-link的to属性变成动态属性 里面写成对象

有两个参数: :to="{name + params}"

参数1:name是路由组件的名字

参数2:params是传递的参数

例如:

<!-- :to="{name + params}"
    参数1: name  name就是每个路由组件的名字
    参数2: params  path: '/home/:name/:id'  后面跟/:的值
          params:{name:'tian',id:'123'}
-->
<router-link :to="{name:'home', params:{name:'tian',id:'123'} }">User</router-link>

2、props路由组件传参

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

使用props解耦的目的:不要在组件里出现路由的参数

在路由配置中使用props有两种方法

方法1:

const routes = [
    {
        path: '/user/:id',
        component: User,
        // 允许在User组件通过props传参
        props: true
    }
]

方法2: 函数方式

const routers = [
    {
        path: '/user/:id',
        component: User,
        props: route => ({id: route.params.id})
    }
]

 在组件中用props写入需要传递的参数

export default {
    props: ['id', 'name']        
}

五、嵌套路由配置

一个路由组件中可能有二级,三级子路由,如果要进行跳转,也需要对子路由进行配置。

在对子路由的配置中经常用到redirect重定向:在父级添加,路由组件的默认显示路径。

const routes = [
    {
        path: "/about",
        name: "about",
        component: () => import("../views/AboutView.vue"),
        // 重定向   /about/us为默认路径
        redirect: "/about/us",
        // children子级(子路由)
        children: [
            {
                // 二级导航的路径不要加 / 
                path: "us",
                // name可以不写
                component: () => import("../views/AboutSub/AboutUS.vue")
            },
            {
                path: "info",
                component: () => import("../views/AboutSub/AboutInfo.vue")
            }
        ]
    }
]

六、别名

别名的意思是:/a的别名是/b, 也就是说, 当用户访问/b时, url会保持为/b, 但是路由匹配则是/a, 就像用户访问/a一样(组件没变,但地址变了)

用途:多个功能共享一个组件。给用户感觉跳转到新界面了,但其实还是同一个组件。

const router = new VueRouter({
    routes: [
        {
            path: '/about',
            component: About,
            // 访问/b显示的是About组件
            alias: '/b'
        }
    ]
})

七、History模式

Hash模式: 路径带井号 #

History模式:路径不带 #

语法配置:

const router = new VueRouter({
    mode: 'history',
    routes
})

八、编程式导航

在上面的<router-link></router-link> 是声明式导航/标签式导航。

所谓的编程式导航,就是通过js来控制跳转,借助router的实例方法: router.push()。在vue实例内部, 可以通过 $router 访问路由实例。因此可以调用 this.$router.push。

$route:一般获取路由信息(路径,query,params)
$router:一般进行编程式导航进行路由跳转(push|replace) push与replace的区别在于能否记录历史记录

编程式导航的路由跳转也分了带参和不带参

1、不带参数

// 字符串
this.$router.push('/home')
// 对象
this.$router.push({ path: '/home' })

2、带参数(params和query)

携带的参数分为params参数和query参数

(1)params参数:属于路径当中的一部分,需要注意:在配置路由的时候,需要占位 

写法(/abc):/search/abc

注意:命名的路由跳转,传参 name只能和params搭配使用;path不能和params一起使用

this.$router.push({
    name: 'user',  // 要跳转的组件名
    // 都是跳转到user页面,params只是路径地址后面的参数不同
    params: {
        // 参数需要在路由配置的路径中进行占位
        uname: 'admin',
        id:123
    }
})

// path路径跳转 拼接path路径
this.$router.push({
    path: '/user/admin/123'
})

(2)query参数:不属于路径当中的一部分,类似于ajax中的queryString  ?号的部分 

写法(?k=v&kv=):/search?k=v&kv=,不需要占位 

// 第一种:字符串形式
this.$router.push('/search/'+this.keyword+'?k='+this.keyword.toUpperCase());
// 第二种:模版字符串
this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`);

query参数也可以写成对象的形式,例如

this.$router.push({ path: '/about', query: { plan: 'private' } })

最后的路径会变成:/register?plan=private

:路由传递参数(对象写法)path是否可以结合params参数一起使用?

this.$router.push({
    path: 'search',
    params: {keyword: this.keyword},
    query: {k:this.keyword.toUpperCase()}
})

路由跳转传参的时候,对象的写法可以是name、path形式,但需要注意的是,path这种写法不能与params参数一起使用

 九、路由导航守卫

路由守卫作用:拦截作用

1、全局前置守卫

2、全局后置钩子

3、路由独享守卫

4、组件内的守卫

5、路由元信息

 1、全局前置守卫

使用router.beforeEach() 注册一个全局前置守卫,回调里有三个参数

参数1 to:Route: 即将要进入的目标 路由对象

参数2 from: Route: 当前导航正要离开的路由

参数3 next: Function: 一定要调用该方法来 resolve 这个钩子。执行效果依赖next方法的调用参数。next是放行, 一定要有。

注意:只要发生路由跳转,都会被拦截,都会走全局前置守卫

// 在router目录下index.js中
router.beforeEach((to,from,next) => {
  // 对参数1,2进行打印
  console.log(to);
  console.log(from);
  // 一定要有next放行
  next();
})

可以看到to,from打印的结果:里面包含了路径,路由名字,参数等

 1.next(): 进行管道中的下一个钩子。如果全部钩子执行完了, 则导航的状态就confirmed(确认的)。
2.next(false): 中断当前的导航。如果浏览器的url改变了(可能是用户手动或浏览器后退按钮),
那么url地址会重置到from路由对应的地址。
3.next('/')或next({ path:'/' }): 跳转的一个指定的页面。
4.next(error):如果传入next的参数是一个Error实例, 则导航会被终止且该错误会被传递给router.onError()注册过的回调。

例:如果当前不是登录页,就跳转到登录页

router.beforeEach((to, from, next) => {
    // 如果不是Login页面就让它跳转到Login;如果已经是Login页面,就放行
    if (to.name !== 'Login') next({ name:'Login' })
    else next()
})

2、全局后置钩子

可以注册全局后置钩子,和守卫不同的是,这些钩子不会接受 next 函数,也不会改变导航本身

router.afterEach((to, from) => {
    ...
})

3、路由独享守卫

可以在路由配置上直接定义 beforeEnter 守卫

路由独享守卫和全局前置守卫不一样的是:独享守卫只作用于自己的单个路由组件,而全局前置守卫是对所有路由组件生效。

const routes = [
  {
    path: '/about',
    name: 'about',
    component: () => import('../views/AboutView.vue'),
    beforeEnter: (to, from, next) => {
      console.log('路由独享守卫');
      next()
    }
  }
]

4、组件内的守卫(3个)

组件内的守卫:beforeRouteEnter(读不到this),beforeRouteUpdate,beforeRouteLeave

export default {
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // !!! 不能获取组件实例 'this'
    // 因为当守卫执行前,组件实例还没被创建
  },
  // !!!很重要!!!
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例:对于一个带有动态参数的路径 /foo/:id, 在 /foo/1 和 /foo/2 之间跳转的时候
    // 由于会渲染同样的Foo组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 'this'
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 'this'
  }
}

5、路由元信息

路由元信息:定义路由的时候可以配置 mata 字段,标记作用。

例如:一个有网站的首页,订单页,个人中心页面,只有首页不需要登录就能访问,其他页面均需要登录后访问,这时候就需要在配置路由的时候,用meta个需要登录的页面打上标记。

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
    meta: {
      // isLogin为false,不需要登录
      isLogin: false
    }   
  },
  {
    path: '/order',
    name: 'order',
    component: () => import('../views/AboutView.vue'),
    meta: {
      // 为true,则需要登录
      isLogin: true
    }
  },
  {
    path: '/center',
    name: 'center',
    component: () => import('../views/CenterView.vue'),
    meta: {
      isLogin: true
    }
  },
  {
    path: '/login',
    name: 'Login',
    component: () => import('../views/Login.vue')
  }
]

下面是全局前置守卫的配置:

router.beforeEach((to, from, next) => {
  // 如果meta的isLogin字段为true,则必须要登录才能进入
  if (to.meta.isLogin) {
    // 再判断用户是否登录
    let user = '' // 判断用户是否有登录信息
    // 已登录,放行
    if (user) {
      next()
    } 
    // 未登录,到登录页
    else {
      next('/login')
    }
  } 
  // 不需要登录的页面,直接放行
  else {
    next()
  }
})

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值