Vue3学习 路由

安装router

npm init vite@latest
npm install
npm install vue-router@4 -S

创建: src/router/index.ts

import {createRouter, createWebHistory} from 'vue-router'

const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        name:'Login'
        component:()=>import('../components/Login.vue')
    },
    {
        path:'/reg',
        name:'Reg',
        component:()=>import('../components/Reg.vue')
    },
    {
        path:'/logout/:id',
        name:'Logout',
        component:()=>import('../components/Logout.vue')
    }
]
const router = createRouter({
    history:createWebHistory(),
    routes:routes
})
export default router

在main.ts中注册

import router from './router'
app.use(router)

在App.vue中使用

<router-link to="/">Login</router-link>
<router-link to="/reg">Regist</router-link>
<router-view></router-view>

路由的模式

createWebHashHistory()
location.hash = '/'  跳转到Login.vue 使用hash时url路径带有#
window.addEvenetListener('hashchange',(e)=>{   //监听浏览器前进后退按钮的变化
    console.log(e)
})

createWebHistory() 基于H5的history来实现,URL不带#
window.addEvenetListener('popstate',(e)=>{   //监听浏览器前进后退按钮的变化
    console.log(e)
})
history.pushState({state:1},'', '/reg') 不会被浏览器监听到

命名路由和编程式导航

<router-link to="{name:'Login'}">Login</router-link>
<router-link to="{name:'Reg'}">Regist</router-link>
或
<a href='/'>Login</a>
<a href='/reg'>Regist</a> //这种方式和router-link的不一样是页面会刷新
<router-view></router-view>

编程式导航

@click='toPage("/reg")'

import {useRouter} from 'vue-router'
const router = useRouter()
const toPage = (url:string)=>{
    router.push(url)
    或对象的形式
    router.push({
        path:url   //还可以传递参数
    })
    也可以是命名式跳转,path改成name  @click='toPage("Reg")'
    router.push({
        name:urlName   //还可以传递参数
    })
}

历史记录 使用replace来防止页面前进后退

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

编程式防止页面前进后退

router.replace({
    path:url   //还可以传递参数
})

编程式实现前进后退

const next = ()=>{
    router.go(1);
    //router.go(-1);  后退
}

const prev = ()=>{
    router.go(-1);  或  router.back();
}

路由传参

A.vue 

@click=toDetails(item)

import {useRouter} from 'vue-router'
import {data} from './data.js'   //js中为{data:[{name:'Jason', price:2.0, id:1001},{}]}

type ItemData = {
    name:string,
    price:number,
    id:number
}

const router = useRouter()

const toDetails = (item:ItemData)=>{
    //query方式,参数拼接在url上,接收方也用query来取
    router.push({
        path:'/reg',
        query:item   
    })
    //params式传参,只能用name,参数不显示在url中
    router.push({
        name:'Reg',
        params:item
    })
    
    //动态路由参数
    router.push({
        name:'Reg',
        params:{
            id:item.id
        }
        //或者直接params:item,因为item中有id属性
    })
}

Reg.vue

//接收query式传参
{{ route.query.name }}

//接收params式传参
{{ route.params.name }}

import {useRoute} from 'vue-router'
const route = useRoute()

嵌套路由

适用于一个页面中部分内容不变,部分需要变化的场景,比如后台管理界面和手机界面

const routes:Array<RouteRecordRaw> = [
    {
        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')
            }
        ]
    }
]

Footer.vue

<router-view></router-view>
<router-link to="/user">Login</router-link> 
<router-link to="/user/reg">Regist</router-link>

命名视图

const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        component:()=>import('../components/Root.vue')
        children:[
            {
                path:'/user1',
                components:[
                    default:()=>import('../components/AAA.vue')
                ]
            },
            {
                path:'/user2',
                components:[
                    bbb:()=>import('../components/BBB.vue'),
                    ccc:()=>import('../components/CCC.vue')
                ]
            }
        ]
    }
]

Root.vue

<router-link to='/user1'>User1</router-link>
<router-link to='/user2'>User2</router-link>
<router-view></router-view>
<router-view name='bbb'></router-view>
<router-view name='ccc'></router-view>

重定向和别名

const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        component:()=>import('../components/Root.vue'),
        redirect: '/user1',  //重定向  或{path:'/user1', query:{}} 或 {name:'User1',params:    
                    {}} 或 to=>{return '/user1'} 或to=>{return {name:'User1',params:{}}}
        alias:['/root','/rt'] //取别名
        children:[
            {
                path:'/user1',
                name:'User1',
                components:[
                    default:()=>import('../components/AAA.vue')
                ]
            },
            {
                path:'/user2',
                components:[
                    bbb:()=>import('../components/BBB.vue'),
                    ccc:()=>import('../components/CCC.vue')
                ]
            }
        ]
    }
]

前置及后置守卫

import {createRouter, createWebHistory} from 'vue-router'

const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        component:()=>import('@/views/Login.vue')
    },
    {
        path:'/index',
        component:()=>import('@/views/Index.vue')
    }
]
const router = createRouter({
    history:createWebHistory(),
    routes:routes
})
export default router

登录成功后保存token

localStorage.setItem('token', '123');

前置守卫 main.ts中:

const whiteList = ['/']
router.beforeEach((to, from, next)=>{
     if(whiteList.includes(to.path) || localStorage.getItem('token')) {
        next()
     }else{
        next('/') //不在白名单或没有凭证的话,跳转回登录界面
     }
})

后置守卫 
LoadingBar.vue

defineExpose({
    startLoading,
    endLoading
})

main.ts中:

import { createApp, createVNode,render } from 'vue'
import loadingBar from '@/views/LoadingBar.vue'

const VNode = createVNode(loadingBar)  //转换成虚拟dom
render(VNode, document.body) //将虚拟函数挂载到body
router.beforeEach((to, from, next)=>{
    VNode.component?.exposed?.startLoading()
})
router.afterEach((to, from) => {
    VNode.component?.exposed?.endLoading()
})

路由元信息

src/router/index.ts

declare module 'vue-router' {
    interface RouteMeta {
        title:string
    }
}
const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        component:()=>import('@/views/Login.vue'),
        meta:{
            title:'登录'
        }
    }
]

main.ts中:

router.beforeEach((to, from, next)=>{
    document.title=to.meta.title
})

路由过渡动效

src/router/index.ts

declare module 'vue-router' {
    interface RouteMeta {
        title:string,
        transition:string
    }
}
const routes:Array<RouteRecordRaw> = [
    {
        path:'/',
        component:()=>import('@/views/Login.vue'),
        meta:{
            title:'登录',
            transition:'animate_fadein'
        }
    }
]

 App.vue

<router-view #default='{route, Component}'>
    <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
        <component :is='Component'></component>
    </transition>
</router-view>

动态路由

1: 从后台返回路由配置信息
2: 登录成功后调用后台服务获取用户路由信息,使用addRoute和removeRoute来动态添加上删除路由信息

import {useRouter} from 'vue-router'
const router = useRouter()

const initRouter = async()=>{
    const result = await axios.get('http://localhost:8080/login',{params:formInline})
    result.data.route.forEach((v:any)=>{
        router.addRoute({
            path:v.path,
            name:v.name,
            component:()=>import(`../views/${v.component}`)  //注意这里不能用@代替src
        })
    })
}


    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值