vue-router的使用
安装
npm install vue-router@next
设置路由
import { createRouter, createWebHistory } from "vue-router";
// 引入
import Home from "@/views/Home.vue";
import About from "@/views/About.vue";
// 路由信息
let routes = [
{
path: "/",
name: 'home',
component: Home,
},
{
path: "/about",
name: 'about',
component: About,
},
];
// 路由器
const router = createRouter({
history: createWebHistory(), // HTML5模式
routes,
});
export default router;
引入路由
import { createApp } from 'vue'
import App from './App.vue'
// 引入插件
import router from "@/store/index";
// 安装router插件
createApp(App).use(router).mount('#app')
挂载路由
在App.vue中
<template>
<router-view></router-view>
</template>
路由跳转
嵌套路由
在项目中,想要嵌套路由,要配置children属性
// 文件目录结构
src
————views
————————Home
————————————components
————————————————HomeAside.vue
————————————————HomeHeader.vue
————————————————HomeMain.vue
————————————Home.vue
————App.vue
例如,在App.vue中
<script setup lang="ts">
</script>
<template>
<RouterView/>
</template>
<style lang="scss">
@import '@/styles/reset.scss';
@import '@/styles/common.scss';
@import '@/styles/iconfont.scss';
</style>
而在子路由中HomeMain组件中
<template>
<div>
<router-view></router-view>
</div>
</template>
<script setup lang="ts">
</script>
<style lang="scss" scoped>
</style>
在router.js下的配置
import { createRouter, createWebHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
// 主页面
import Home from '@/views/Home/Home.vue'
// 登录注册
import Login from '@/views/Login/Login.vue'
import Register from '@/views/Register/Register.vue'
// 信息维护
import Charts from '@/views/Charts/Charts.vue'
import Information from '@/views/Information/Information.vue'
import Performance from '@/views/Performance/Performance.vue'
import TagManage from '@/views/TagManage/TagManage.vue'
import AccountManage from '@/views/AccountManage/AccountManage.vue'
declare module 'vue-router' {
interface RouteMeta {
auth?: boolean;
menu?: boolean;
title?: string;
icon?: string;
}
}
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: Home,
redirect: '/maintenance',
meta: {
auth: true,
menu: true,
title: '信息维护',
icon: '#icon-yonghuweihu'
},
children: [
{
path: '/maintenance',
name: 'Maintenance',
redirect: '/charts',
meta: {
auth: true,
menu: true,
title: '信息维护',
icon: '#icon-yonghuweihu'
},
children:[
{
path: '/charts',
name: 'Charts',
component: Charts,
meta: {
auth: true,
menu: true,
title: '数据展示',
icon: '#icon-a-007_shujufenxi'
}
},
{
path: '/information',
name: 'Information',
component: Information,
meta: {
auth: true,
menu: true,
title: '员工信息',
icon: '#icon-yuangongguanli'
}
},
{
path: '/performance',
name: 'Performance',
component: Performance,
meta: {
auth: true,
menu: true,
title: '绩效成绩',
icon: '#icon-jixiaopinggu'
}
},
{
path: '/tagManage',
name: 'TagManage',
component: TagManage,
meta: {
auth: true,
menu: true,
title: '标签管理',
icon: '#icon-biaoqian'
}
},
{
path: '/accountManage',
name: 'AccountManage',
component: AccountManage,
meta: {
auth: true,
menu: true,
title: '账号管理',
icon: '#icon-zhanghaoguanli1'
}
},
{
path: '/employeePortrait',
name: 'EmployeePortrait',
component: EmployeePortrait,
meta: {
auth: true,
menu: true,
title: '员工画像',
icon: '#icon-yonghuhuaxiang1'
}
}
]
}
]
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/register',
name: 'register',
component: Register
}
]
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
路由传参
query传参
<template>
<div class="container">
<!-- 传参 -->
<router-link v-for="product in arrs" class="item" :key="blog.id" :to="{ name: 'productdetail', query: { id: product.id } }">
</router-link>
</div>
</template>
设置query: { id: product.id } }给路由传参
接收query传参
<template>
<div class="container">
<h2>{{ product.name }}</h2>
<p>{{ product.description }}</p>
</div>
</template>
<script>
import sourceData from "@/data.json";
import { useRoute } from "vue-router";
export default {
setup(props) {
// 获取路由
let route = useRoute();
// 获取query参数
let productId = route.query.id;
return {
blog: sourceData.find((product) => product.id == productId),
};
},
};
</script>
通过route.query.id就能获取到传递的商品id, 然后就能显示对应的商品详细信息了。
动态路由
在碰到入商品页这种,大多商品页面逻辑都相同的,我们可以使用动态路由去实现
配置
<!-- router.js -->
let routes = [
//...
{
<!-- 动态路由路径 -->
path: '/productdetail/:id',
name: "productdetail",
component: () => import("@/views/ProductDetail.vue")
}
];
传参
<template>
<div class="container">
<!-- 传参 -->
<router-link v-for="product in arrs" class="item" :key="product.id" :to="{ name: 'productdetail', params: { id: product.id } }">
</router-link>
</div>
</template>
通过设置params:{ id: blog.id} 给动态路由传参
接收参数
let productId = route.params.id;
通过route.params.id就能获取传递的商品id,就能显示对应的商品详情页信息
路由守卫
独享守卫
<!-- router.js -->
{
path: 'sign',
name: 'sign',
component: Sign,
meta: {
menu: true,
title: '在线打卡签到',
icon: 'calendar',
auth: true
},
async beforeEnter(to, from, next){
const usersStore = useUsersStore()
const signsStore = useSignsStore()
const newsStore = useNewsStore()
const { infos: usersInfos } = storeToRefs(usersStore)
const { infos: signsInfos } = storeToRefs(signsStore)
const { info: newsInfo } = storeToRefs(newsStore)
if( _.isEmpty(signsInfos.value) ){
const res = await signsStore.getTimeAction({ userid: usersInfos.value._id })
if(res.data.errcode === 0){
signsStore.updateInfos(res.data.infos)
}
else{
return;
}
}
if( _.isEmpty(newsInfo.value) ){
const res = await newsStore.getRemindAction({ userid: usersInfos.value._id })
if(res.data.errcode === 0){
newsStore.updateInfo(res.data.info)
}
else{
return;
}
}
next()
}
}
全局守卫
在某些路由中需要一些特定的操作,譬如访问前必须是登录用户。这时候可以通过使用meta属性和全局守卫来实现。
router.beforeEach((to, from, next)=>{
const usersStore = useUsersStore()
const { token, infos } = storeToRefs(usersStore)
if( to.meta.auth && _.isEmpty(infos.value) ){
if(token.value){
usersStore.infosAction().then((res)=>{
if(res.data.errcode === 0){
usersStore.updateInfos(res.data.infos)
if(res.data.infos.permission.includes(to.name)){
next()
}
else{
next('/403')
}
}
})
}
else{
next('/login');
}
}
else{
if( token.value && to.path === '/login' ){
next('/');
}
else{
next();
}
}
})
组件内的路由守卫
<script setup>
import { ref } from '@vue/reactivity';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import sourceData from "@/data.json";
// 定义props
const props = defineProps({
catId: {
type: Number,
required: true,
}
})
let arrs = ref([]);
let fetchData = (id) => {
return id !== 0 ? sourceData.filter((blog) => blog.catId == id) : sourceData;
}
<!-- 组件内的路由守卫 -->
onBeforeRouteUpdate((to, from, next) => {
arrs.value = fetchData(to.params.catId)
});
arrs.value = fetchData(props.catId);
</script>
对于一个带有动态参数的路径 /category/:catId,在 /category/1 和 /category/2 之间跳转的时候, 会触发onBeforeRouteUpdate的路由钩子函数,在钩子函数中可以进行数据的更新。
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 LeoStar
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果