样式定制:
.sidebar{
--sidebar-bg:#fff;
--sidebar-shadow:2px08pxrgba(0,0,0,0.15);
background:var(--sidebar-bg);
box-shadow:var(--sidebar-shadow);
}
通过这种设计,侧边栏组件将具备以下优势:
完整的响应式支持
灵活的动画配置
完善的移动端体验
良好的可访问性
支持插槽内容定制
与Vue3生态完美集成
📚代码测试
有个报错,调整下代码
📚整理后主要代码
📘定义组件 Sidebar.vue
import{ref,computed,watch,onMounted,onBeforeUnmount}from'vue'
constprops=defineProps({
position:{
type:String,
default:'left',
validator:v=>['left','right'].includes(v)
},
width:{
type:[String,Number],
default:'300px'
},
collapsible:{
type:Boolean,
default:true
},
defaultCollapsed:{
type:Boolean,
default:false
},
showOverlay:{
type:Boolean,
default:true
},
overlayOpacity:{
type:Number,
default:0.5
},
closeOnClickOutside:{
type:Boolean,
default:true
},
preventScroll:{
type:Boolean,
default:true
},
animationType:{
type:String,
default:'slide',
validator:v=>['slide','fade','none'].includes(v)
},
animationDuration:{
type:Number,
default:300
},
responsive:{
type:Boolean,
default:true
},
breakpoint:{
type:Number,
default:768
},
modelValue:{
type:Boolean,
required:true
}
})
constemit=defineEmits(['update:modelValue','open','close','toggle','overlay-click'])
//计算样式
constsidebarStyles=computed(()=>({
width:typeofprops.width==='number'?`${props.width}px`:props.width,
'--animation-duration':`${props.animationDuration}ms`
}))
constoverlayStyles=computed(()=>({
backgroundColor:`rgba(0,0,0,${props.overlayOpacity})`
}))
//处理遮罩点击
consthandleOverlayClick=()=>{
if(props.closeOnClickOutside){
emit('update:modelValue',false)
emit('overlay-click')
}
}
//响应式处理
onMounted(()=>{
if(props.responsive){
window.addEventListener('resize',handleResize)
}
if(props.preventScroll){
document.body.style.overflow=props.modelValue?'hidden':''
}
})
onBeforeUnmount(()=>{
if(props.responsive){
window.removeEventListener('resize',handleResize)
}
if(props.preventScroll){
document.body.style.overflow=''
}
})
consthandleResize=()=>{
if(window.innerWidthprops.modelValue,(val)=>{
if(props.preventScroll){
document.body.style.overflow=val?'hidden':''
}
emit(val?'open':'close')
})