vue路由高级语法糖
1.当 <router-link> 对应的路由匹配成功,将自动设置 class 属性值 .router-link-active.
模板中可以用{{$route.params.xxx取到路由参数}}或者{{$route.query取到参数}}或者{{$route.hash取到hash}}
实例中(js)可用:this.$route.params.xxx/this.$route.query.xxx取到路由参数;
2.通过$router 访问路由实例;
3.路由带参数:
const userId = 123
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
router.push({ path: 'register', query: { plan: 'private' }})
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user
4.路由历史记录:
window.history.go(n)
router.go(n)
History.back() //历史记录中的上一页
History.forward() //历史记录中的下一页
在window.history里新增一个历史记录点 存储当前历史记录点
//当前的url为:http://qianduanblog.com/index.html
var json={time:new Date().getTime()};
window.history.pushState()三个参数:
//1.状态对象:记录历史记录点的额外对象,可以为空
//2.页面标题:目前所有浏览器都不支持
//3.可选的url:浏览器不会检查url是否存在,只改变url,url必须同域,不能跨域
window.history.pushState(json,"","http://qianduanblog.com/post-1.html");
执行了pushState方法后,页面的url地址为http://qianduanblog.com/post-1.html。
替换当前历史记录点:window.history.replaceState()不会在window.history里新增历史记录点
其效果类似于window.location.replace(url),都是不会在历史记录点里新增一个记录点的;
监听历史记录点:直观的可认为是监听URL的变化,但会忽略URL的hash部分,监听URL的hash部分,HTML5有新的API为onhashchange事件
通过window.onpopstate来监听url的变化;并且可以获取存储在该历史记录点的状态对象;
//当前的url为:http://qianduanblog.com/post-1.html
window.onpopstate=function(){
// 获得存储在该历史记录点的json对象
var json=window.history.state;
//点击一次回退到:http://qianduanblog.com/index.html
//获得的json为null
//再点击一次前进到:http://qianduanblog.com/post-1.html
//获得json为{time:1369647895656}
}
注意:js脚本执行window.history.pushState和window.history.replaceState不会触发onpopstate事件。
5.路由重定向
{ path: '/a', redirect: { name: 'foo' }} //重定向的目标也可以是一个命名的路由
vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载;
6.路由元信息:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
children: [
{
path: 'bar',
component: Bar,
meta: { requiresAuth: true }
}
]
}
]
})
对应:
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!auth.loggedIn()) {
next({
path: '/login',
query: { redirect: to.fullPath }
})
} else {
next()
}
} else {
next() // 确保一定要调用 next()
}
})
7.滚动行为:当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置;
注意: 这个功能只在支持 history.pushState 的浏览器中可用;(也就是mode: 'history')
const router = new VueRouter({
routes: [...],
scrollBehavior (to, from, savedPosition) {
return { x: 0, y: 0 }
// return 期望滚动到哪个的位置
}
})
对于所有路由导航,简单地让页面滚动到顶部;
scrollBehavior (to, from, savedPosition) {
if (savedPosition) {
return savedPosition
} else {
return { x: 0, y: 0 }
}
}
如果你要模拟『滚动到锚点』的行为:
scrollBehavior (to, from, savedPosition) {
if (to.hash) {
return {
selector: to.hash
}
}
}
异步滚动:
scrollBehavior (to, from, savedPosition) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({ x: 0, y: 0 })
}, 500)
})
}
8.Router 构造配置:
mode:可选值: "hash(默认值浏览器环境)" | "history" | "abstract(默认值Node.js 环境)",
base:"/",(默认值)应用的基路径
linkActiveClass:"router-link-active"(默认值),
linkExactActiveClass(2.5.0+):"router-link-exact-active"(默认值),
scrollBehavior:滚动行为function;
parseQuery / stringifyQuery:提供自定义查询字符串的解析/反解析函数。覆盖默认行为function;
fallback(2.6.0+):当浏览器不支持 history.pushState 控制路由是否应该回退到 hash 模式。默认值为 true。
类型: boolean,在 IE9 中,设置为 false 会使得每个 router-link 导航都触发整页刷新。它可用于工作在 IE9 下的服务端渲染应用,因为一个 hash 模式的 URL 并不支持服务端渲染。
9.路由信息对象
$route.path:字符串,对应当前路由的路径,
$route.params:一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象,
$route.query:一个 key/value 对象,表示 URL 查询参数,如果没有查询参数,则是个空对象。
$route.hash:当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。
$route.fullPath:string类型完成解析后的 URL,包含查询参数和 hash 的完整路径。
$route.matched:一个数组,包含当前路由的所有嵌套路径片段的路由记录。
$route.name:当前路由的名称,如果有的话。(查看命名路由)
$route.redirectedFrom:如果存在重定向,即为重定向来源的路由的名字。
在 HTML5 history 模式下,router-link 会守卫点击事件,让浏览器不再重新加载页面。
当你在 HTML5 history 模式下使用 base 选项之后,所有的 to 属性都不需要写(基路径)了。
10.导航守卫:
一、全局守卫
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
to: Route: 即将要进入的目标 路由对象
from: Route: 当前导航正要离开的路由
next: Function: 一定要调用该方法来 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 方法,否则钩子就不会被 resolved。
二、全局后置钩子
router.afterEach((to, from) => {
// ...
})
二、路由独享的守卫
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
三、组件内的守卫
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
})
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`,你可以通过传一个回调给 next来访问组件实例
// 因为当守卫执行前,组件实例还没被创建
},
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
}
11.路由懒加载
import page1 from './routes/page1.vue'
const page2 = r => require.ensure([], () => r(require('./routes/page2.vue')))
const routes = [
{ path: '/main', component: page1 },
{ path: '/other', component: page2 }
]
//这两条路由被打包在相同的块中,访问任一路由都会延迟加载该路由组件
//有时候我们想把某个路由下的所有组件都打包在同个异步 chunk 中。(借助WebPack的require.ensure())
语法:require.ensure(dependencies: String[], callback: function(require), chunkName: String)
const page1= r => require.ensure([], () => r(require('./routes/page1.vue')), 'big-pages')
const page2 = r => require.ensure([], () => r(require('./routes/page2.vue')), 'big-pages')
写法二:
export default new Router({
routes: [
{
path: '/',
component: resolve => require(['components/Hello.vue'], resolve)
},
{
path: '/about',
component: resolve => require(['components/About.vue'], resolve)
}
]
})
12.vue组件的按需加载(2种方式)
组件里面:
components: {
bview: resolve => {require(["./b.vue"], resolve);}
},
模板里面:
<component :is="current" :data="myData" ></component>
data() {
return {
current: "",
myData:"",
show:false
}
},
methods: {
changeComponents(view){
if(view=='aview'){
this.myData='a1000';
}
else{
this.myData='b1000';
}
this.current=view;
}
}