vue3 + elemenplus реализует панель навигации
vue3 + elemenplus реализует панель навигации

Предисловие

Недавно я хочу создать музыкальный сайт. Он разделен на сторону управления и сторону клиента. Запишите процесс разработки здесь. Я надеюсь, что каждый сможет меня поправить.

Сделайте это сегодняПанель навигации。Прежде чем начать статью, создайте несколько новых папок.,Используется для хранения нашего кода некоторое время. (создано использоватьvite).

vueRouter

В этой статье я сосредоточусь только на том, как это реализовать, и добавлю некоторые дополнительные сведения о vueRouter. Прежде всего, если вы хотите реализовать панель навигации, вам нужна поддержка маршрутизации.

Установить

Язык кода:javascript
копировать
# Установитьмаршрутизация
yarn add vue-router@4копироватькод

Создайте новый файл маршрутизатора

Оставьте пока это здесь, позже мы изменим.

Язык кода:javascript
копировать
// /src/router/router.ts
// представлять vue-router
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    name: 'Login',
    component: () => import('@/client/login/Login.vue'), // Уведомлениездесьхотетьприноситьначальство Суффикс файла .vue 
  },
]
// createRouter создает маршрут
const router = createRouter({
  history: createWebHistory(),
  routes,
})
// Наконец экспорт. Модульный подход es6
export default routerкопироватькод

Монтируем в main.js

Подключите маршрутизатор к приложению, и его можно будет использовать по всему миру.

Язык кода:javascript
копировать
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/router'

const app = createApp(App)

app.use(router)

app.mount('#app')копироватькод

Измените файл маршрутизатора

существоватьrouterСоздайте новый в папкеclientRouter.ts(jsФайлы также могут быть)иmanageRouter.tsХранить отдельно Сторона управленияиклиентизмаршрутизация配置。а затем привести кrouter.tsсередина。

Поскольку компоненты еще не написаны, сначала они все пусты. Не забудьте их экспортировать.

manageRouter

Язык кода:javascript
копировать
const manageRouter =  // Сторона управления
{

}
export default manageRouterкопироватькод

clientRouter

Язык кода:javascript
копировать
const clientRouter = {
   
}
export default clientRouter;копироватькод

router

Язык кода:javascript
копировать
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
import clientRouter from './clientRouter'
import manageRouter from './manageRouter'
/**
 * 1. Потому что мы разделеныклиенти Сторона управлениядве части,только Сторона управления需хотеть有Layoutнавигация Поэтому следующее управление маршрутизатором разделено.
 * 2. При ссылке на структуру суффикс здесь должен быть приносить на vue. Потому что ts знает, как найти файлы .vue по умолчанию.
 * 
 */

const routes: RouteRecordRaw[] = [
  // Сторона управления
  manageRouter,
  // клиент
  clientRouter,

]

const router = createRouter({
  // режим маршрутизации
  history: createWebHistory(),
  routes,})

export default routerкопироватькод

elementplus

URL-адрес:✈️

Установить

Язык кода:javascript
копировать
// NPM
npm install element-plus --save

// Yarn
yarn add element-plus

// pnpm
pnpm install element-plusкопироватькод

монтирование main.ts

app.use(ElementPlus)

Язык кода:javascript
копировать
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/router'
// ElementPlus и Что CSS-файл
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)

app.use(router)
app.use(ElementPlus)

app.mount('#app')копироватькод

Давайте посмотрим на официальную документацию. Мы хотим добиться следующего макета.

Новый файл

Создано выше layout Новое в папке AppLayout.vue。Во-первых, сначала поместите контент официального сайта.копироватьприезжать。Затем добавьте немного цвета фона。

  • el-aside — это боковая панель. el-header — это положение заголовка навигации. el-main — это основная область отображения, ее содержимое должно меняться в соответствии с изменениями маршрута.
  • <script lang="ts" setup> здесь lang="ts"представлятьиспользоватьиспользоватьtsграмматика。setup是一个新изграмматика糖。 setup Этот параметр доступен до создания компонента, props Выполняется после анализа и представляет собой комбинированный тип. API вход. Подробную статью выложу позже.
  • <style scoped lang="scss"> для всех Vue компоненты,只хотеть设置了<style scoped></style>,Vue сгенерирует уникальное значение данных для компонента. Как показано ниже:
