跳至主要內容

16 【Router 4】

约 1582 字大约 5 分钟...

16 【Router 4】

使用Vue3 安装对应的router4版本

使用Vue2安装对应的router3版本

npm install vue-router@4

1.路由配置

与之前版本区别:

  1. createRouter() 替换 new Router()
  2. 路由模式由 createWebHistory() 替换 mode: 'history'
  3. main.js中由 .use(router) 替换 new Vue({ router })

以前版本写法:

// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import routes from './routes'

Vue.use(Router);

const router = new Router({  // 区别1
	mode: 'history',  // 区别2
	routes
});

export default router;


// main.js
import Vue from 'vue'
import router from './router'
// ...
new Vue({
	el: '#app',
	router,   // 区别3
	components: { App },
	template: '<App/>'
})

vue-router 4.x 版本写法:

// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import routes from './routes'

const router = createRouter({ // 区别1
	history: createWebHistory(process.env.BASE_URL),  // 区别2
	routes 
})

export default router 


// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App);
app.use(router).mount('#app');  // 区别3

路由模式区别:

vue-router 3.xvue-router 4.x
historycreateWebHistory()
hashcreateWebHashHistory()
abstractcreateMemoryHistory()

在src目录下面新建router 文件 然后在router 文件夹下面新建 index.ts

//引入路由对象
import { createRouter, createWebHistory, createWebHashHistory, createMemoryHistory, RouteRecordRaw } from 'vue-router'
 
//vue2 mode history vue3 createWebHistory
//vue2 mode  hash  vue3  createWebHashHistory
//vue2 mode abstact vue3  createMemoryHistory
 
//路由数组的类型 RouteRecordRaw
// 定义一些路由
// 每个路由都需要映射到一个组件。
const routes: Array<RouteRecordRaw> = [{
    path: '/',
    component: () => import('../components/a.vue')
},{
    path: '/register',
    component: () => import('../components/b.vue')
}]
 
 
 
const router = createRouter({
    history: createWebHistory(),
    routes
})
 
//导出router
export default router

最后在main.ts 挂载

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对象,可以获取对应的namepathparamsquery

以上在vue2.xvue3.x中是一致的,要注意区分。

vue3.x setup中useRouteruseRoute通常用来:

  • useRouter:进行路由跳转
  • useRoute:获取路由参数
<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中 获取路由参数:

  1. 在组件中: {{$route.query.color}}{{$route.params.color}}
  2. 在 JS 中: this.$route.query.colorthis.$route.params.color

3.路由(导航)守卫

路由守卫简单来讲就是监听页面进入修改,和离开的功能。

每个守卫接受三个参数:

  • to:即将要进入的路由对象
  • from:当前导航正要离开的路由
  • next:一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

关于 next :

  1. next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

  2. next(false):中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

  3. next('/')next({ path: '/' }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。

  4. next(error):(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

vue-router 3.x中:

<script type="text/ecmascript-6">
	export default {
	
			beforeRouteEnter(to, from, next){
			    // 在渲染该组件的对应路由被confirm前调用
			    // 此时组件实例还没被创建,因此不能获取`this`
			}
			
			beforeRouteUpdate(to, from, next){
			    // 在当前路由改变,但该组件被复用时调用
			    // 举例:对于一个带有动态参数的路径`/item/:id`,在`/item/1`和`/item/2`之间跳转的时候,
			    // 由于会渲染相同的`Item`组件,因此组件实例会被复用,从而触发这个钩子
			    // 此时可以获取到`this`
			}
			
			beforeRouteLeave(to, from, next){
			    // 导航离开该组件的对应路由时调用
			    // 时可以获取到`this`
			}
			
	    }
	};
</script>

vue-router 4.x中:

vue-router 3.xvue-router 4.x
beforeRouteEnter
beforeRouteUpdateonBeforeRouteUpdate
beforeRouteLeaveonBeforeRouteLeave

setup中,由于路由已经发生了,因此在setup内部设置beforeRouteEnter没有任何意义,因此并无onBeforeRouteEnter

import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'

export default {
  setup() {
    // 与 beforeRouteLeave 相同,无法访问 `this`
    onBeforeRouteLeave((to, from) => {
      const answer = window.confirm(
        'Do you really want to leave? you have unsaved changes!'
      )
      // 取消导航并停留在同一页面上
      if (!answer) return false
    })

    const userData = ref()

    // 与 beforeRouteUpdate 相同,无法访问 `this`
    onBeforeRouteUpdate(async (to, from) => {
      //仅当 id 更改时才获取用户,例如仅 query 或 hash 值已更改
      if (to.params.id !== from.params.id) {
        userData.value = await fetchUser(to.params.id)
      }
    })
  },
}

4.动态路由

动态路由参数 id:

<!-- 导航页 -->
<template>
    <router-link :to="'/news/' + newsId">新闻详情</router-link>
</template>

<script setup>
import { ref } from 'vue';
const newsId = ref('001');
</script>

获取路由参数:

<!-- 新闻详情页 -->
<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-aliveincludeexclude 属性(include 和 exclude 包含的name 是组件的name不是router name)来设置缓存:

  • include 值为字符串或者正则表达式匹配的组件name会被缓存
  • exclude 值为字符串或正则表达式匹配的组件name不会被缓存

vue2.x写法:

<keep-alive exclude="Home">  // 缓存除了Home外的所有组件
   <router-view></router-view>
</keep-alive>

vue3.x写法:

将内容传递给路由组件的 <slot>#open in new window

之前你可以直接传递一个模板,通过嵌套在 <router-view> 组件下,由路由组件的 <slot> 来渲染:

<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>

<router-view v-slot="{ Component }">
  <component :is="Component">
    <p>In Vue Router 3, I render inside the route component</p>
  </component>
</router-view>
<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属性动态判断:

meta: { title: '缓存页面', keepAlive: true }
import { watch } from 'vue'
import {useRouter} from 'vue-router'

const router =useRouter()
const includeList = [];

watch(() => router.currentRoute.value,(val) => {
  // 只要设置了keepAlive属性的,全部加入缓存列表中
  if (val.meta.keepAlive && keepAliveList.indexOf(val.name) === -1) {
    includeList.push(val.name);
  }
},{immediate: true,deep: true})

6.vite中的路由懒加载

已到达文章底部,欢迎留言、表情互动~
  • 赞一个
    0
    赞一个
  • 支持下
    0
    支持下
  • 有点酷
    0
    有点酷
  • 啥玩意
    0
    啥玩意
  • 看不懂
    0
    看不懂
评论
  • 按正序
  • 按倒序
  • 按热度
Powered by Waline v2.15.8