vue-router
安装
cdn
npm
npm install vue-router@4
项目中使用
import { createApp } from 'vue'
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/',
component: Dashboard
},
{
path: '/todos',
component: Todos
}
]
})
createApp(App)
.use(router)
.mount("#app")
特性
动态路由
router.addRoute({
path:'/about',
name:'about',
component:()=>import('../components/About.vue')
})
router.addRoute('about',{
path:'/about/info',
name:'info',
component:{
render(){
return h('div', 'info page')
}
}
})
composition
获取路由器实例
import { useRouter } from 'vue-router';
const router = useRouter()
backTodash(){
router.push('./')
}
监控route对象
import { useRoute } from "vue-router";
// route是响应式对象,可监控其变化
const route = useRoute();
watch(
() => route.query,
(query) => {
console.log(query);
}
);
守卫
import { onBeforeRouteLeave } from "vue-router";
onBeforeRouteLeave((to, from) => {
const answer = window.confirm("你确定要离开当前页面吗?");
if (!answer) {
return false;
}
});
RouterLink、useLink
import { RouterLink, useLink } from 'vue-router'
props: {
...RouterLink.props
},
setup (props) {
// 获取RouterLink内部属性和方法
const{ route, href, isActive, isExactActive, navigate } = useLink(props)
console.log(route, href, isActive, isExactActive, navigate);
return {
route,
isActive,
navigate
}
}
变化
实例创建方式
new Router() 变成 createRouter()
history选项替代了mode选项
- history -- createWebHistory()
- hash -- createWebHashHistory()
- abstract -- createMemoryHistory()
base选项移至createWebHistory等方法中
通配符*被移除
isReady() 替代 onReady()
router.push()
// before
router.onReady(onSuccess,onError)
// now
router.isReady().then(onSuccess).catch(onError)
scrollBehavior 变化
- x,y -- left,top
<router-view>、<keep-alive> 和 <transition>
transition 和 keep-alive 现在必须通过 v-slot API 在 RouterView 内部使用:
// before
<keep-alive>
<router-view></router-view>
</keep-alive>
// now
<router-view v-slot="{ Component }">
<transition>
<keep-alive>
<component :is="Component" />
</keep-alive>
</transition>
</router-view>
<router-link> 一些属性移除
- append
<router-link to="child-route" append>to relative child</router-link>
替换成
<router-link :to="append($route.path, 'child-route')">
to relative child
</router-link>
// App 实例上定义一个全局的 `append` 函数:
app.config.globalProperties.append = (path, pathToAppend) =>
path + (path.endsWith('/') ? '' : '/') + pathToAppend
- event/tag
<router-link to="/about" tag="span" event="dblclick">About Us</router-link>
替换成
<router-link to="/about" custom v-slot="{ navigate }">
<span @click="navigate" @keypress.enter="navigate" role="link">About Us</span>
</router-link>
忽略 mixins 中的导航守卫
删除 router.match 改为 router.resolve
删除 router.getMatchedComponents()
router.currentRoute.value.matched.flatMap(record =>
Object.values(record.components)
)
包括首屏在内的 所有的导航现在都是异步的
这意味着,如果使用一个 transition,你可能需要等待路由 ready 好后再挂载程序:
app.use(router)
// 注意:在服务器端,需要手动跳转到初始地址。
router.isReady().then(() => app.mount('#app'))
如果在初始导航时有导航守卫,你可能不想阻止程序渲染,直到它们被解析,除非你正在进行服务器端渲染。否则,在这种情况下,不等待路由准备好挂载应用会产生与 Vue2 中相同的结果。
router的parent属性被移除
const parent = this.$route.matched[this.$route.matched.length - 2]
删除 pathToRegexpOptions
pathToRegexpOptions=>strictcaseSensitive=>sensitive
createRouter({
strict:boolean,
sensitive:boolean
})
history.state 的用法
// 将
history.pushState(myState, '', url)
// 替换成
await router.push(url)
history.replaceState({ ...history.state, ...myState }, '')
// 将
history.replaceState({}, '', url)
// 替换成
history.replaceState(history.state, '', url)
options 中的 routes 属性是必需的
createRouter({ routes: [] })
跳转不存在的命名路由报错
缺少必填参会抛出异常
带有空 path 的命名子路由不再添加斜线
const routes = [
{
path: '/dashboard',
name: 'dashboard-parent',
component: DashboardParent
children: [
{ path: '', component: DashboardDefault },
],
},
]
const routes = [
{
path: '/parent',
component: Parent,
children: [
// 现在将重定向到 `/home` 而不是 `/parent/home`
{ path: '', redirect: 'home' },
{ path: 'home', component: Home },
],
},
]
$route 属性编码行为
params、query和 hash
path和fullPath不再解码hash被解码push、resolve和replace,string地址或path属性时必须编码params斜线字符(/)会被解码query中 + 不处理,stringifyQuery