Язык кода:javascript
копировать
<template>
  <div class="common-layout">
    <el-container class="container">
      <el-aside class="aside">
        <AppMenu/>
      </el-aside>
      <el-container>
        <el-header class="header">Header</el-header>
        <el-main class="main"><router-view/></el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script lang="ts" setup >
import AppMenu from '@/components/AppMenu.vue';
</script>
<style scoped lang="scss">
.container{
.aside{
  background: #797979;
  width:230px;
}
.header{
  background: #a1e9d2;
  height:80px;
}
.main{

}
}

</style>копироватькод

Добавить маршрутизатор

Только что у нашего ManageRouter нет содержимого конфигурации.

  • представлятьнашAppLayoutкомпоненты,Сделайте это как самую внешнюю навигацию.
  • Другие страницы в разделе управления помещаются в дочерние элементы.
  • childrenсерединакомпонентыиз引用иAppLayoutкомпонентыиз引用都记得хотеть добавить суффикс .vue
  • Постройте это снова Home.vue и UserManage.vue здесь Чтобы прочитать «Эффект», сначала можно написать что-нибудь небрежно.
Язык кода:javascript
копировать
import AppLayout from '@/layout/AppLayout.vue'
const manageRouter =  // Сторона управления
{
  path:'/manage',
  component : AppLayout,
  children:[
    {
      path:'',
      name:'home',
      component:()=>import('@/manage/Home/Home.vue')  
    },
    {
      path:'/user',
      имя: «Управление пользователями»,
      component:()=>import('@/manage/UserManage/UserManage.vue')
    }
  ]
}
export default manageRouterкопироватькод

Home

Язык кода:javascript
копировать
<template>
 home
</template>
<script lang="ts" setup >

</script>
<style scoped lang="scss">

</style>копироватькод

UserManage

Язык кода:javascript
копировать
<template>
 Управление пользователями
</template>
<script lang="ts" setup >

</script>
<style scoped lang="scss">

</style>копироватькод

Тогда взгляните на текущий Эффект,http://localhost:3000/manage (Обратите внимание на порт, который вы запускаете).

Вы можете обнаружить, что не только есть поля, но и высота не равна 100%. Давайте изменим стиль ниже.

Изменить стиль

Установитьsass

Язык кода:javascript
копировать
# sass
// общая ситуация Установить
yarn global add sass
npm install -g sass
// Удалить соответствующий пакет
npm install sass sass-loader --save-devкопироватькод

Создайте новый файл глобального стиля.

первый вstyleНовое в папкеcommon.scss

Язык кода:javascript
копировать
// Удалить поля
*{
    margin:0;
    padding: 0;
}копироватькод

представлять

В файле приложения есть этот файл стиля.

Язык кода:javascript
копировать
@import './style/common.scss';копироватькод

Эффект

Если поля удалены следующим образом, это означает, что наш глобальный файл стиля положения работает.

Изменить высоту

Если мы хотим изменить высоту стороны, нам нужно установить его родительский элемент и родительский элемент родительского элемента на 100%. Но с появлением вх необходимости этого делать нет.

Добавьте один в контейнер height: 100vh;

Язык кода:javascript
копировать
.контейнер{
  высота: 100вх;
.в сторону{
  фон: #797979;
}
.header{
  фон: #a1e9d2;
  высота: 80 пикселей;
}
.основной{

}
}
скопировать код

Добавить меню

Давайте сначала посмотрим на Эффект

Взяв меню как компонент, мы создаем новое под компонентами. AppMenu.vue

AppMenu.vueкомпоненты

  • Оставьте место для вашего логотипа
  • Используйте эл-меню

