route可翻译为路由信息对象,它包括path,params,hash,query,name等参数;
router是路由实例对象,它包括路由的跳转方法(push,replace),钩子函数等
路由基础
简单路由
-
定义路由组件
同步组件:
const component1 = { template: '<div>路由组件1</div>' }
异步组件
const asyncComponent = defineAsyncComponent({ loadding: LoadingComponent, //加载组件实例 loader: () => import "./demo.vue", delay: 500, timeout:2000, error: errorComponent })
-
定义路由
const routes = [ { path: '/', component: component1 }, { path: '/asyc', name: 'asyc', component: asyncComponent } ]
-
创建路由实例,提供history模式 / mash模式
const router = VueRouter.createRouter({ history: VueRouter.createWebHashHistory(), routes });
-
创建挂载根实例
const app = Vue.createApp({}); app.use(router).mount("#app");
动态路由
响应路由参数的变化
const routes = [
{
path: '/asyc/:id/post/:username',
component: asyncComponent
}
]
const asyncComponent = {
template: `<div>{{$route.params.id}} {{$route.params.username}}</div>`
}
导航守卫
- 在当前路由改变,但是该组件被复用时调用
- 导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上
const asyncComponent = {
template: `<div>{{$route.params.id}} {{$route.params.username}}</div>`,
beforeRouteUpdate(to,from,next){
next()
console.log(to,from)
}
}
匹配任何路径
嵌套路由
const routes = [
{
path: '/asyc',
component: asyncComponent1,
children:[{
path: '/com1', //asyc/com1
component: asyncComponent2
}]
}
]
编程式导航
在导航时不会向 history 添加新记录,取代了当前的条目。
- push
this.$router.push({name: 'asyc',params:{userId:1}}); //asyc 【注意用得是name】
this.$router.push({path: '/asyc',query:{userId:1}}); //asyc?userId=1
this.$router.push({path: '/asyc',hash: '#userId'}); //asyc#team
- replace
this.$router.push({path: 'home',replace:true});
this.$router.replace({path: 'home'});
横跨历史
this.$router.go(1) // == this.$router.forward()
this.$router.go(-1) // == this.$router.back()
this.$router.go(n)
命名路由
const routes = [
{
path: '/user',
name: 'user',
component: User
}
]
命名视图
<router-view name=leftSideBar></router-view>
<router-view name=rightSideBar></router-view>
<router-view></router-view>
import leftSideBar from './leftSideBar';
import rightSideBar from './rightSideBar';
import appMain from './appMain';
const routes = [
{
path: '/',
components:{
leftSideBar,
rightSideBar,
appMain
}
}
]
重定向
const routes = [
{
path: '/',
redirect: '/index'
},
{
path: '/index',
name: 'index'
},
{
path: '/home',
redirect:{
name: 'index'
}
},
{
path: '/login',
redirect:(to) => ({path:'/index',query:{userId:1}})
}
]
相对重定向
const routes = [
{
path:'/index/clothes',
//重定向到 /pants
//redirect: 'pants'
//重定向到 /index/path
redirect: to => 'pants'
}
]
路由传参(cx加的)
url | 接收 |
---|---|
/about/:id | $route.params.id |
/asyc?id=1 | $route.query.id |
路由组件传参(解耦)
就是通过props让在组件和路由解耦
布尔模式
const comp1 = {
props: ['id'],
template: '<div>comp id:{{id}}</div>'
};
const routes = [{
path: '/:id',
component: comp1,
props: true
}];
命名模式(命名视图)
<router-view name="comp1"></router-view>
<router-view name="comp2"></router-view>
const routes = [{
path: '/index/:id',
components: {
comp1: comp1,
comp2: comp2
},
props: {
comp1: true,
comp2: false
//default: false 表示的是非命名视图
}
}];
对象模式
要求路由中的props是静态的,不是来自路由中携带的参数。
-
当时视图是默认
<router-view ></router-view>
const comp3 = { template: '<div>comp3 id:{{id}}</div>', props: ["id"] }; const routes = [{ path: '/home', component:comp3, props: {id: 100} }];
-
视图是命名视图
<router-view name="comp3"></router-view>
const comp3 = { template: '<div>comp3 id:{{id}}</div>', props: ["id"] }; const routes = [{ path: '/home', components:{comp3}, props: { comp3:{id: 100 } } }];
函数模式
-
当时视图是默认
<router-view></router-view>
const comp4 = { template: '<div>comp4 id:{{id}}</div>', props: ["id"] }; const routes = [{ path: '/home/:id', component: comp4, props: route => { const id = route.params.id; return {id} } }];
-
视图是命名视图
<router-view name="comp4"></router-view>
const comp4 = { template: '<div>comp4 id:{{id}}</div>', props: ["id"] }; const routes = [{ path: '/home/:id', components: { comp4 }, props: { comp4: route => { const id = route.params.id; return {id} } } }];
历史记录模式
Hash模式
在传递实际url之前使用了一个哈希字符#,所以它不需要在服务器上有特殊的服务
const router = createRouter({
history: VueRouter.createWebHashHistory()
});
HTML5模式
没有#,但是会直接访问一个url,可能会得到一个404
const router = createRouter({
history: VueRouter.createWebHistory()
});
路由进阶
导航守卫
全局前置守卫
router.beforeEach(aysnc (to,from) => {
if(!login)
return false; //取消当前的导航
else
return {path: '/index'} //重定向导航,可以写name,replace等等
})
可选的第三个参数next: 确保 next
在任何给定的导航守卫中都被严格调用一次
router.beforeEach(async (to,from) => {
if(!login)
next({path: '/login'});
else
next();
})