关于在Vue中使用TypeScript时,基于vue-property-decorator的@Component装饰器参数说明
@Component装饰器接收一个对象(options:ComponentOptions = {}))作为参数,vue-property-decorator是这样声明的:
declare module 'vue/types/options' {
interface ComponentOptions<V extends Vue> {
router?: VueRouter
beforeRouteEnter?: NavigationGuard<V>
beforeRouteLeave?: NavigationGuard<V>
beforeRouteUpdate?: NavigationGuard<V>
}
}
由此可见@Component接受一个对象参数,该对象中可传可选参数路由router,以及Vue导航守卫beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。
vue-router导航守卫[官方文档]
“导航”表示路由正在发生改变。导航守卫就是监听组件或页面进入、修改、离开,通过跳转还是取消的方式守卫导航。
守卫钩子接受三个参数:
- to: Route: 即将要进入的目标路由对象。到哪里去
- from: Route: 当前导航正要离开的路由。从哪里来
- next: NavigationGuardNext: 一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。要干什么
-
- next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
-
- next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
-
- next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
-
- next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
**确保 next 函数在任何给定的导航守卫中都被严格调用一次。
- next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
//Home.vue
<template>
<div class="home">
<h1>{{ title }}</h1>
<HomeComponent msg="Hello World" />
</div>
</template>
<script lang="ts">
import { Vue, Component } from "vue-property-decorator"; //导入Component装饰器
import HomeComponent from "@/components/HomeComponent.vue"; // 引入组件
import { NavigationGuardNext, Route } from "vue-router";
@Component({
components: {
HomeComponent,
},
beforeRouteEnter(to: Route, from: Route, next: NavigationGuardNext) {
// 导航进入该组件的对应路由时调用,或者可以理解为从另一个页面跳转到当前页面
console.log("*****Home***Enter*****");
console.log("beforeRouteEnter", this); //undefined
console.log("to", to);
console.log("from", from);
next((vm: any) => {
console.log(vm); // vm就是当前组件的实例,相当于this
// 因为当beforeRouteEnter钩子执行前,组件实例还未被创建
// 所有需要通过传一个回调给next来访问组件实例
// 在下面定义了一个title变量,我们来改变这个参数试试
vm._data.title = "vmHomeTitle"; //不知道这样操作对不对,编译运行都没报错和警告,^_^
});
},
beforeRouteUpdate(to: Route, from: Route, next: NavigationGuardNext) {
// 在当前路由改变,但是该组件被复用时调用
// 对于一个带有动态参数的路径 /home/:id,在 /home/1 和 /home/2 之间跳转的时候,
// 由于会渲染同样的home组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问当前组件实例this
console.log("*****Home***Update*****");
console.log("Update", this); //当前组件实例
console.log("to", to);
console.log("from", from);
console.log("next", next);
// 注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。
// 对于 beforeRouteUpdate 和 beforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。
next();
},
beforeRouteLeave(to: Route, from: Route, next: NavigationGuardNext) {
// 导航离开该组件的对应路由时调用,或者可以理解为从当前页面跳转到另一个页面
// 可以访问当前组件实例this
console.log("*****Home***Leave*****");
console.log("Leave", this); //当前组件实例
console.log("to", to);
console.log("from", from);
console.log("next", next);
// 这个离开守卫通常用来禁止用户在还未保存修改前突然离开。
// 该导航可以通过 next(false) 来取消。
const answer = window.confirm(
"Do you really want to leave? you have unsaved changes!"
);
if (answer) {
next();
} else {
next(false);
}
},
})
export default class Home extends Vue {
private title = "HomeTitle";
}
</script>
//HomeComponent.vue
<template>
<h1>{{ msg }}</h1>
</template>
<script lang='ts'>
import { Component, Vue, Prop } from "vue-property-decorator";
@Component
export default class HomeComponent extends Vue {
@Prop() private msg!: string;
}
</script>
<style scoped>
</style>
**内容原创,整理不易,转载请注明出处!!!谢谢合作!**