zoukankan      html  css  js  c++  java
  • vue2.0---vue-router总结(项目基于vue-cli)

    vue2.0---vue-router总结(项目基于vue-cli)

    1. 在项目中安装

    npm install vue-router --save

    2. 在项目中的引入:

    // The Vue build version to load with the `import` command
    // (runtime-only or standalone) has been set in webpack.base.conf with an alias.
    import Vue from 'vue';
    import Vuex from 'vuex';
    import VueResource from 'vue-resource';
    
    import App from './App';
    import router from './router';
    import store from './store';
    // Resource
    Vue.use(VueResource);
    
    // vuex
    Vue.use(Vuex);
    
    Vue.config.productionTip = false;
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store,
      template: '<App/>',
      components: { App }
    });

    3. router.js的配置

    我们先来看一下 router/index.js 代码如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    export default new Router({
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        }
      ]
    });

    router常见的参数有如下:

    3-1 mode 可选的参数有 hash 和  history;

    hash: 默认为hash, 如果使用hash的话,页面的地址就会加上 # 号就会比较不好看,如我们的地址变成如下:http://localhost:8080/#/
    history: 我们使用history的话,那么访问页面的时候就和平常一样,不带井号的;如下地址也可以访问 http://localhost:8080/
    router/index.js 配置代码变成如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    export default new Router({
      mode: 'history', // 访问路径不带井号
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        }
      ]
    });

    3-2 base

    应用的基路径,比如整个单页应用服务在 /page/app/ 下,那么base就应该设置为 /page/app/. 一般写成 __direname(在webpack中有配置),当然你也可以写成 /page/app/
    router.js代码如下配置:

    import Vue from 'vue';
    import Router from 'vue-router';
    import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    export default new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: HelloWorld
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: HelloWorld
        }
      ]
    });

    因此页面这样访问 http://localhost:8080/page/app/ 和 http://localhost:8080/ 访问的效果是一样的。

    3-3 routers

    基本的代码如下:

    routes: [
      {
        path: '/',
        name: 'HelloWorld',
        component: HelloWorld
      },
      {
        path: '/helloworld',
        name: 'HelloWorld',
        component: HelloWorld
      }
    ]

    path: 就是我们访问这个页面的路径。
    name: 给这个页面路径定义一个名字,当在页面进行跳转的时候也可以使用名字跳转。唯一性
    component组件,就是使用import 引入的组件了。
    引入组件还有一种懒加载的方式。懒加载引入的优点是:当你访问这个页面的时候才会去加载相关的资源,这样的话能提高页面的访问速度。
    比如如下这样:component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
    因此router/index.js 可以写成如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    // import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    export default new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
        }
      ]
    });

    3-4 router传参数

    首先我们在router/index.js 代码做如下配置:

    {
      path: '/helloworld/:name', // 对路径做拦截,这种类型的链接后面的内容会被vue-router映射成name参数了
      name: 'HelloWorld',
      component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
    }

    当我们在页面上访问 http://localhost:8080/page/app/helloworld/xx=1 的时候,然后我们在 heeloworld这个组件内的created
    的生命周期内,使用 console.log(this.$route.params.name); // xx=1 可以获取到/helloworld/ 后面的所有的参数了。

    3-4-2 Get请求传参数

    比如在页面访问的时候,可以使用问号(?)对参数进行传递;比如如下网址:

    http://localhost:8080/page/app/helloworld?age=1

    首先在router/index.js 代码先还原成如下:

    {
      path: '/helloworld',
      name: 'HelloWorld',
      component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
    }

    然后我们在helloworld组件内 使用如下获取:

    let age = this.$route.query.age; //问号后面参数会被封装进 this.$route.query;
    console.log(age); // 打印出1

    3-5 编程式导航

    现在看看页面是如何跳转的了,主要是利用 <router-link>来创建可跳转链接,我们还可以利用 this.$router.push('xxx')进行跳转。
    首先我们现在 router/index.js 添加 demo这个组件,然后从heeloworld这个页面跳转到demo这个组件页面;如下router的配置:

    routes: [
      {
        path: '/',
        name: 'HelloWorld',
        component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
      },
      {
        path: '/helloworld',
        name: 'HelloWorld',
        component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
      },
      {
        path: '/demo',
        name: 'demo',
        component: resolve => require(['@/views/demo'], resolve) // 使用懒加载
      }
    ]

    然后我们在helloworld组件添加如下代码:

    <router-link to="/demo">点击我跳转</router-link>

    因此点击就可以跳转了;
    我们也可以使用 router-link 像get方式那要传递一些参数过,比如如下router-link代码:

    <router-link :to="{path: '/demo', query:{'id': 22, 'name': 'kongzhi'}}">
      点击我跳转
    </router-link>

    然后我们在demo组件内通过如下方式可以获取值:

    console.log(this.$route.query.id); // 22
    console.log(this.$route.query.name); // kongzhi

    我们也可以使用 this.$router.push('xxx')进行跳转; 如下代码:

    <div @click="func()">点击进行跳转</div>

    JS代码如下:

    methods: {
      func () {
        this.$router.push('/demo');
      }
    }

    可以有如下方式:

    // 字符串,这里的字符串是路径path匹配噢,不是router配置里的name
    this.$router.push('/demo')
    
    // 对象
    this.$router.push({path: '/demo'});
    /*
     * 命名的路由 跳转到demo组件,因此地址栏变成 http://localhost:8080/page/app/demo 
     * 在demo组件内 通过 console.log(this.$route); 打印如下信息
     {
       fullPath: '/demo',
       hash: '',
       matched: [....],
       name: 'demo',
       params: {userId: 123},
       path: '/demo',
       query: {}
     }
     因此 我们可以通过 this.$route.params.userId 就可以获取到传递的参数 userId了。
    */
    this.$router.push({name: 'demo', params: { userId: 123 }})
    
    /*
     带查询参数,跳到到demo组件内,因此地址栏会变成如下:http://localhost:8080/page/app/demo?userId=1234
     然后我们和上面一样 可以通过 this.$route.query.userId 就可以获取到传递的参数 userId了。
    */
    this.$router.push({path: 'demo', query: { userId: '1234' }});

    3-6 导航钩子

    导航钩子函数,主要是在导航跳转的时候做一些操作,比如跳转页面之前,进行判断,比如跳转的时候,判断是否某个字段是否为true,如果为true,
    则跳转到A组件内,否则的话跳到B组件内。而钩子函数根据其生效范围可以分为 全局钩子函数, 路由独享钩子函数 和 组件内钩子函数。

    3-6-1 全局钩子函数
    比如我们可以直接在 router/index.js 代码编写代码逻辑,对一些全局性的东西进行拦截。

    router.beforeEach((to, from, next)=>{
      //do something
      next();
    });
    router.afterEach((to, from, next) => {
        console.log(to.path);
    });

    上面的钩子方法接收三个采纳数:
    to:  即将要进入的目标路由对象。
    from: 当前导航正要离开的路由。
    next:  一定要调用该方法来 resolve这个钩子。
    next() 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed(确定的)。
    next(false). 中断当前的导航。
    next('/')next({path: '/'}), 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

    注意: 确保要调用 next 方法,否则钩子就不会被 resolved。
    我们再来访问 页面地址 http://localhost:8080/page/app/helloworld,然后在router/index 配置如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    // import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    const router = new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
        },
        {
          path: '/demo',
          name: 'demo',
          component: resolve => require(['@/views/demo'], resolve) // 使用懒加载
        }
      ]
    });
    router.beforeEach((to, from, next) => {
      // do something
      console.log(to.path); // 打印 /helloworld
      console.log(from.path); // 打印 /
      next();
    });
    router.afterEach((to, from, next) => {
      console.log(to.path); // 打印 /helloworld
      console.log(from.path); // 打印 /
    });
    export default router;

    刷新下页面就可以看到调用 beforeEach 和 afterEach 的输出了。

    3-6-2 路由独享钩子函数

    我们可以对单个的路由的跳转进行拦截,对单个的路由使用 beforeEnter 函数,我们在router/index的文件里面可以如下编写代码:

    import Vue from 'vue';
    import Router from 'vue-router';
    // import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    const router = new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve), // 使用懒加载
          beforeEnter(to, from, next) {
            console.log(111)
            console.log(to.path); // 打印 /helloworld
            console.log(from.path); // 打印 /
            next(); // 跳到/helloworld 组件页面
          }
        },
        {
          path: '/demo',
          name: 'demo',
          component: resolve => require(['@/views/demo'], resolve) // 使用懒加载
        }
      ]
    });
    export default router;

    3-6-3 组件内钩子函数

    更细粒度的路由拦截,只针对一个进入某一个组件的拦截。
    我们把 router/index的代码还原成如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    // import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    const router = new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
        },
        {
          path: '/demo',
          name: 'demo',
          component: resolve => require(['@/views/demo'], resolve) // 使用懒加载
        }
      ]
    });
    export default router;

    然后对 helloworld 组件内的代码 使用 beforeRouterEnter()方法进行拦截;如下HelloWorld.vue代码

    export default {
      name: 'HelloWorld2',
      data () {
        return {
          msg: 'Welcome to Your Vue.js App'
        };
      },
      created () {
        this.getInfo();
      },
      beforeRouteEnter(to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当钩子执行前,组件实例还没被创建
        console.log(to.path); // 打印 /helloworld
        console.log(from.path); // 打印 /
        next();  // 跳转到 /helloworld 指定的页面
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
      }
    };

    钩子函数使用场景:

    其实路由钩子函数在项目开发中用的并不是非常多,一般用于登录态的校验,没有登录跳转到登录页;权限的校验等等。

    4. 滚动行为
    在利用 vue-router 去做跳转的时候,到了新页面如果对页面的滚动位置有要求的话,可以使用如下方法:

    const router = new VueRouter({
      routes: [...],
      scrollBehavior (to, from, savedPosition) {
        // return 期望滚动到哪个的位置
      }
    });

    scrollBehavior 方法接收 to 和 from 路由对象。
    第三个参数 savedPosition 当且仅当 popstate 导航 (mode为 history 通过浏览器的 前进/后退 按钮触发) 时才可用。

    //所有路由新页面滚动到顶部:
    scrollBehavior (to, from, savedPosition) {
      return { x: 0, y: 0 }
    }
    
    //如果有锚点
    scrollBehavior (to, from, savedPosition) {
      if (to.hash) {
        return {
          selector: to.hash
        }
      }
    }

    比如在页面是使用 <router-link> 做跳转的时候,那么到另一个页面需要滚动到100px的时候,我们可以对全局使用,也可以对某个路由时候,或者对某个
    组件使用,下面我们是在 router/index.js 代码内对代码全局使用如下:

    import Vue from 'vue';
    import Router from 'vue-router';
    // import HelloWorld from '@/views/HelloWorld';
    
    Vue.use(Router);
    
    const router = new Router({
      mode: 'history', // 访问路径不带井号
      base: '/page/app',  // 配置单页应用的基路径
      routes: [
        {
          path: '/',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve)  // 使用懒加载
        },
        {
          path: '/helloworld',
          name: 'HelloWorld',
          component: resolve => require(['@/views/HelloWorld'], resolve) // 使用懒加载
        },
        {
          path: '/demo',
          name: 'demo',
          component: resolve => require(['@/views/demo'], resolve) // 使用懒加载
        }
      ],
      scrollBehavior (to, from, savedPosition) {
        return { x: 100, y: 100 }
      }
    });
    export default router;

    当我们从 heeloworld.vue 组件内 点击跳转到 demo.vue的时候,在demo.vue会滚动100px;

  • 相关阅读:
    「UOJ#117」 欧拉回路
    「LuoguP1341」 无序字母对(欧拉回路
    「NOIP2002」「Codevs1099」 字串变换(BFS
    「IOI1998」「LuoguP4342」Polygon(区间dp
    「LuoguP2420」 让我们异或吧(树上前缀和
    「USACO13MAR」「LuoguP3080」 牛跑The Cow Run (区间dp
    「LuoguP1220」 关路灯(区间dp
    「CQOI2007」「BZOJ1260」涂色paint (区间dp
    「LuoguP1430」 序列取数(区间dp
    「USACO16OPEN」「LuoguP3147」262144(区间dp
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/8068075.html
Copyright © 2011-2022 走看看