用到技术栈:
vue3+vite+element-plus
使用 CSS3 中的 transition 属性来实现平滑过渡效果。可以给 aside 元素添加 transition 属性,来让浏览器自动实现宽度变化的过渡动画
设置过渡时间为 0.3s,结合 will-change 属性进行优化---will-change: width;
将过渡时间延长到较长的时间段,或者使用缓动函数(如 ease-in-out)来实现更柔和的过渡效果
.aside {
transition: width 0.8s ease-in-out 0.1;
}
transition-property ?过渡值
添加过渡的属性,常见的取值有:? ? ? ? ? ?transition-property: none【不选择任何需要过渡的属性】
? ? ? ? ? ?transition-property: all【选择所有可以过渡的属性】
? ? ? ? ? ?transition-property: property【指定需要过渡的属性,属性间用逗号分隔】
?transition-duration ?过渡时间
transition-duration指的是过渡效果持续的时间,单位为 s(秒)或者ms(毫秒)???????????transition-duration: .5s ;
? ? ? ? ? ?transition-duration: 1000ms ;
? ? ? ? ? ?transition-duration: 2s ;
transition-timing-function 过渡速度
transition-timing-function 指的是过渡效果变化的快慢,常见的取值有:? ? ? ? ? ?transition-timing-function: linear【匀速】
? ? ? ? ? ?transition-timing-function: ease【缓出-缓进】
? ? ? ? ? ?transition-timing-function: ease-in【缓出】
? ? ? ? ? ?transition-timing-function: ease-out【缓进】
? ? ? ? ? ?transition-timing-function: ease-in-out【缓出-缓进,较ease更慢一些】
? ? ? ? ? ?transition-timing-function: cubic-bezier(n,n,n,n)【利用贝塞尔曲线自定义过渡速度】
transition-delay 过渡延迟
????????transition-timing-function 能使过渡效果延迟一段时间后发生,同 transition-duration ????????过渡时间一样,单位为 s(秒)或者ms(毫秒)
代码实现
<template>
<div class="home">
<el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
<el-radio-button :label="false">expand</el-radio-button>
<el-radio-button :label="true">collapse</el-radio-button>
</el-radio-group>
<el-container class="cont1">
<el-header class="header">Header</el-header>
<el-container class="cont2">
<el-aside :width="asideWidth" class="aside">
// 触发事件的元素标签
<p class="xianyin" @click="handleAsideClick">|||</p>
<el-menu active-text-color="#ffd04b" background-color="#545c64" class="el-menu" default-active="2"
text-color="#fff" @open="handleOpen" @close="handleClose" :collapse="isCollapse">
<el-sub-menu index="1">
<template #title>
<el-icon>
<location />
</el-icon>
<span>基础档案</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 index="1-3">item three</el-menu-item>
<el-sub-menu index="1-4">
<template #title>item four</template>
<el-menu-item index="1-4-1">仓库设置</el-menu-item>
</el-sub-menu>
</el-sub-menu>
<el-menu-item index="2">
<el-icon><icon-menu /></el-icon>
<span>采购管理</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<el-icon>
<document />
</el-icon>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<el-icon>
<setting />
</el-icon>
<span>Navigator Four</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main class="main"><RouterView/></el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import { ref, onMounted,nextTick } from 'vue'
import {RouterView} from 'vue-router'
import {
Document,
Menu as IconMenu,
Location,
Setting,
} from '@element-plus/icons-vue'
import router from '@/router';
// 状态的判断
const isCollapse = ref(localStorage.getItem('isCollapse') === 'true');
const asideWidth = ref(localStorage.getItem('asideWidth') || '200px');
// 使用了nextTick()函数来等待页面加载完成,然后再将asideWidth的值从本地缓存中获取并进行更新,在
// 页面加载完成之后,才会应用正确的侧边栏宽度,从而避免抖动的问题?
onMounted(async () => {
await nextTick(); // 等待页面加载完成
asideWidth.value = localStorage.getItem('asideWidth') || '200px';
});
const handleAsideClick = () => {
// 点击后状态取反
isCollapse.value = !isCollapse.value;
// 状态存入到本地存储中
localStorage.setItem('isCollapse', isCollapse.value.toString());
asideWidth.value = isCollapse.value ? '60px' : '200px';
// 宽度存入到本地存储中
localStorage.setItem('asideWidth', asideWidth.value);
};
// 官方的,没用到
const handleOpen = (key, keyPath) => {
console.log(key, keyPath)
}
const handleClose = (key, keyPath) => {
console.log(key, keyPath)
}
</script>
<style scoped lang="less">
.home {
height: 100%;
.cont1 {
height: 100%;
.header {
height: 50px;
background-color: aliceblue;
}
.cont2 {
height: 100%;
.aside {
height: 100%;
// 动画的实现
will-change: width;
transition: width 0.6s ease-in-out 0.1s;
overflow: hidden;
.xianyin{
width: 100%;
height: 20px;
text-align: center;
background-color: cadetblue;
}
.el-menu {
height: 100%;
}
}
.main {
height: 100%;
background-color: cornsilk;
margin: 15px;
}
}
}
}
</style>