FE - 走向Node与Webpack 之路 - 必须知道的 Vue Router !

推荐资料

vue-router 2

资料中个别东西不理解的,本文可以找到。(真没有,就评论或私信)

1. 安装与配置

安装:

npm install vue-router -D-save-dev

配置:

为了使用方便,新建 router.js 进行注册和配置VueRouter , 比如:

router.js

/**
 * Created by yuan on 2/24/2017.
 */
import Vue from "vue";
import VueRouter from "vue-router";

//全局注册
Vue.use(VueRouter);

const router = new VueRouter({
   routes:[
   ]
});

export default router; //提供接口

配置 在 vue 实例中: (main.js

import Vue from "vue";
import App from "./App.vue";
import router from "./router";

new Vue({
    el: '#app',
    router,//配置
    render: h => h(App)
})

Router 配置

declare type RouteConfig = {
  path: string;
  component?: Component;
  name?: string; // for named routes (命名路由)
  components?: { [name: string]: Component }; // for named views (命名视图组件)
  redirect?: string | Location | Function;
  alias?: string | Array<string>;
  children?: Array<RouteConfig>; // for nested routes
  beforeEnter?: (to: Route, from: Route, next: Function) => void;
  meta?: any;
}

这在上面的文档里摘的,具体内容可以看看里面的。

举个例子:

const router = new VueRouter({
    mode: 'history',
    routes: [
        //动态路径参数,以冒号开头
        {
            path: "/user/:id",
            component: User,
            name: "u",
        },
        {
            path: "/demo",
            components: {//多个组件
                demo: Demo,
                demo1:Demo1,
            }
        },
    ]
});
  • mode
    三个值 : hash” | “history” | “abstract”
    • hash : 默认值,地址栏 会多个#号:http://localhost:8080/#/
    • history : 指定的时候,就正常了,没有#
    • abstract : 不知道!!
  • routes
    指定地址 和 组件等 ,路由匹配后面说!

2.路由匹配

路由地址匹配,常见的类型有 :

localhost/user/{id}
localhost/user?id=12

(1)动态路由匹配

// 动态路径参数 以冒号开头,后面是组件名称(单个组件)
    { path: '/user/:id', component: User }

使用的时候,可以直接使用router-link (路径前面有“/” 表示根路径):

<router-link to="/user/12">动态匹配:/user/12</router-link><br><br>

User组件中就可以获取到12,通过 route对象获取:

<template>
    <div>
        <h1>User : params </h1>
        <h3>{{this.$route.params.id}}</h3>
    </div>
</template>

(2)编程式导航

简言 :就是通过 router 对象进行操作(非route对象);
比如:

routers 一个对象

 {
            path: "/user/:id",
            component: User,
            name: "user", //命名路由
        }

编程式 操作


// 对象 : VueRouter 下 routes 下的 path 路径
router.push({ path: '/user/12' })

// 命名的路由 : VueRouter 下 routes 下的 name 路径
router.push({ name: 'user', params: { id: 12 }})

// 带查询参数,变成 /user?id=12
router.push({ path: 'user', query: { id: 12 }})

在 Component 中使用的时候,使用 this.$router 获取 router对象并进行操作。

router-link

// router.push(对象) 该对象均可以在router-link 传入
<router-link :to="对象">

(3)重定向 与 别名

VueRouter 下 router对象配置

重定向到 b

 { path: '/a', redirect: '/b' }

重定向到路由名称为foo的路径

{ path: '/a', redirect: { name: 'foo' }}

重定向指定函数

{ path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }

别名 :访问 b 时 ,地址为 b , 内容为 a .

 { path: '/a', component: A, alias: '/b' }

3.命名视图

router-view 组件是一个 functional 组件,渲染路由路径匹配到的视图组件;

单组件:

 {
            path: "/home",
            component: Home, // 单组件
            name: "h",
        }

入口组件下实现 : 自动将 Home 组件 渲染到 router-view

// 在 App.vue  template 下 
 <router-view></router-view>

多组件 : 属性 name

 {
            path: "/demo",
            components: { // 多组件 指定 components , 渲染不同router-view
                demo: Demo,
                demo1:Demo1,
            }
        }

入口文件下实现: 将不同组件名的 渲染到 相同namerouter-view 上。

<div >
            <router-view name="demo"></router-view>
            <router-view name="demo1"></router-view>
</div>

行为表现 :

通过路由将组件渲染到 router-view 中,它也是组件,可以配合 过渡效果<transition> 和 组件缓存 <keep-alive> 使用。如果同时使用的话 <keep-alive> 保证在内层使用。

<transition>
  <keep-alive>
    <router-view></router-view>
  </keep-alive>
</transition>

4.数据加载

(1)vue 生命周期

Vue 2.0 生命周期

vue的生命周期也对应component的生命周期,可以在component中使用生命周期的钩子已达到自己的目的。

比如:

可以在 created 钩子(回调)中执行加载数据操作

这里写图片描述

通过上图所示,可以看见生命周期的钩子(回调):

  • beforeCreate
  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeDestory

示例:
在 mounted中加载数据

 export default {
        name: "user",
        data(){
            return {
                post: null,
            }
        },
        mounted(){
           let id = this.$route.params.id
           this.$http.getUserInfo(id,response(data){
            })
        }
}

(2)数据获取

路由数据获取也有钩子(回调),两种方式:

Vue Router 数据获取

这里面刚开始看的时候,有些懵,导航?什么鬼。其实就是地址栏URL , 下面我简言说明

先加载数据,后跳转URL

未完成前,触发某个路由时,在路由的 beforeRouteEnter 钩子中获取数据,在数据获取成功后执行跳转。

比如:

   export default {
        name: "user",
        data(){
            return {
                post: null,
            }
        },
        watch: {
            //监听route 数据变化,route数据是只读的!
            '$route': 'changData'
        },
        methods: {
            changData: function () {
                let id = this.$route.params.id;
                console.log("changData : " +id);
                this.post = "changData change post !"+id;
            },
            test: function () {
                this.$router.push({path: "/user/188"});
            }
        },
        beforeRouteEnter(to, from, next){
            //先完成数据加载,再完成导航,后渲染组件
            let id = to.params.id;
            console.log("beforeRouteEnter : " + id);
            //获取数据成功
//            next(true);
            //获取数据失败 : 拦截不跳转
//            next(false);
            //对data数据赋值
            next(vm => vm.post = ('beforeRouteEnter load'+id));
        },

    }

beforeRouteEnter 钩子: 内置 next 方法 当next(true)时,执行跳转,否则拦截跳转

先跳转URL,后加载数据

先完成跳转,然后在接下来的组件生命周期钩子中获取数据。比如 created 和 mounted中执行 加载

export default {
        name: "user",
        data(){
            return {
                post: null,
            }
        },
        mounted(){
           // mounted中
           let id = this.$route.params.id
           this.$http.getUserInfo(id,response(data){
            })
        },
        created(){
         // created 中 
        let id = this.$route.params.id
           this.$http.getUserInfo(id,response(data){
            })
        }

(3)懒加载

路由懒加载(异步组件)

当打包应用时候,js 包会变得十分的大,影响页面加载。把 不同路由对应的组件分割成不同的代码块,当访问这个路由的时候,再去加载对应组件,就快速了。

定义异步组件 : 将现有的组件,定义为 异步组件,后配置路由,即可实现懒加载

定义Foo组件为异步组件!

const Foo = resolve => {
  // require.ensure 是 Webpack 的特殊语法,用来设置 code-split point
  require.ensure(['./Foo.vue'], () => {
    resolve(require('./Foo.vue'))
  })
}

这样也可以定义

const Foo = resolve => require(['./Foo.vue'], resolve)

使用异步组件 : 使用异步组件和直接使用组件一模一样

const router = new VueRouter({
  routes: [
    { 
        path: '/foo',
        component: Foo
      }
  ]
})

5.进阶

(1)路由钩子(回调)

上面的数据加载中已经使用 beforeRouteEnter 钩子数据回调;

路由对象钩子

  • beforeEach : 路由触发时,执行前执行的回调钩子

全局

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // to : 进入目标的route路由信息对象
  // from: 离开的 route路由信息对象
  // next : functionnext(true) 执行跳转,next(false) 拦截跳转
})

