vue基於類的寫法,和基於對象的寫法並不一致。
使用vue-cli3建立的項目,src
目錄下的文件結構並無多大區別,store
、router
、app
、view
、components
、aeests
該有的仍是有的。
可是,多了一個東西:vue-property-decorator
,vue-property-decorator
是vue-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-decorator
和vue-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-router
和vuex
的使用。
但也正是這些問題,讓咱們有更大的興趣學習使用這個新的技術規範。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>
如上,能夠愉快的使用單獨的路由鉤子啦!!!