16 【Router 4】
使用Vue3 安装对应的router4版本
使用Vue2安装对应的router3版本
1
| npm install vue-router@4
|
1.路由配置
与之前版本区别:
- 由
createRouter()
替换 new Router()
- 路由模式由
createWebHistory()
替换 mode: 'history'
- main.js中由
.use(router)
替换 new Vue({ router })
以前版本写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import Vue from 'vue'; import Router from 'vue-router'; import routes from './routes'
Vue.use(Router);
const router = new Router({ mode: 'history', routes });
export default router;
import Vue from 'vue' import router from './router'
new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
|
vue-router 4.x
版本写法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| import { createRouter, createWebHistory } from 'vue-router'; import routes from './routes'
const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes })
export default router
import { createApp } from 'vue' import App from './App.vue' import router from './router'
const app = createApp(App); app.use(router).mount('#app');
|
路由模式区别:
vue-router 3.x |
vue-router 4.x |
history |
createWebHistory() |
hash |
createWebHashHistory() |
abstract |
createMemoryHistory() |
在src目录下面新建router 文件 然后在router 文件夹下面新建 index.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import { createRouter, createWebHistory, createWebHashHistory, createMemoryHistory, RouteRecordRaw } from 'vue-router'
const routes: Array<RouteRecordRaw> = [{ path: '/', component: () => import('../components/a.vue') },{ path: '/register', component: () => import('../components/b.vue') }] const router = createRouter({ history: createWebHistory(), routes })
export default router
|
最后在main.ts 挂载
1 2 3 4
| import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app')
|
2.路由跳转及参数
router: 是VueRouter的一个全局对象,通过Vue.use(VueRouter)
和VueRouter
构造函数得到的一个实例对象,包含了所有路由包含了许多关键的对象和属性
route: 是一个跳转路由的局部对象,每个路由都会有一个route对象,可以获取对应的name
、path
、params
、query
等
以上在vue2.x
与vue3.x
中是一致的,要注意区分。
在vue3.x setup中
, useRouter
、useRoute
通常用来:
- useRouter:进行路由跳转
- useRoute:获取路由参数
1 2 3 4 5 6 7 8
| <script setup> import { useRoute, useRouter } from 'vue-router' const router = useRouter(); const route = useRoute();
console.log(route); router.push('/logo'); </script>
|
vue-router 3.x中 获取路由参数:
- 在组件中:
或
- 在 JS 中:
this.$route.query.color
或 this.$route.params.color
3.路由(导航)守卫
路由守卫简单来讲就是监听页面进入,修改,和离开的功能。
每个守卫接受三个参数:
- to:即将要进入的路由对象
- from:当前导航正要离开的路由
- next:一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。
关于 next :
next()
:进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false)
:中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/')
或 next({ path: '/' })
:跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
next(error)
:(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
vue-router 3.x中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <script type="text/ecmascript-6"> export default { beforeRouteEnter(to, from, next){ } beforeRouteUpdate(to, from, next){ } beforeRouteLeave(to, from, next){ } } }; </script>
|
vue-router 4.x中:
vue-router 3.x |
vue-router 4.x |
beforeRouteEnter |
无 |
beforeRouteUpdate |
onBeforeRouteUpdate |
beforeRouteLeave |
onBeforeRouteLeave |
在setup
中,由于路由已经发生了,因此在setup
内部设置beforeRouteEnter
没有任何意义,因此并无onBeforeRouteEnter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' import { ref } from 'vue'
export default { setup() { onBeforeRouteLeave((to, from) => { const answer = window.confirm( 'Do you really want to leave? you have unsaved changes!' ) if (!answer) return false })
const userData = ref()
onBeforeRouteUpdate(async (to, from) => { if (to.params.id !== from.params.id) { userData.value = await fetchUser(to.params.id) } }) }, }
|
4.动态路由
动态路由参数 id:
1 2 3 4 5 6 7 8 9
| <!-- 导航页 --> <template> <router-link :to="'/news/' + newsId">新闻详情</router-link> </template>
<script setup> import { ref } from 'vue'; const newsId = ref('001'); </script>
|
获取路由参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <!-- 新闻详情页 --> <template> <div id="news"> <p>id:{{$route.params.id}}</p> <p>{{newsId}}</p> </div> </template>
<script setup> import {useRoute} from 'vue-router'; import {computed} from 'vue'; const route=useRoute();
const newsId=computed(()=>{ return route.params.id }) </script>
|
5.keep-alive
可利用keep-alive
的 include
或 exclude
属性(include 和 exclude 包含的name 是组件的name不是router name)来设置缓存:
include
值为字符串或者正则表达式匹配的组件name会被缓存。
exclude
值为字符串或正则表达式匹配的组件name不会被缓存。
vue2.x写法:
1 2 3
| <keep-alive exclude="Home"> // 缓存除了Home外的所有组件 <router-view></router-view> </keep-alive>
|
vue3.x写法:
将内容传递给路由组件的 <slot>
#
之前你可以直接传递一个模板,通过嵌套在 <router-view>
组件下,由路由组件的 <slot>
来渲染:
1 2 3
| <router-view> <p>In Vue Router 3, I render inside the route component</p> </router-view>
|
由于 <router-view>
引入了 v-slot
API,你必须使用 v-slot
API 将其传递给 <component>
:
1 2 3 4 5
| <router-view v-slot="{ Component }"> <component :is="Component"> <p>In Vue Router 3, I render inside the route component</p> </component> </router-view>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <template> <router-view v-slot="{ Component }"> <keep-alive :include="includeList"> <component :is="Component" /> </keep-alive> </router-view> </template>
<script setup> import { ref } from 'vue';
// 需要缓存的组件name值 const includeList = ref(['About', 'User']); // 缓存About和User组件 </script>
|
也可以在router.js
中添加meta
属性动态判断:
1
| meta: { title: '缓存页面', keepAlive: true }
|
1 2 3 4 5 6 7 8 9 10 11 12
| import { watch } from 'vue' import {useRouter} from 'vue-router'
const router =useRouter() const includeList = [];
watch(() => router.currentRoute.value,(val) => { if (val.meta.keepAlive && keepAliveList.indexOf(val.name) === -1) { includeList.push(val.name); } },{immediate: true,deep: true})
|
6.vite中的路由懒加载