局部

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})
  • afterEach :路由触发时,执行后回调的钩子
// 也可以全局和局部设置 ,但没有next 方法,只有route对象
router.afterEach(route => {
  // ...
})

组件内钩子:

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave

比如:

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

注意 beforeRouteEnter 方法 ,无法通过this获取vue实例,因为该方法执行时,vue还未加载,可以通过下面next方法获取vue实例。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

(2)过渡效果

因为 <router-view>也是组件,所有可以添加过渡效果,比如

<transition>
  <router-view></router-view>
</transition>

(3)HTML5 History mode

如果是混合开发的话,使用默认的hash就可以,这时候URL后面有个#符号:

http://yoursite.com/index.html/#/home

如果是单个服务器跑SPA应用的话,可以配置为 history,这样看起来更正式点;

http://yoursite.com/user/id

mode属性

mode

类型: string

默认值: "hash" (浏览器环境) | "abstract" (Node.js 环境)

可选值: "hash" | "history" | "abstract"

6.router与route 对组件注入

router :
当前router实例,常用方法:

  • router.beforeEach(guard)
  • router.afterEach(hook)
  • router.push(location)
  • router.go(n)
  • router.replace(location
  • router.currentRoute : 获取当前 route 路由信息对象

route :

路由信息对象,当前路由状态信息,常用属性

  • $route.params
  • $route.query
  • $route.path
  • $route.name

组件内使用

  • 在Component中使用 router 对象 ,使用 this.$router调用 。
  this.$router.push({path: "/user/188"});
  • 在Component中获取route 路由信息对象,使用 this.$route调用。
 this.$route.params.id

下篇: 单页面应用 与 传统web应用

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值