Vue router

1、Router

一、URL 的hash 改变路由原理

URL的hash也就是锚点(#),本质上是改变window.location的href属性

可以通过直接复制location.hash来改变href,但是页面不发生刷新

<div id="app">
    <a href="#/home">home</a>
    <a href="#/about">about</a>
    <div class="content">Default</div>
</div>
<script>
    const contentEl = document.querySelector(".content");
    window.addEventListener("hashchange", () => {
        switch(location.hash) {
            case "#/home":
                contentEl.innerHTML = "home";
                break;
            case "#/about":
                contentEl.innerHTML = "about";
                break;
            default: 
                contentEl.innerHTML = "default";
        }
    })
</script>

二、URL 的history 改变路由原理

history 接口是HTML5新增的,它有六种模式改变URL而不刷新页面

  • replaceState:替换原来的路径
  • pushState:使用新的路径
  • popState:路径的回退
  • go:向前或向后改变路径
  • forward:向前改变路径
  • back:向后改变路径
<div id="app">
    <a href="/home">home</a>
    <a href="/about">about</a>
    <div class="content">Default</div>
</div>
<script>
    const contentEl = document.querySelector(".content");
    const aEls = document.getElementsByTagName("a");
    for(let aEl of aEls) {
        aEl.addEventListener("click", e => {
            e.preventDefault();
            const href = aEl.getAttribute("href");
            history.pushState({},"",href);
            switch(location.pathname) {
                case "/home":
                    contentEl.innerHTML = "home";
                    break;
                case "/about":
                    contentEl.innerHTML = "about";
                    break;
                default: 
                    contentEl.innerHtml = "Default";
            }
        })
    }
</script>

三、路由的基本使用

// App.vue
<template>
    <div id="app">
        <router-link to="/home">首页</router-link>
        <router-link to="about">关于</router-link>

        <router-view/>
    </div>
</template>

// router.js
import { createRouter, createWebHistory, createrWebHashHistory } from 'vue-router'
import Home from '../pages/Home.vue';
import About from '../pages/About.vue';

// 配置映射关系 routes
const routes = [
    { path: "/", redirect: "/home" },
    { path: "/home", component: Home },
    { path: "/about", component: About }
];

// 创建路由对象 router
const router = createRouter({
    routes,
    history: createrWebHashHistory(),
    // history: createWebHistory()
})

export default router

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

const app = createApp(App);
app.use(router);
app.mount("#app");

四、router-link 的属性

  • to:只是一个字符串,或者是一个对象
  • replace:当点击时,会调用router.replace(),而不是router.push()
  • active-class:设置激活a元素后应用的class,默认是router-link-active
  • exace-active-class:精准匹配,链接精准激活时,应用于渲染的<a>的class,默认是router-link-exact-active
<template>
    <div id="app">
        <router-link to="/home" replace active-class="why-active">首页</router-link>
        <router-link to="/about" replace active-class="why-active">关于</router-link>

        <router-view/>
    </div>
</template>
<style scoped>
    .router-link-active {
        color: red
    }
    .why-active {
        color: blue
    }
</style>

// router.js
// 修改active-class 和 exace-active-class
const router = createRouter({
    routes,
    history: createWebHistory(),
    linkActiveClass: "why-active",
    linkExactActiveClass: "thy-exact-active"
})

 五、路由懒加载

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

// 配置映射关系 routes
const routes = [
    { path: "/", redirect: "/home" },
    // 路由懒加载 
    // import 返回的是一个promise
    // 在打包的时候会对静态资源自动分包
    // magic comment webpack魔法注释 修改打包后的文件名称
    { path: "/home", component: () => import ( /* webpackChunkName: "home-chunk" */"../pages/Home.vue" )},
    { path: "/about", component: () => import ( /* webpackChunkName: "about-chunk" */"../pages/About.vue" )}
];

// 创建路由对象 router
const router = createRouter({
    routes,
    history: createrWebHashHistory(),
    // history: createWebHistory()
})

export default router

六、路由的其他属性

const routes = [
    { path: "/", redirect: "/home" },
    { 
        path: "/home", 
        component: "home",
        // 路由记录独一无二的名称
        name: "home",
        // 自定义数据
        meta: {
            name: "why",
            age: 18,
            height: 1.88
        }
    }
];

七、动态路由匹配

// router.js
import { createRouter, createWebHistory, createrWebHashHistory } from 'vue-router'
import Home from "../pages/Home.vue";
import About from "../pages/About.vue";
import User from "../pages/User.vue"

// 配置映射关系 routes
const routes = [
    { path: "/", redirect: "/home" },
    { 
        path: "/home", 
        component: Home,
    },
    { 
        path: "/about", 
        component: About,
    },
    { 
        path: "/user/:username/id/:id", 
        component: User,
    }
];
// 创建路由对象 router
const router = createRouter({
    routes,
    history: createWebHistory(),
    // history: createrWebHashHistory(),
})

export default router


// App.vue
<template>
    <div id="app">
        <router-link to="/home" >首页</router-link>
        <router-link to="/about" >关于</router-link>
        
        <router-link :to="'/user' + name + 'id' + id">关于</router-link>
        
        <router-view/>
    </div>
</template>
<script>
    export default {
        data() {    
            return {
                name: why,
                id: 111
            }
        },
    }
</script>


// User.vue
<template>
    <div>
        <h2>User: {{ $route.params.username }} - {{ $route.params.id }}</h2>
    </div>
</template>
<script>
    import { useRoute } from "vue-router"
    export default {
        created() {
            console.log(this.$route.params.username)
        },
        setup() {
            const route = useRoute();
            console.log(route.params.username)
        }
    }
</script>

八、NotFound 的匹配路由

// NotFound.Vue
<template>
    <div>
        <h2>Page Not Found</h2>
        <h1>{{ $route.params.patchMatch }}</h1>
    </div>
</template>


// router.js
import { createRouter, createWebHistory, createrWebHashHistory } from 'vue-router'
import Home from "../pages/Home.vue";
import About from "../pages/About.vue";

// 配置映射关系 routes
const routes = [
    { path: "/", redirect: "/home" },
    { 
        path: "/home", 
        component: Home,
    },
    { 
        path: "/about", 
        component: About,
    },
    {
        path: "/:pathMatch(.*)*",
        component: () => import("../pages/NotFound.vue")
    }
];
// 创建路由对象 router
const router = createRouter({
    routes,
    history: createWebHistory(),
    // history: createrWebHashHistory(),
})
export default router

九、路由嵌套

// Home.vue
<template>
    <div>
        <h2>Home</h2>
        <router-link to="/home/message">消息</router-link>
        <router-link to="/home/shops">商品</router-link>
        <router-view></router-view>
    </div>
</template>


// router.js
import { createRouter, createWebHistory, createrWebHashHistory } from 'vue-router'
import Home from "../pages/Home.vue";
import About from "../pages/About.vue";
// 配置映射关系 routes
const routes = [
    { path: "/", redirect: "/home" },
    { 
        path: "/home", 
        component: Home,
        children: [
            {
                path: "",
                redirect: "/home/message"
            },
            {
                path: "message",
                component: () => import("../pages/HomeMessage.vue")
            },
            {
                path: "shops",
                component: () => import("../pages/HomeShops.vue")
            }
        ]
    },
    { 
        path: "/about", 
        component: About,
    },
];
// 创建路由对象 router
const router = createRouter({
    routes,
    history: createWebHistory(),
    // history: createrWebHashHistory(),
})
export default router

十、编程式导航

// App.vue
<template>
    <div id="app">
        <router-link to="/home" >首页</router-link>
        <router-link to="/about" >关于</router-link>
        
        <button @click="jumpToAbout">跳转到关于</button>
        <button @click="forwardOneStep">前进一步</button>
        
        <router-view/>
    </div>
</template>
<script>
    import { useRouter } from 'vue-router'
    export default {
        // Vue2 
        methods: {
            jumpToHome() {
                this.$router.push("/about")
            }
        },
        // Vue3
        setup() {
            const router = useRouter()
            const jumpToAbout = () => {
                // router.push("/about")
                // 通过query 方式传递参数
                router.push({
                    path: "/about",
                    query: {
                        name: "why",
                        age: 18
                    }
                })
            }
            const forwardOneStep = () => {
                router.replace("/about")
                router.go(1);
                router.go(-1);
                router.forward();
                router.back();
            }
            return {
                jumpToAbout,
                forwardOneStep
            }
        }
    }
</script>


// About.vue
<template>
    <div>
        <h2>关于 {{ $route.query.name }} - {{ $route.query.age }}</h2>
    </div>
</template>

十一、router-link 的v-slot

<template>
    <div id="app">
        <!-- props: href 跳转的链接 -->
        <!-- props: route 对象 -->
        <!-- props: navigate 导航函数 -->
        <!-- props: isActive 是否当前处于活跃的状态 -->
        <!-- props: isExactActive 是否当前处于精确的活跃的状态 -->

        <router-link to="/home" v-slot="props" custom>
            <p>{{ props.route }}</p>
            <button>{{ props.href }}</button>
            <button @click="props.navigate">哈哈哈</button>
            <span :class="{'active': props.isActive}">{{ props.isActive }}</span>
            <span :class="{'active': props.isExactActive}">{{ props.isExactActive }}</span>
        </router-link>
        
        <router-view/>
    </div>
</template>

十二、

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值