vue-router学习

2021-05-08  本文已影响0人  喵星人and亦人
单页面应用(SPA)

只有一张web页面的应用,跳转的时候紧紧刷新局部资源,公共资源(js、css等)仅需加载一次,第一次进入页面时只会请求一个html,刷新的时候清除页面上的组件,切换到其他的组件,这是路径也会发生相应的变化,但是不会有新的html文件请求.

vue-router是什么

vue-router是vue.js的官方路由插件,它依赖于vue.js,适用于单页面应用,在单页面应用中将路径和组件映射起来,路由的本质我感觉就是将url和组件之间建立映射关系.

刚刚开始接触路由的时候,可能会奇怪为什么使用路由,为什么不直接使用a标签呢,这是因为Vue做的都是单页面应用,Vue的项目打包的时候只会生成一个index.html页面,a标签的跳转页面会重新渲染,相当于打开一个新的网页.

vue-router实现原理
spa的核心是更新视图而不重新请求页面,它提供了两种方式来实现单页面前端路由: Hash模式和History模式
1. Hash模式:

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。hash(#)是URL 的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会滚动到相应位置,不会重新加载网页,也就是说hash 出现在 URL 中,但不会被包含在 http 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面;同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。hash 模式的原理是 onhashchange 事件(监测hash值变化),可以在 window 对象上监听这个事件

2.History模式:

由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: 'history'",这种模式充分利用了html5 history interface 中新增的 pushState() 和 replaceState() 方法。这两个方法应用于浏览器记录栈,在当前已有的 back、forward、go 基础之上,它们提供了对历史记录修改的功能。只是当它们执行修改时,虽然改变了当前的 URL ,但浏览器不会立即向后端发送请求

//main.js文件中
const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

当你使用 history 模式时,URL 就像正常的 url,例如 yoursite.com/user/id,比较好… 不过这种模式要玩好,还需要后台配置支持。因为我们的应用是个单页客户端应用,如果后台没有正确的配置,当用户在浏览器直接访问 oursite.com/user/id 就会返回 404,这就不好看了。 所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

 export const routes = [ 
  {path: "/", name: "homeLink", component:Home}
  {path: "/register", name: "registerLink", component: Register},
  {path: "/login", name: "loginLink", component: Login},
  {path: "*", redirect: "/"}]

此处就设置如果URL输入错误或者是URL 匹配不到任何静态资源,就自动跳到到Home页面

3. 使用模块路由来实现页面的跳转
Vue-router的使用方式:
  1. 通过npm安装vue-router

    npm i vue-router -S

  2. 引入vue-router到main.js中

import VueRouter from 'vue-router'

  1. 安装插件

Vue.use(VueRouter)

  1. 创建路由对象并配置路由规则
const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

const router = new VueRouter({
  routes
})
  1. 将路由对象传递给Vue的实例
new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

  1. 在app.vue放置router-view
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

Vue的核心要点

1. vue-router传递参数的方式

在路由文件src/router/index.js配置name属性

const routes = [
{
  path: '/',
  name: 'Home',
  component: Home
},
{
  path: '/about',
  name: 'About',
  // route level code-splitting
  // this generates a separate chunk (about.[hash].js) for this route
  // which is lazy-loaded when the route is visited.
  component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]

通过<router-link>来传值

  <router-link to="/about/测试">About</router-link>

在About组件中通过$route.params.urlName来获取

<h2>{{$route.params.urlName}}</h2>

单页面多路由区域操作

有时候一个页面同时展示多个视图,而不是嵌套显示,比如在写后台管理系统的时候有侧导航栏和主内容区域两个视图,这时候就要用命名视图了,可以在一个vue页面中拥有多个单独命名的视图(router-view),如果没有设置名字,那么name的值为default.

<template>
  <div id="app">
    <router-link :to="{name:'HelloWord'}">H1</router-link>|
    <router-link :to="{name:'H1'}">H2</router-link>|
    <router-view />
    <router-view name="left" style="float:left;width:50%;background-color:#ccc;height:300px;" />
    <router-view
      name="right"
      style="float:right;width:50%;background-color:yellowgreen;height:300px;"
    />
  </div>
</template>

上面的第一个router-view因为没有设置name,所以他的默认值是default,第二个router-view的name的值是left,第三个是right,

当点击第一个<router-link>的时候会根据HelloWord对应的路由,寻找其对应的组件即下面:

  {
    path: '/',
    name: 'HelloWord',
    components: {
      default: HelloWorld,
      left: H1,
      right: H2
    }
  }

HelloWord组件替换第一个router-view,H1组件替换name为left的router-view...

Vue-router二级路由的配置

项目开发中,组件往往是多层嵌套的,URL中各段的动态路径也按照某种结构对应嵌套的各层组件

在app.vue中写入一下代码

<template>
  <div id="app">
    <router-link :to="{name:'HelloWord'}">主页面</router-link>|
    <router-link :to="{name:'H1'}">H1页面</router-link>|
    <router-link :to="{name:'H2'}">H2页面</router-link>
    <router-view></router-view>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}
</style>

在router/index.js配置嵌套路由

const routes = [
  {
    path: '/',
    name: 'HelloWord',
    component: HelloWorld,
    children: [{
      path: '/h1',
      name: 'H1',
      component: H1
    },{
      path: '/h2',
      component: H2,
      name: 'H2'
    }]
  }
]

当启动服务的时候回默认会加载主页面,点击H1会去匹配子路由,我个人的理解是url被路由配置,层层匹配,将匹配到的路由组件渲染出来.

vue-router跳转的方法

<button @click="goToMenu" class="btn btn-success">Let's order!</button>
.....
<script>
  export default{
    methods:{
      goToMenu(){
        this.$router.go(-1)//跳转到上一次浏览的页面
        this.$router.replace('/menu')//指定跳转的地址
        this.$router.replace({name:'menuLink'})// 指定跳转路由的名字下
        this.$router.push('/menu')通过push进行跳转
        this.$router.push({name:'menuLink'})通过push进行跳转路由的名字下
      }
    }
  }
</script>

其中replace和push的区别是:

push会留下访问记录,会向history中添加记录,但是replace不会添加新的记录

错误页面的设置

当url输入错误的时候,应该友好的给一个页面,这个页面就是404页面,可以在路由配置页面中这样配置

{
    path: '*',
    component: Error
  }

代码这里

上一篇下一篇

猜你喜欢

热点阅读