Web App开发--Vue Router
介绍
Vue Router的作用和用法在Vue Router的官方文档中已经写的非常清楚了,读者可以直接去阅读vue-router 2官方文档。
简洁教程
Vue项目是基于组件构建的,因此一个页面往往对应一个组件。为了提高模块化开发的代码的可维护性,每一个模块都在一个独立的文件中实现,最好不要把若干个模块放到一个文件中。Vue Router的创建依赖于对应模块的实例,因此Vue Router创建前必须先创建完所有的组件实例。但是,页面加载不同组件的文件是不同的网络请求,是异步的,并不能保证创建Vue Router的文件一定在创建所有需要路由的组件的文件之后加载完。如果创建Vue Router的文件先加载完,则所依赖的组件的实例不存在,引发undefined variable异常,导致vue router实例创建失败。
模块化开发的情况下,vue router的创建需要解决多文件异步加载的问题。而上一章组件间通信的一节无依赖的事件传递机制 的事件管理机制,可以帮助实现多文件异步加载的逻辑上同步加载。也就是说,虽然多个js文件网络请求是异步加载的,通过这个事件通知机制,每当一个需要路由的组件的文件加载完,组件的实例创建之后,通知路由器创建相应的router链接,从而解决依赖问题。
1. 模块化创建Vue Router实例
# html
<router-link :to="{path: '/componentPage', query: {var1: xxx, var2: xxx}}" >点击我跳转</router-link>
<router-view name="componentPage"></router-view>
其中<router-link></router-link>
实际上会被渲染成<a></a>
,:to
配置跳转的路由信息,path
为跳转的页面,query
可选的,跳转时携带的参数.
<router-view>
告诉组件,路由后在这里渲染界面, name
是可选的,对应<router-link>
中的path
。没有name
选项则路由默认渲染到这里, 配置了name即为命名路由。
# js
route.js文件,管理路由器的创建:
window.RouterLoader = function () {
this.loadedRouterNum = 0; // 已经创建好的路由数量,对应于已经加载创建好的组件实例数量
this.totalRouterNum = 9; // 路由总数量
this.routeList = []; // 路由路径->组件配置信息列表
};
window.RouterLoader.prototype = {
createRouter: function (routerInfo) {
this.routeList.push(routerInfo);
this.loadedRouterNum += 1;
if (this.loadedRouterNum == this.totalRouterNum) { // 所有子组件加载完成后才能穿件VueRouter实例
EventManager.fire('createRouter', {ready: true});
}
}
}
window.routerLoader = new RouterLoader();
EventManager.register('createRouter', function (data) { // 创建路由器实例
if (data.message.ready == true) {
window.router = new VueRouter({
routes: routerLoader.routeList,
mode: 'hash' // 有hash和history两种模式
});
EventManager.unRegister('createRouter'); // 创建实例后,注销事件,防止被反复创建实例
EventManager.fire('createApp', {ready: true}); // 创建好路由器实例后创建Vue实例
}
});
创建组件实例后,创建相应的路由:
const subComponent = {
template: 'I am subComponent',
data: function() {
return {
var: xxx
}
},
methods: {
back: function () {
this.$router.back();
},
},
}
routerLoader.createRouter({path: '/componentPage', components: {myComponent: subComponent}});
最后创建Vue实例,注意router选项:
EventManager.register('createApp', function (data) {
if (data.message.ready == true) {
EventManager.unRegister('createApp'); // 防止实例被反复创建
window.app = new Vue({
el: "#app",
store,
router, // 路由实例
data: {
var: xxx
},
});
}
})
2. 添加过渡动效
和native app一样,进入页面和退出页面,web app也可以实现相应的进场动画效果和退场动画效果。Vue router结合纯css的动画库animate.css可以实现很好的过渡动画效果。
<transition name="custom-classes-transition"
enter-active-class="animated slideInRight"
leave-active-class="animated slideOutRight">
<router-view name="componentPage"></router-view>
</transition>
上面的enter-active-class
配置进场动效, leave-active-class
配置退场动效。animated
和slideInRight
为animate.css的动画效果。更多关于animate.css纯CSS3动画的使用,请阅读animate.css github资源,或者直接看animate.css动画效果展示
# 导航钩子
这里只讲组件内的导航钩子,关于更多的导航钩子,请阅读Vue Router导航钩子。
你可以在路由组件内直接定义以下路由导航钩子:
- beforeRouteEnter
- beforeRouteUpdate (2.2 新增)
- beforeRouteLeave
const Foo = {
template: `...`,
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
,因为钩子在导航确认前被调用,因此即将登场的新组件还没被创建。
不过,你可以通过传一个回调给 next
来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
}
你可以 在 beforeRouteLeave
中直接访问 this
。这个 leave
钩子通常用来禁止用户在还未保存修改前突然离开。可以通过 next(false)
来取消导航。
在钩子中读取跳转时传递过来的参数:
<router-link :to="{path: '/componentPage', query: {var1: xxx, var2: xxx}}" >点击我跳转</router-link>
这个例子中的query
就是一个跳转时传递的参数,这里的:to
路由对应的是组件内钩子beforeRouteEnter (to, from, next)
中的to
参数,因此,读取参数中的var变量:
beforeRouteEnter (to, from, next) {
console.log(to.query.var1);
console.log(to.query.var2);
}
另外,还有路由的构造选项、滚动行为等内容,可以直接去官网阅读,Vue的一系列内容都有很详细的官方文档,所以Vue的入门学习比较简单。
上一篇: Web App开发--Vuex状态管理层