свойство

использовать

:collapse

В развернутом и свернутом меню используется значение, переданное родительским компонентом.

:collapse-transition

Развернуть и свернуть анимацию Эффект

@open

Развернуть указанное подменю

@close

Свернуть указанное подменю

background-color

Цвет фона меню

text-color

цвет текста

active-text-color

цвет текста в выбранном состоянии

router

Включить ли режим vue-router. Включение этого режима будет использовать индекс в качестве пути для перехода по маршруту при активации навигации.

  • const props = defineProps(['isCollapse']) Значение, переданное родительским компонентом isCollapse
  • min-height: calc(100vh - 80px);Минимальная высота меню удалена.logoвысота цели
Язык кода:javascript
копировать
<template>
  <div class="logo">

  </div>
  <el-menu
    default-active="2"
    :collapse="props.isCollapse"
    :collapse-transition="false"
    @open="handleOpen"
    @close="handleClose"
    background-color="#ebf1f5"
    text-color="#606266"
    active-text-color="#2F74FF"
    class="menu"
    router
  >
    <el-sub-menu index="1">
      <template #title>
        <el-icon><location /></el-icon>
        <span>Navigator One</span>
      </template>
      <el-menu-item-group>
        <template #title><span>Group One</span></template>
        <el-menu-item index="1-1">item one</el-menu-item>
        <el-menu-item index="1-2">item two</el-menu-item>
      </el-menu-item-group>
      <el-menu-item-group title="Group Two">
        <el-menu-item index="1-3">item three</el-menu-item>
      </el-menu-item-group>
      <el-sub-menu index="1-4">
        <template #title><span>item four</span></template>
        <el-menu-item index="1-4-1">item one</el-menu-item>
      </el-sub-menu>
    </el-sub-menu>
    <el-menu-item index="2">
      <el-icon><icon-menu /></el-icon>
      <template #title>Navigator Two</template>
    </el-menu-item>
    <el-menu-item index="3" disabled>
      <el-icon><document /></el-icon>
      <template #title>Navigator Three</template>
    </el-menu-item>
    <el-menu-item index="4">
      <el-icon><setting /></el-icon>
      <template #title>Navigator Four</template>
    </el-menu-item>
  </el-menu>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import {
  Document,
  Menu as IconMenu,
  Location,
  Setting,
} from '@element-plus/icons-vue'

const props = defineProps(['isCollapse'])
const handleOpen = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
const handleClose = (key: string, keyPath: string[]) => {
  console.log(key, keyPath)
}
</script>

<style>
.logo{
  height:80px;
  background: #e1eaf4;
}
.menu{
  min-height: calc(100vh - 80px);
 
}
</style>копироватькод

Компонент AppMenu, на который ссылается AppLayout.

  • Используйте тернарный оператор для передачиisCollapseДаватьel-asideразная ширина :style="{'width':(isCollapse?'63px':'230px')}"
  • Используйте компонент AppMenu и передайте isCollapse дочернему компоненту.
  • Вам необходимо использовать метод ref для значения isCollapse, чтобы это значение можно было динамически отображать.
  • toggle Метод, используемый для изменения значения isCollapse. И после обработки по ссылке isCollapse требует .valueТолько тогда мы сможем действительно получить ценность
  • Добавлен теневой эффект в Sideиheader в стиле. здесь推荐一个阴影код生成URL-адресshadows.brumm.af/
Язык кода:javascript
копировать
<template>
  <div class="common-layout">
    <el-container class="container">
      <el-aside class="aside" :style="{'width':(isCollapse?'63px':'230px')}">
        <AppMenu :isCollapse="isCollapse"/>
      </el-aside>
      <el-container>
        <el-header class="header">
          <el-row>
            <el-col :span="1">
              <!-- el-icon size:number -->
              <el-button type="text" @click="toggle"><el-icon  :size="25"><fold /></el-icon></el-button>
            </el-col>
          </el-row>
        </el-header>
        <el-main class="main"><router-view/></el-main>
      </el-container>
    </el-container>
  </div>
