vue路由的使用

18 篇文章 1 订阅

vue路由的使用

route和router区别

route 是用来获取路由信息的,router是用来操作路由的。

router是vueRouter的一个全局实例对象,包含所有的路由

route是当前激活的路由对象(局部的对象),包含当前url解析得到的数据,可以获取对应的name,path,params,query

this.$router.currentRoute = this.$route

路由跳转

router目录index.js

export default new Router({
  // 默认使用hash模式的路由,地址栏中URL带有 # 形式
  // mode: 'history',
  routes: [
    {
      path: '/Home',
      name: 'Home',
      component: Home
    },
    {
      path: '/About',
      name: 'About',
      component: About
    },
    {
      path: '/News',
      name: 'News',
      component: News
    }
  ]
})
声明式

想在一个页面嵌套子路由,并且不跳转页面的时候,子页面就会渲染在router-view中

  • 无参模式

    //路由入口
    <router-link to="/About">About</router-link>
    //视图出口
    <router-view></router-view>
    
  • 传参模式

    <router-link to="/About?name=xxx">About</router-link>
    
    <router-link to="/About?id=666&title=你好">About3</router-link>
    
    <router-link :to="{
      path: '/About',
      query: {
        id: 666,
        title: '你好'
      }
    }">About4</router-link>
    
    <router-link :to="`/About/${n.aid}`">{{ n.name }} 1</router-link>
    
    <router-link :to="{
      name: 'About',
      params: {
        id: n.aid,
        name: n.name,
      },
    }">
      {{ n.name }} 2
    </router-link>
    
    • query?name=xxx增加显式参数,浏览器地址栏信息会附带参数信息
    • params增加隐式参数
    • 要使用/${n.aid}必须在index.js中增加对应的路由规则。
      {
        path: '/About/:aid',
        name: 'About',
        component: About
      },
      
编程式
  • get第一种,浏览器地址栏信息会附带?name=xxx

    // About
    <button @click="get1">get1</button>
    get1(){
      this.$router.push("/News?name=xcv");
    }
    
    // News
    console.log(this.$route.query);
    {name: 'xcv'}
    
  • get第二种,浏览器地址栏信息会附带?name=xxx

    // About
    <button @click="get2">get2</button>
    get2(){
      this.$router.push({
        path: '/News',
        query: {name: 'xcv'}
      });
    },
    
    // News
    console.log(this.$route.query);
    {name: 'xcv'}
    
  • post

    // About
    post(){
      this.$router.push({
        name: 'News',
        params: {name: 'xcv'}
      });
    }
    
    // News
    console.log(this.$route.params);
    {name: 'xcv'}
    

    post传参刷新会导致数据丢失

    使用this.$route.params接收参数

    URL地址栏传参隐藏

路由重定向

index.js,使用redirect,用户在访问地址 A 的时候,强制用户跳转到地址 C

