vue-router是 Vue.js 官方的一个路由,它深度整合了 Vue.js 以更好的创建一个单页面应用。
Include:
- Nested route/view mapping
- Modular, component-based router configuration
- Route params, query, wildcards
- View transition effects powered by Vue.js' transition system
- Fine-grained navigation control
- Links with automatic active CSS classes
- HTML5 history mode or hash mode, with auto-fallback in IE9
- Restore scroll position when going back in history mode
Get started with the documentation.
# install deps npm install # build dist files npm run build # and unit tests at localhost:8080 npm run dev
在Webpack设置好入口后,在入口处实例化Router,当然,你也可以传入一些配置参数.
new Router({
// Default: true, 设置为false的时候,路径会被格式化为:**/#/foo/bar**,反之为**/#!/foo/bar**
hashbang: [Boolean],
// Default: false, 在初次加载时是否对**<router-view></router-view>**处理场景切换,默认会直接渲染
transitionOnLoad: [Boolean]
})
对于路由设置这里主要有三个路径:
router.map({
'/list': {
name: 'markdown',
setting: setting,
component: Listview
},
'/list/:archive':{
name: 'archive',
setting: setting,
component: Listview,
},
'/post/:archive/:title': {
name: 'post',
setting: setting,
component:Postview
}
});
默认任何其他无效路径都是指向于 /list/markdown
,即显示各种post的列表, /list/:archive
是指向各个post归档, name
在这里可以理解为一个路由别名alias,具体可看文档。
App.vue主要引入了三个组件 Listview.vue
、 MenuButton.vue
、 Postview.vue
,在进行切换, transition-mode
是切换的方式, in-out
即是当新组件加载进来了,再将就组件移出去。
关于 vue-router
,他有一个具体的生命周期: canResuse
-> canDeactivate
-> canActivate
-> deactivate
-> activate
,在什么时候需要做什么操作就在什么时候调用对应的钩子即可。
组件component: App.vue - Listview.vue - MenuButton.vue - Postview.vue 过滤器filter: index.js // 因*.md包含了日期和标题,这里主要是介绍vue-router,所以便正则简单过滤了一下,否则可像hexo那样用模板参数 - onlyTitle // 对日期进行过滤 - onPublishDate 仓库store: index.js // 异步请求文件内容,并返回一个Promise(利用GitHub的API) - getPost // 异步请求列表 - getListByName 配置setting: // 各种路径参数,GitHub API请求参数,标题等... index.js
router.redirect({
'*': '/home'
});
router.alias({
'/home': '/list/markdown'
});
因为有了上面两段代码,我们一开始访问的页面其实是挂载在App.vue上的 Listview.vue
,而且我们还设置了 $loadingRouteData
参数,这样在异步请求还未resolve时,页面将会有一个过渡界面。紧接着导入 filter
和 store
。
route: {
data ({ to }) {
const archive = to.params.archive;
document.title = to.setting.blogTitle;
return {
items: store.getListByName(archive).then(items => items)
};
},
}
这里采用的是ES6进行编码, route
里面的data参数是官网文档所说的transition,但这里利用了ES6的对象解构,可以方便获取URL上的params,获取list成功后将resolve数据到组件中的 data
项,这样在HTML上就可以直接通过 Vue.js
的template模板变量进行遍历访问。
同时,每个Listview的item都有一个 v-link
链接到 /post/{title}
页面,对应于组件 Postview.vue
,在该页面下,同样使用了 store
里封装的一个异步请求函数,resolve后将数据直接渲染到组件页面中。
watch: {
content() {
let linksArray = Array.from(document.querySelectorAll('a'));
const currentHost = window.location.host;
linksArray.forEach(el => {
if (el.href && el.host !== currentHost) {
el.target = '_blank'
}
});
}
}
这里的 watch
是当content有变化时,遍历内容中的a标签,若非当前域名下的页面,则将其target设置为新建一个窗口打开。
说到这里,其实这个Demo的已经介绍的差不多了,UI那些其实看多几遍就好,看一个项目的源码,首先找到入口,对整体的轮廓和交互逻辑有了个大概的了解后,再来对细节部分逐一攻破。
不然,老是纠结于某细小的一点那样太浪费时间了,而且能力也并不会提高多少。