</template>
<script lang="ts" setup>
import AppMenu from '@/components/AppMenu.vue';
import {ref} from 'vue'
import {Fold} from '@element-plus/icons-vue';
let isCollapse= ref(false)
const toggle = ():void=>{
  isCollapse.value = !isCollapse.value
}

</script>
<style scoped lang="scss">
.container{
  height: 100vh;
.aside{
  overflow: hidden;
  box-shadow:2.8px 2.8px 2.2px rgba(0, 0, 0, 0.02),
  6.7px 6.7px 5.3px rgba(0, 0, 0, 0.028),
  12.5px 12.5px 10px rgba(0, 0, 0, 0.035),
  22.3px 22.3px 17.9px rgba(0, 0, 0, 0.042),
  41.8px 41.8px 33.4px rgba(0, 0, 0, 0.05),
  100px 100px 80px rgba(0, 0, 0, 0.07);
}
.header{
  background:#ebf1f5;
  height:80px;
  box-shadow:
  8.7px 9.2px 2.6px rgba(0, 0, 0, 0.023),
  18.5px 19.6px 6.3px rgba(0, 0, 0, 0.025),
  29.9px 31.7px 11.9px rgba(0, 0, 0, 0.024),
  44.2px 46.8px 21.2px rgba(0, 0, 0, 0.023),
  64.1px 67.9px 39.7px rgba(0, 0, 0, 0.028),
  100px 106px 95px rgba(0, 0, 0, 0.07)
;

}
.main{

}
}

</style>копироватькод

Динамически отображаемая навигация

Метод маршрутизации: маршрутизация Хаси

В файле router.ts измените его на Hash-маршрутизацию при создании маршрута.

Язык кода:javascript
копировать
const router = createRouter({
  // режим маршрутизации
  history: createWebHashHistory(),
  routes,})копироватькод

hash

Как использовать его в vue

Язык кода:javascript
копировать
createWebHashHistory()копироватькод

Выяснить

Хэш-маршрутизация помечается знаком #, который имеет то же значение, что и # в CSS. Хэш также называется точкой привязки, которая используется для позиционирования страницы, чтобы элемент, соответствующий идентификатору, мог отображаться в видимой области (например, при возврате наверх).

history

Появление истории призвано исправить некоторые недостатки хеша.

Как использовать его в vue

Язык кода:javascript
копировать
createWebHistory()копироватькод

преимущество

  • Хэш-маршрутизация изначально использовалась для опорных точек, но теперь, когда она используется для навигации, опорные точки использовать нельзя.
  • Хэш передает параметры на основе URL-адреса, который имеет ограничение по размеру, тогда как режим истории может не только помещать параметры в URL-адрес, но и сохранять данные в определенном объекте.

Изменить файл роутера

Язык кода:javascript
копировать
import AppLayout from '@/layout/AppLayout.vue'
import { RouterView } from 'vue-router'
const manageRouter =  // Сторона управления
{
  path:'/manage',
  component : AppLayout,
  children:[
    {
      path:'/',
      name:'home',
      component:RouterView,
      meta: { title: 'первая страница', icon: 'Fold' },
    },
    {
      path:'/user',
      имя: «Управление пользователями»,
      component:RouterView,
      children:[
        {
          path:'blacklist',
          имя: «Управление черным списком»,
          component:()=>import('@/manage/UserManage/BlackList/BlackList.vue'),
        }
      ]  
    },
    { 
        path:'/dashboard',
        имя: «Данные Канбан»,
        component:RouterView,
        children:[
          {
            path:'pv',
            имя:'Просмотры',
            component:()=>import('@/manage/DashBoard/PV/PV.vue'),}
        ]  
      
    }
  ]
}
export default manageRouterкопироватькод

1. RouterView:

Как показано ниже, соответствующей страницы для навигации по управлению пользователями нет. Таким образом, мы можем использовать RouterView в качестве значения компонента.