routes: [
    {
       path: '/',
       redirect: '/Home',
    },
    ...

404路由

routes: [
    ...
    {
      path: '*',
      component: NotFound
    }
]

嵌套路由

index.js,children下的path不带/

export default new Router({
  routes: [
    ...
    {
      path: '/News',
      name: 'News',
      component: News,
      children: [
        {
          path: 'Top',
          name: 'Top',
          component: Top,
        },
        {
          path: 'Bottom',
          name: 'Bottom',
          component: Bottom,
        }
      ]
    },
    ...
  ]
})

News.vue

  • to 写全路径
  • :to 使用"{name: ‘Top’}"
  • path 写全路径
  • name 使用name属性
<button @click="getChild1">getChild1</button>
<button @click="getChild2">getChild2</button>

// 方式1
<router-link to="/News/Top">to-top</router-link>

// 方式2
<router-link :to="{name: 'Top'}">to-top2</router-link>

// 方式3
getChild1(){
  this.$router.push({
    path: '/News/Top'
  });
},

// 方式4
getChild2(){
  this.$router.push({
    name: 'Bottom',
  });
}

动态路由

路由规则中有部分规则是动态变化的,有路由参数
index.js

export default new Router({
  routes: [
    ...
    {
      path: '/About/:aid?',
      name: 'About',
      component: About
    },
    ...
  ]
})

?表示可传可不传,不加?则必须传

Home.vue

<router-link to="/About/123">About2</router-link>

// About.vue 
params: {aid: '123'}
path: "/About/123"

同时加载多个子路由

index.js,children中使用components

export default new Router({
  ...
  routes: [
    {
      path: '/News',
      name: 'News',
      component: News,
      children: [
        {
          path: '',
          components: {
            'Top': Top,
            'Bottom': Bottom
          }
        },
      ]
    },
    ...
  ]
})

News.vue中,router-view使用name属性

// 默认显示的路由
<router-view name="Top"></router-view>
<router-view name="Bottom"></router-view>

push和replace

  • this.$router.push
    跳转到不同的url,但这个方法会向history栈添加一个记录,点击后退会返回到上一个页面

  • this.$router.replace
    跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面,(A----->B----->C 结果B被C替换 A----->C)

    <reouter-link :to="..." replace></router-link>
    
    this.$router.replace({path: '/homo'})
    
    this.$router.push({path: '/homo', replace: true})
    

forward,back和go

  • this.$router.forward()
    路由前进

  • this.$router.back()
    路由后退

  • this.$router.go(n)
    当前页面向前或向后跳转多少个页面,n可为正数可为负数

hash模式和history模式

前端路由的核心,在于 —— 改变视图的同时不会向后端发出请求,hash 模式和 history 模式都属于浏览器自身的特性

默认是hash模式,浏览器localhost:8080/#/Home
history模式,浏览器localhost:8080/Home

export default new Router({
  // 默认使用hash模式的路由,地址栏中URL带有 # 形式
  // mode: 'history',
  routes: [
    ...
  ]
})
hash

路由的哈希模式利用了window.onhashchange事件,也就是哈希值(#后面的值)如果有变化,浏览器并不会重新发起请求,而是会触发 onhashchange 事件

//http://127.0.0.1:8001/01-hash.html?a=100&b=20#/aaa/bbb
location.protocal // 'http:'
localtion.hostname // '127.0.0.1'
location.host // '127.0.0.1:8001'
location.port //8001
location.pathname //'01-hash.html'
location.serach // '?a=100&b=20'
location.hash // '#/aaa/bbb'
  • hash变化会触发网页跳转,即浏览器的前进和后退。
  • hash 可以改变 url ,但是不会触发页面重新加载(hash的改变是记录在 window.history 中),即不会刷新页面。即所有页面的跳转都是在客户端进行操作。因此,这并不算是一次 http 请求,所以这种模式不利于 SEO 优化。hash 只能修改 # 后面的部分,所以只能跳转到与当前 url 同文档的 url 。
  • hash 通过 window.onhashchange 的方式,来监听 hash 的改变,借此实现无刷新跳转的功能。
  • hash 永远不会提交到 server 端(可以理解为只在前端自生自灭)。
history

history API 是 H5 提供的新特性,允许开发者直接更改前端路由,即更新浏览器 URL 地址而不重新发起请求。

history.pushState:往历史记录堆栈顶部添加一条记录
history.replaceState:更改当前的历史记录

  • 新的 url 可以是与当前 url 同源的任意 url ,也可以是与当前 url 一样的地址,但是这样会导致的一个问题是,会把重复的这一次操作记录到栈当中。
  • 通过 history.state ,添加任意类型的数据到记录中。
  • 可以额外设置 title 属性,以便后续使用。
  • 通过 pushState 、 replaceState 来实现无刷新跳转的功能,虽然改变了当前的 URL,但浏览器不会向后端发送请求
总结
  • 对于 hash 模式来说, 它虽然看着是改变了 url ,但不会被包括在 http 请求中,改变 hash 并没有真正地改变 url ,所以页面路径还是之前的路径, nginx 也就不会拦截

  • 在使用 history 模式时,需要通过服务端来允许地址可访问

  • to B 的系统推荐用 hash ,相对简单且容易使用,且因为 hash 对 url 规范不敏感

  • to C 的系统,可以考虑选择 H5 history ,但是需要服务端支持

  • hash模式下,仅hash符号之前的内容会被包含在请求中,如http://www.abc.com,因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误。

  • history模式下,前端的 URL 必须和实际向后端发起请求的 URL 一致,如http://www.abc.com/book/id如果后端缺少对/book/id的路由处理,将返回 404 错误,需要后台配置支持,要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html页面。

路由守卫

  • router.beforeEach: 全局前置路由守卫,每次路由切换之前被调用,可以做权限拦截
  • router.afterEach: 全局后置路由守卫,每次路由切换之后调用, 可用于切换document.title
  • router.beforeEnter: 独享路由守卫,只有前置,没有后置,写在routes配置项里
  • router.beforeRouteEnter: 组件内路由守卫, 写在组件中,路过路由规则进入该组件时被调用
  • crouter.beforeRouteLeave: 组件内路由守卫, 写在组件中,路过路由规则离开该组件时被调用
全局守卫
const router =  new Router({
  ...
  routes: [
    {
      path: '/All',
      name: 'All',
      component: All,
      meta:{
        isAuth: true  //需要鉴权
      },
    },
    ...
  ]
})

// 配置在实例对象外 初始化时调用,每次发生路由变化前调用
router.beforeEach((to,from,next)=>{
  console.log('beforeEach',to,from)
  if(to.meta.isAuth){ //判断当前路由是否需要进行权限控制
    if(localStorage.getItem('user') === 'ghn'){ //权限控制的具体规则
      next() //放行
    }else{
      alert('暂无权限查看')
      // next({name:'guanyu'})
    }
  }else{
    next() //放行
  }
})

//全局后置守卫:初始化时执行、每次路由切换后执行
router.afterEach((to,from)=>{
  console.log('afterEach',to,from)
  if(to.meta.title){ 
    document.title = to.meta.title //修改网页的title
  }else{
    document.title = 'vue_test'
  }
})

export default router
独享守卫

配置路由的时候给路由加入

const router =  new Router({
  ...
  routes: [
    {
      path: '/All',
      name: 'All',
      component: All,
      //独享守卫
      beforeEnter:(to,form,next)=>{
        if (to.meta.isAuth) {//判断当前路由是否需要权限控制
          if(localStorage.getItem('user') === 'ghn'){//权限控制的具体规则
            next()//旅行
          }else{
            alert('暂无权限查看')
          }
        } else {
          next();
        }
      },
      meta:{
        isAuth: true  //需要鉴权
      },
    },
    ...
  ]
})
组件内守卫
export default {
  name: "All",
  data() {
    return {}
  },
  components: {},
  methods: {},
  // 组件内守卫
  // 进入守卫,通过路由规则,进入该组件时被调用
  beforeRouteEnter(to, from, next) {
    // ...
    console.log("enter");
    next();
  },
  // 离开守卫,通过路由规则,离开该组件时被调用
  beforeRouteLeave(to, from, next) {
    // ...
    console.log("leave");
    next();
  },
  mounted() {
    console.log(this.$route);
  },
  computed: {},
  created() {

  },
  destroyed() {

  },
}
</script>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anjushi_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值