比较全的vue-router的详解(常用)

本文详细介绍了VueRouter的各种用法,包括router-link和router-view的使用,函数式导航的三种方式,管理路由历史记录的方法,以及路由传参的query和params方式。还探讨了嵌套路由、命名视图、重定向策略以及导航守卫的应用,最后提到了过渡动画和路由元信息的设置。
摘要由CSDN通过智能技术生成

router路由

router-view

 <router-link :to="{ name: 'Login' }">Login</router-link>

router-link

函数式导航

第一种(字符串式)

<button @click="toPage('/')">Login</button>
import { useRouter } from "vue-router";
const router = useRouter();
const toPage = (url: string) => {
  router.push(url);
};

第二种(对象式)

<button @click="toPage('/')">Login</button>
import { useRouter } from "vue-router";
const router = useRouter();
const toPage = (url: string) => {
   router.push({
    path:url
  })
};

第三种(命名式)

<button @click="toPage('Login')">Login</button>
import { useRouter } from "vue-router";
const router = useRouter();
const toPage = (url: string) => {
   router.push({
    path:url
  })
};

router历史记录

第一种:router-link

//加上replace标签,取消历史记录
<router-link replace :to="{ name: 'Login' }">Login</router-link>

第二种:编程式

<button @click="toPage('/')">Login</button>
const toPage = (url: string) => {
  router.replace({
    path:url
  })
};

第二种:函数式

<button @click="next">next</button>
<button @click="prev">prev</button>
//num  == 几次历史记录
const next = () => {
  router.go(${num})
}
const prev = () => {
  router.back(${num})
}

路由传参

第一种 地址栏传参 :query

<button @click="toDetail(item)">详情</button>
type Item = {
  定义好类型
  // name: string;
  // price: number;
  // id: number;
};
const toDetail = (item: Item) => {
  router.push({
    path: "/reg",//路由地址
    query:item//传值
  });
};

//reg 接收
/html
{{route.query.item}}
/html
/script
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
/script

第二种 动态路由

const toDetail = (item: Item) => {
  router.push({
    name: "Reg",// 必须使用 路由约定的name
    params:{
      id:item.id
    }
  });
};

'/reg'
//查找到这一项
const item = data.find((item) => item.id === Number(route.params.id));
/html
	{{item?.name }}
  {{ item?.price }}
 	{{ item?.id }}
/html

嵌套路由

 {
    path:"/user",
    component:() => import('../components/footer.vue'),
    children:[
      {
        path:"",
        name:'Login',
        component:() => import('../components/login.vue')
      },{
        path:"reg",
        name:'Reg',
        component:() => import('../components/reg.vue')
      }
    ]
  },

命名视图

{
    path:'/',
    component:()=> import ('../components/root.vue'),
    children:[
      {
        path:'/user1',
    components:{ //一定是加s
      default:()=>import ('../components/A.vue')
    }
  },
    {
      path:'/user2',
  components:{ //一定是加s
    bbb:()=>import ('../components/B.vue'),
    ccc:()=>import ('../components/C.vue')
  }
  }
    ]
  },


/html
 <div>
    <router-link to="/user1">/user1</router-link>
    <router-link to="/user2">/user2</router-link>
    <hr />
    <router-view></router-view>
    <router-view name="bbb"></router-view>
    <router-view name="ccc"> </router-view>
  </div>
/html

image.pngimage.png

重定向(三种方式)

alias:['/root','/root1','/root2'],
redirect:"/user1",
 redirect:{
   path:"/user1"
},
redirect:to=>{
  return '/user1'
},
  return{//传参数
    path:'user1',
    query:{
      name:"ckj",
      age:20
    }
  }

导航守卫

前置

const whileList = ['/'] //白名单
router.beforeEach((to,from,next)=>{
  //要么白名单之内,要么已经登陆过 才放行 next()
  if(whileList.includes(to.path)||localStorage.getItem('token')){
    next()
  }else{
    next('/')
  }
})

后置(制作进度条)

<template>
  <div class="wrapper">
    <div ref="bar" class="bar"></div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
let speed = ref<number>(1); //初始速度
let bar = ref<HTMLElement>(); 
let timer = ref<number>(0); //定义一个定时器
//开始
const startLoading = () => {
  let dom = bar.value as HTMLElement; //获取元素
  speed.value = 1; 
  
  timer.value = window.requestAnimationFrame(function fn() {
    if (speed.value < 90) {
      speed.value += 1; //递增
      dom.style.width = speed.value + "%"; //设置百分比样式
      timer.value = window.requestAnimationFrame(fn); //递归
    } else {
      speed.value = 1;
      window.cancelAnimationFrame(timer.value); //终止
    }
  });
};
//结束
const endLoading = () => {
  let dom = bar.value as HTMLElement;
  setTimeout(() => {
    window.requestAnimationFrame(() => {
      speed.value = 100;
      dom.style.width = speed.value + "%";
    });
  }, 1000);
};
//暴露给全局方法
defineExpose({
  startLoading,
  endLoading,
});
</script>
<style lang="less" scoped>
.wrapper {
  position: fixed;
  top: 0;
  width: 100%;
  height: 2px;
  .bar {
    height: inherit;

    width: 0;
    background-color: rgb(43, 200, 19);
  }
}
</style>

import  loadingBar  from '@/components/loadingBar.vue'
import { createVNode,render } from 'vue'
//使用Vnode转换一真实dom
const Vnode = createVNode(loadingBar)
render(Vnode,document.body)//挂载在全局上
router.beforeEach((to,from,next)=>{
  Vnode.component?.exposed?.startLoading()
})
router.afterEach((to,from)=>{
  Vnode.component?.exposed?.endLoading()
})

路由元组件

title

/路由.ts
declare module 'vue-router'{
  interface RouteMeta{
    title:string,
  }
}
{
      path:'/',
      component:()=>import('@/views/Login.vue'),
      meta:{
        title:'登录页面',
      }
    },
/路由.ts

/main.ts
router.beforeEach((to,from,next)=>{
  console.log(to);
  document.title = to.meta.title
})
/main.ts

transition

/路由.ts
declare module 'vue-router'{
  interface RouteMeta{
    title:string,
    transition:string
  }
}
{
      path:'/',
      component:()=>import('@/views/Login.vue'),
      meta:{
        title:'登录页面',
        transition:"animate__fadeIn"
      }
    },
/路由.ts

/app.vue
<template>
   <div>
     <router-view #default="{route,Component}">
     <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
      <component :is="Component"></component>
     </transition>
     </router-view>
   </div>
</template>
<script setup lang='ts'>
  //npm i animate.css
import 'animate.css'
</script>
/app.vue

滚动行为

const router = createRouter({
  history:createWebHistory(),
  //保存跳转前的距离
  scrollBehavior:(to,from,savePosition)=>{
    if(savePosition){
      return savePosition
    }else{
      return{
        top:0
      }
    }
  },
  routes:[
    ]
})

动态路由

转过去路由 刷新才正常显示

debug:

  1. 检查路由信息是否有误、是否多空格.vue插件观察routes是否添加正确

image.png

  1. 放行 next(),其余next(‘/login’)、next(to)等等都不是放行,是关闭一个新打开一个

image.png

  1. 一定不要忘记抱起来,同时增加一个父级div包裹以防万一
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值