vue-router

2023-04-16

技术

项目创建

npm create vite@latest
# 项目命名为 sidebar
cd sidebar
npm i
npm run dev

资源准备

图标与字体,在index.html中head标签中引用

<link
    href="https://fonts.googleapis.com/css2?family=Material+Icons"
    rel="stylesheet"
/>
        
<link 
    rel="preconnect" 
    href="https://fonts.googleapis.com" 
/>
<link 
    rel="preconnect" 
    href="https://fonts.gstatic.com" 
    crossorigin 
/>
<link
    href="https://fonts.googleapis.com/css2?family=Fira+Sans:wght@100&display=swap"
    rel="stylesheet"
/>

sass

npm add -D sass

vue-router

npm i vue-router

路由配置

以下都是在src文件夹下: src/views/Home.vue

<template>
    <main class="home-page">
        <h1>Home</h1>
        <p>This is Home page</p>
    </main>
</template>

src/views/About.vue类似

<template>
    <main class="about-page">
        <h1>About</h1>
        <p>This is About page</p>
    </main>
</template>

src/main.js

import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import { createRouter,createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'

const router=createRouter({
    history: createWebHistory(),
    routes: [
        {
            path:'/',
            component: Home,
        },
        {
            path:'/about',
            component: About,
        }
    ]
})

createApp(App).use(router).mount('#app')

src/App.vue

<script setup>

</script>

<template>
  <div class="app">
    <router-view/>
  </div>
</template>

<style lang="scss">

</style>

将路由配置独立出来

新建文件夹src/router 将原来main.js有关router的代码移动到src/router/index.js,注import时文件层级会发生变化; 该文件导出模块命名为router: export default router

import { createRouter,createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const router=createRouter({
    history: createWebHistory(),
    routes: [
        {
            path:'/',
            component: Home,
        },
        {
            path:'/about',
            component: About,
        }
    ]
})

export default router

在main.js中引用

import { createApp } from 'vue'
// import './style.css'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

侧边栏准备

src/components/Sidebar.vue

<template>
    <aside>
        Sidebar
    </aside>
</template>

<script setup>

</script>

<style lang="scss" scoped>

</style>

src/App.vue

<script setup>
import Sidebar from './components/Sidebar.vue';
</script>

<template>
    <div class="app">
        <Sidebar />
        <router-view />
    </div>
</template>

<style lang="scss">
:root {
    --primary: #4ade80;
    --grey: #64748b;
    --dark: #1e293b;
    --dark-alt: #334155;
    --light: #f1f5f9;
    --sidebar-width: 300px;
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Fira sans', sans-serif;
}

body {
    background: var(--light);
}

button {
    cursor: pointer;
    appearance: none;
    border: none;
    outline: none;
    background: none;
}

.app{
    display: flex;
    main{
        flex: 1 1 0;
        padding: 2rem;

        @media (max-width: 768px) {
            padding-left: 6rem;
        }
    }
}
</style>

主要是写整体的css样式排版,我也不是很懂 接下来重点在src/components/Sidebar.vue上

侧边导航栏

<div class="menu">
    <router-link class="button" to="/">
        <span class="material-icons">home</span>
        <span class="text">Home</span>
    </router-link>
    <router-link class="button" to="/about">
        <span class="material-icons">description</span>
        <span class="text">About</span>
    </router-link>
</div>

css代码有点麻烦,忽略,只了解router-link即可

Sidebar代码

<template>
    <!-- 当is_expanded为true时,添加类名为'is_expanded'的样式 -->
    <aside :class="`${is_expanded&&'is_expanded'}`">
        <div class="logo">
            <img src="../assets/vue.svg" alt="vue"/>
        </div>
        
        <div class="menu-toggle-wrap">
            <button class="menu-toggle" @click="ToggleMenu">
                <span class="material-icons">keyboard_double_arrow_right</span>
            </button>
        </div>

        <h3>Menu</h3>
        <div class="menu">
            <router-link class="button" to="/">
                <span class="material-icons">home</span>
                <span class="text">Home</span>
            </router-link>

            <router-link class="button" to="/about">
                <span class="material-icons">description</span>
                <span class="text">About</span>
            </router-link>
        </div>

    </aside>
</template>

<script setup>
import { ref } from 'vue';
import { RouterLink } from 'vue-router';

const is_expanded=ref(false)
const ToggleMenu=()=>{
    is_expanded.value=!is_expanded.value
}

</script>

<style lang="scss" scoped>
aside{
    display: flex;
    flex-direction: column;

    background-color: var(--dark);
    color: var(--light);
    width: calc(2rem + 32px);
    overflow: hidden;
    min-height: 100vh;
    padding: 1rem;
    transition: 0.2s ease-out;

    .logo{
        margin-bottom: 1rem;
        img{
            width: 2rem;
        }
    }

    .menu-toggle-wrap{
        display: flex;
        justify-content: flex-end;
        margin-bottom: 1rem;
        
        position: relative;
        top: 0;
        transition: 0.2s ease-out;

        .menu-toggle{
            transition: 0.2s ease-out;
            .material-icons{
                font-size: 2rem;
                color: var(--light);
                transition: 0.2s ease-out;
            }

            &:hover{
                .material-icons{
                    
                    color: var(--primary);
                    transform: translateX(0.5rem);
                }
            }
        }
    }

    h3, .button .text{
        opacity: 1;
        transition: 0.3s ease-out;
    }

    .menu{
        margin: 0 -1rem;

        .button{
            display: flex;
            align-items: center;
            text-decoration: none;

            padding: 0.5rem 1rem;
            transition: 0.2s ease-out;
        }

        .material-icons{
            font-size: 2rem;
            color: var(--light);
            transition: 0.2s ease-out;
        }

        .text{
            color: var(--light);
            transition: 0.2s ease-out;
        }

        &:hover{
            background-color: var(--dark-alt);

            
                
        
        }

        
    }
    &.is_expanded{
        width: var(--sidebar-width);

        .menu-toggle-wrap{
            top: -3rem;
            .menu-toggle{
                transform: rotate(-180deg);
            }
        }
    }

    @media (max-width: 768px) {
        position: fixed;
        z-index: 99;
    }
}
</style>