2. Вторичное меню:

Уведомление , Вторичное менюизpathНетиспользовать /。начальство面引用изкомпоненты没有из话,По желанию вы можете создать два новых. Мы здесь только для того, чтобы посмотреть «Эффект».

Язык кода:javascript
копировать
<template>
 Pv
</template>
<script lang="ts" setup >

</script>
<style scoped lang="scss">

</style>копироватькод

Меню первого уровня

ВоляmanageRouterпредставлять

Напишите наше ManageRouterпредложение перед,В компоненте AppMenu,Как пройти необходимые данные.

Язык кода:javascript
копировать
import manageRouter from '@/router/manageRouter'копироватькод

Обход первых данных

первый в <template>середина遍历,из-за насразличать Сторона управленияиклиент所以существовать外面有一层 /manage,И мы,Панель навигациииз内容都是Чтоchildrenсерединаиз内容。所以遍历из是 manageRouter.children

Язык кода:javascript
копировать
<el-menu
    :collapse="props.isCollapse"
    :collapse-transition="false"
    @open="handleOpen"
    @close="handleClose"
    background-color="#ebf1f5"
    text-color="#606266"
    active-text-color="#2F74FF"
    :unique-opened="true"
    class="menu"
    @select="handleSelect"
    :default-active='selectKey'
    router
  >
   <template v-for="(first,index) in manageRouter.children">

     </template> 

  </el-menu>копироватькод

Различные панели навигации первого уровня

1.

Как показано на рисунке ниже, хотя домашняя страница и панель управления пользователями являются навигационными панелями первого уровня, они не совпадают. Домой соответствует страница, а управление пользователями используется только для расширения подменю.

Язык кода:javascript
копировать
   <template v-for="(first,index) in manageRouter.children">
      <el-sub-menu :index="first.path" v-if="first.children" :key="index" >
       
      </el-sub-menu>  
      <el-menu-item v-else :index="first.path" :key="'item'+index">   
              <span>{{first.name}}</span>
      </el-menu-item>  
     </template> копироватькод

2.

Используйте v-if здесь и v-else выносить суждение first.childrenБудь то пусторазличатьнавигация。

el-menu-item используется для домашних элементов без подменю, а el-sub-menu используется для элементов с подменю.

3. Уведомление :index Соответствует траектории прыжка.

Вторичное меню

Язык кода:javascript
копировать
     <el-sub-menu :index="first.path" v-if="first.children" :key="index" >
        <template  v-if="first.children">
            <el-menu-item-group v-for="(second,sec_index) in first.children"  :key="sec_index"> 
            <!--этот:index需хотеть Воляначальство级菜单измаршрутизация组合一起-->
                <el-menu-item :index="first.path+'/'+second.path"><i class="el-icon-odometer" />              
                    {{second.name}}
                  </el-menu-item>
          </el-menu-item-group>
          </template>
            <template #title>
              <span>{{first.name}}</span>
            </template>
      </el-sub-menu>  копироватькод

различать

Управление пользователямии黑名单管理都существовать el-sub-menuсередина,也是需хотеть判断различать一下из。Управление пользователями Просто отобразите название заголовка напрямую。И управление черным списком,Его нужно пройти еще раз.

Выберите цвет фона

Добавить стиль

Язык кода:javascript
копировать
.menu .el-menu-item:hover {
    background-color:#FFFFFF80;
}
.menu .el-menu-item.is-active{
  background-color: #FFFFFF80!important;
  color: #2f74ff !important;
}копироватькод

Использование значков

Поскольку значки тоже перемещаются, я попробовал несколько способов. Возможен следующий метод.

Смонтируйте значок глобально

main.ts

Добавлено в файл маршрутизации

существовать Добавлено в файл маршрутизации метаобъект, в котором хранятся значки.

Этот HomeFilled соответствует названию значка официального документа.

значок рендеринга

Язык кода:javascript
копировать
 <el-icon><component :is="first.meta.icon"/></el-icon
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose