vue基础知识—9.路由

本文详细介绍了Vue.js的路由管理库vue-router的使用,包括安装、基础配置如导航链接、动态路由匹配、嵌套路由、编程导航和命名路由。还深入探讨了路由守卫的全局、独享和组件内应用,数据获取的最佳时机,动态添加路由,以及组件缓存和懒加载等进阶话题,旨在帮助开发者更好地理解和运用vue-router。
摘要由CSDN通过智能技术生成

9.1安装

vue add router

9.2基础

9.2.1 起步

<nav>
    <router-link to="/">首页</router-link>
    <router-link to="/about">管理</router-link>
</nav>
<router-view></router-view>
<template>
    <div>
        <message ref="msgSuccess" class="success">
            <!-- 命名为title插槽内容 -->
            <template v-slot:title="slotProps">
                <strong>{{slotProps.title}}</strong>
            </template>
            <!-- 默认插槽内容 -->
            <template v-slot:default>新增课程成功!</template>
            </message>
            <message ref="msgWarning" class="warning">
            <!-- 命名为title插槽内容 -->
            <template v-slot:title>
            <strong>警告</strong>
            </template>
            <!-- 默认插槽内容 -->
            <template v-slot:default>请输入课程名称!</template>
        </message>
        <cart-add v-model="course" @add-course="addCourse"></cart-add>
        <course-list :courses="courses"></course-list>
    </div>
</template>
<script>
import CartAdd from "@/components/CartAdd.vue";
import CourseList from "@/components/CourseList.vue";
import Message from "@/components/Message.vue";
import { getCourses } from "@/api/course";
export default {
    name: "app",
    data() {
        return {
            course: "",
            courses: []
        };
    },
    components: {
        CartAdd,
        CourseList,
        Message
    },
    async created() {
        // 组件实例已创建,由于未挂载,dom不存在
        const courses = await getCourses();
        this.courses = courses;
    },
    methods: {
        addCourse() {
        if (this.course) {
            // 添加course到数组
            this.courses.push({ name: this.course, price: 8999 });
            this.course = "";
            this.$refs.msgSuccess.toggle();
        }else{
            this.$refs.msgWarning.toggle();
        }
        }
        }
    }
    </script>

9.2.2 动态路由匹配

我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果:

{path:'/user/:id',component:User}
<div>
    <h2>detail page</h2>
    <p>{{$route.params.name}}</p>
</div>
{
    path:'/course/:name'
    component:()=>import('../views/Detail.vue')
}
<router-link :to="`/course/${c.name}`">
    {{c.nmae}}-{{c,price|currency('¥')}}
</router-link>

通配符
适合做404页面路由

{
    path:'*',
    compoent:()=>import('../views/404.vue')
}

9.2.3 嵌套路由

<router-link :to=`/about/${c.name}`">
  {{c.name}}-{{c.price|currency('¥')}}
</router-link>
{
    path:'/about',
    name:about,
    component:()=>import('../views/About.vue')
    children:[{
        path:':name'
        component:()=>import('../views/Detail.vue')
    }]
}
export default{
    watch:{
        $route:{
            handler:()=>{
                console.log("$route change")
            },
            immediate:true
        }
    }
}

9.2.4 编程导航

router.push(location,onComplete?,onAbort?)
//字符串
router.push('home')
//对象
router.push({path:'home'})
//命名的路由
router.push({name:'user',params:{userId:'123'}})
//带参数查询
router.push({path:'register'},query:{plan:'private'})


<div @click="selectedCourse = c;this.$router.push(`/about/${c.name}`)">
  {{c.name}}-{{c.price|currency('¥')}}
</div>

9.2.5 命名路由

通过一个名称来标识一个路由显得更方便一些,特别在链接一个路由,或者是执行一些跳转的时候,你可以在创建Router实例的时候,在routes配置中给某个路由设置名称

const router = new VueRouter({
    routes:[
        {
            path:'/user/:userId',
            name:'user'
            component:User
        }
    ]
})

要链接到一个命名路由,可以给router-link的to属性传一个对象

<router-link 
    :to = "{
        name :'user',
        params:{userId:123}
    }"
>
User
</router-link>

调用router.push()时

router.push({
    name:'user',
    params:{userId:123}
})

9.3进阶

9.3.1路由守卫

vue-router提供的导航守卫主要是通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的,单个路由独享的,或者组件级的。
全局守卫

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


router.beforeEach((to,form,next)=>{
    if(to.meta.auth){
        if(window.isLogin){
            next()
        }else{
            next('/login?redirect='+to.fullPath')
        }
    }else{
        next()
    }
})
{
    path:'/about',
    meta:{
        auth:true
    }
},{
    path:'/login'
    component:()=>import('../views/Login.vue')
}
<template>
    <div>
        <button @click="login" v-if="isLogin">登录</button>
        <button @click="loginout" v-else>登出</button>
    </div>
</template>
<script>
    export default{
        methods:{
            login(){
                window.isLogin = true
                this.$router.push(this.$route.query.redirect)
            },
            logout(){
                window.isLogin = false
            }
        },
        computed:{
            isLogin(){
                return window.isLogin
            }
        }
    }
</script>

路由独享的守卫
可以路由配置上直接定义beforeEnter守卫:

{
    path:'/about',
    name:'about',
    beforeEnter(to,form,next){
        if(to.meta.auth){
            if(window.isLogin){
                next()
            }else{
                next('/login?redirect='+to.fullPath)
            }
        }else{
            next()
        }
    }
}

组件内守卫
可以在路由组件内直接定义以下路由导航守卫

beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
beforeRouteEnter(to,from,next){
    if(window.isLogin){
        next()
    }else{
        next("/login?redirect="+to.fullPath)
}

9.3.2 数据获取

路由激活时,获取数据的时机有两个:
路由导航前

//组件未渲染,通过给next传递访问组件实例
beforeRouteEnter(to,from,next){
    getPost(to,params.id,post=>{
        next(vm=>vm.setData(post))
    })
}

//组件已渲染,可以访问this直接赋值
beforeRouteUpdate(to,from,next){
    this.post = null
    getPost(to.params.id,post=>{
        this.setData(post)
        next()
    })
}

路由导航后

created(){
    this.fetchData()
},
watch:{
    '$route':'fecthData'
}

9.3.3 动态路由

通过router.addRoutes(routes)方式动态添加路由

router.beforeEach((to,form,next)=>{
    if(window.isLogin){
        if(to.path==='/login'){
            next('/')
        }else{
            next()
        }
    }else{
        if(to.path==='/login'){
            next()
        }else{
            next('/login?redirect='+to.fullPath)
        }
    }
})
login(){
    window.isLogin = true;
    this.$router.addRoutes([
        {
            path:"/about"
        }
    ])
    const redirect = this.$route.query.redirect()||''
    this.$router.push(redirect)
}

9.3.4 路由组件缓存

利用keepalive做组件缓存,保留组件状态,提高执行效率

<keep-alive include="about">
    <router-view></router-view>
</keep-alive>

使用include或exclude时要给组件设置name
两个特别的生命周期:activated,deactivated

9.3.5 路由组件懒加载

路由组件的懒加载可以把不同路由对应的组件分割成不同的代码块,然后路由被访问的时候,才加载对应的组件

()=>import("../views/About")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值