vue-cli3+typescript初体验——router篇

前言

vue基于类的写法,和基于对象的写法并不一致。
使用vue-cli3建立的项目,src目录下的文件结构并无多大区别,storerouterappviewcomponentsaeests该有的仍是有的。
可是,多了一个东西:vue-property-decoratorvue-property-decoratorvue-class-component的超集。vue

import { Component, Prop, Vue, Watch, Emit } from 'vue-property-decorator';

最主要的区别就是这里,组件的定义,参数的接受,方法的定义,等等。
可是本文主要讲的是router的监听。webpack

路由监听

用vue2的vue-cli建立项目,在src下有App.vue,main.js,其中若是要作路由权限控制,能够经过在mian.js添加如下代码来控制:web

import router from './router'

router.beforeEach((to, from, next) => {    
    /*若是须要登陆,当前没有登陆,直接跳转到登陆页*/
    if (to.meta.Auth && !store.state.loginStatus) {
        return next({ name: 'Login', query: {path: to.name}})
    }
    next()    
})

这个功能,在新版本的vue3中依然能够使用,由于使用了typescript,因此应该是main.ts文件。
可是若是要在组件内部使用路由监听,就遇到问题了,路由钩子beforeRouteEnter,beforeRouteLeave,beforeRouteUpdate不生效。
官网推荐在mian.ts中注册解决:vue-router

import Component from 'vue-class-component'

Component.registerHooks([
  'beforeRouteEnter',//进入路由以前
  'beforeRouteLeave',//离开路由以前
  'beforeRouteUpdate'
])

可是在vue-cli3中试过,不生效。多是vue-property-decoratorvue-class-component有区别的缘由,或者项目配置问题。
组件中实现路由监听,只能经过@Watch('$route')来实现。
可是@Watch不是路由守卫,若是离开当前组件,就不能继续监听路由变化,因此须要在当前的router-virew容器组件中监听。vuex

<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>
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator';
@Component
export default class App extends Vue {
  @Watch('$route',{ immediate: true })
  private changeRouter(route: Route){
      console.log(route)
  }
}
</script>

其中{ immediate: true }是关键,必须加这个参数才嫩实现对$route的监听。vue-cli

结语

vue-cli3+typescript的规范还不成熟,各类文档还不够齐全,尤为是中文文档。
不少demo都是基于vue2改造的,致使使用vue-cli3的时候出bug。
尤为是vue-routervuex的使用。
但也正是这些问题,让咱们有更大的兴趣学习使用这个新的技术规范。typescript

后记

通过社区同窗的指点,使用路由钩子的组件必须由路由加载,作了测试,vue-cli3的路由守卫是能够使用的。
入口文件:app

//main.ts
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import { Component } from 'vue-property-decorator';

Vue.config.productionTip = false;
Component.registerHooks([
  'beforeRouteEnter',
  'beforeRouteLeave',
  'beforeRouteUpdate',
]);

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

路由规则文件:学习

//router.ts
import Vue from 'vue';
import Router from 'vue-router';
import Home from './views/Home.vue';

Vue.use(Router);

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  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'),
    },
  ],
});

路由载入组件:测试

//About.vue
<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator';

@Component
export default class About extends Vue {

  beforeRouteEnter(to: Route, from: Route, next: () => void): void {
    console.log('beforeRouteEnter'); 
    next();
  }
  beforeRouteUpdate(to: Route, from: Route, next: () => void): void {
    console.log('beforeRouteUpdate');//暂时不生效,版本问题
    next();
  }
  beforeRouteLeave(to: Route, from: Route, next: () => void): void {
    console.log('beforeRouteLeave'); 
    next();
  }
}
</script>

如上,能够愉快的使用单独的路由钩子啦!!!

相关文章
相关标签/搜索