前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕
目录
- DeepSeek 助力 Vue 开发:打造丝滑的侧边栏(Sidebar)
- 📚前言
- 📚进入安装好的DeepSeek
- 📚页面效果
- 📚指令输入
- 📚think
- 📘组件代码
- 📘调用示例
- 📘扩展建议
- 📚代码测试
- 📚整理后主要代码
- 📘定义组件 Sidebar.vue
- 📘调用 SidebarView.vue
- 📚其他代码
- 📘编写 \router\index.js
- 📘编写 App.vue
- 📚页面效果
- 📚自己部署 DeepSeek 安装地址
- 📚相关文章
📚📗📕📘📖🕮💡📝🗂️✍️🛠️💻🚀🎉🏗️🌐🖼️🔗📊👉🔖⚠️🌟🔐⬇️·正文开始
⬇️·🎥😊🎓📩😺🌈🤝🤖📜📋🔍✅🧰❓📄📢📈 🙋0️⃣1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣8️⃣9️⃣🔟🆗*️⃣#️⃣
DeepSeek 助力 Vue 开发:打造丝滑的侧边栏(Sidebar)
📚前言
在成本方面,DeepSeek 具有明显的优势。其训练成本和推理成本都远低于其他同类模型。例如,DeepSeek-V3 的训练成本仅为 557.6 万美元,而训练 GPT-4 这样的模型则需要数亿美元乃至数十亿美元 。在推理成本方面,DeepSeek 的 API 定价仅为每百万 tokens 输入 1 元、输出 2 元,价格仅为 GPT-4 Turbo 的百分之一 。如此低的成本,使得更多的企业和开发者能够使用 DeepSeek 的技术,降低了人工智能应用的门槛。
在功能方面,DeepSeek 不仅具备强大的自然语言处理能力,还在多模态处理、个性化推荐等方面具有独特的优势。在多模态处理方面,DeepSeek 支持文本、图像、语音等多种模态的数据融合和学习,能够实现更丰富和全面的理解和推理。在智能客服场景中,用户既可以通过文字与 DeepSeek 交流,也可以直接发送语音指令,甚至上传相关图片辅助说明问题,DeepSeek 都能准确理解用户需求,并提供相应的解决方案。在个性化推荐方面,DeepSeek 能根据用户行为和偏好,提供个性化内容推荐,提升用户满意度和参与度。
📚进入安装好的DeepSeek
0基础3步部署自己的DeepSeek安装步骤
打开搭建好的DeepSeek应用。
进入应用。
📚页面效果
📚指令输入
已经创建好了一个基于Vue3的组合式API的项目(Composition API),并能正常运行起来,请帮我用 Vue3的组合式API(Composition API) 生成一个 侧边栏(Sidebar) 的功能组件,所有代码都保存在components/Sidebar 下的文件夹中。功能组件的script标签中只有setup属性,使用普通 JavaScript 实现,不使用TypeScript。
功能要有,如下属性:
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
position | 侧边栏位置(left/right) | String | ‘left’ |
width | 侧边栏宽度(支持所有CSS单位) | String/Number | ‘300px’ |
collapsible | 是否可折叠 | Boolean | true |
defaultCollapsed | 默认是否折叠 | Boolean | false |
showOverlay | 是否显示遮罩层(移动端模式) | Boolean | true |
overlayOpacity | 遮罩层透明度(0-1) | Number | 0.5 |
closeOnClickOutside | 点击遮罩层/外部区域是否关闭 | Boolean | true |
preventScroll | 展开时是否禁止背景滚动 | Boolean | true |
animationType | 过渡动画类型(slide/fade/none) | String | ‘slide’ |
animationDuration | 动画持续时间(毫秒) | Number | 300 |
responsive | 是否启用响应式(自动在小屏幕折叠) | Boolean | true |
breakpoint | 响应式断点(小于该宽度自动折叠) | Number | 768 |
modelValue | 控制侧边栏展开状态(v-model绑定) | Boolean | - |
如下事件: |
事件名 | 说明 | 参数 |
---|---|---|
update:modelValue | 状态变化时触发(用于v-model) | 新状态(Boolean) |
open | 展开时触发 | - |
close | 折叠时触发 | - |
toggle | 切换状态时触发 | 新状态(Boolean) |
overlay-click | 点击遮罩层时触发 | - |
你有更好的建议也可以添加,要注明。组件定义好后给出2个及以上完整的调用示例。
下面是现有目录
vueAndDeepseek/
├── src/ # 源代码目录
│ ├── assets/ # 静态资源
│ │ ├── base.css
│ │ ├── main.css
│ │ └── logo.svg
│ ├── components/ # 组件目录
│ │ ├── HelloWorld.vue
│ │ ├── TheWelcome.vue
│ │ ├── WelcomeItem.vue
│ │ ├── Progress/
│ │ │ └── Progress.vue
│ │ ├── Accordion/
│ │ ├── BackToTop/
│ │ ├── Card/
│ │ ├── InfiniteScroll/
│ │ ├── Notification/
│ │ ├── Timeline/
│ │ ├── Switch/
│ │ ├── Tabs/
│ │ ├── Sidebar/
│ │ └── icons/
│ ├── router/ # 路由配置
│ │ └── index.js
│ ├── stores/ # Pinia 状态管理
│ │ └── counter.js
│ ├── views/ # 页面组件
│ │ ├── ProgressView.vue
│ │ ├── TabsView.vue
│ │ ├── SwitchView.vue
│ │ ├── TimelineView.vue
│ │ ├── NotificationView.vue
│ │ ├── CardView.vue
│ │ ├── InfiniteScrollView.vue
│ │ ├── BackToTopView.vue
│ │ ├── AccordionView.vue
│ │ ├── SidebarView.vue
│ │ └── AboutView.vue
│ ├── App.vue # 根组件
│ └── main.js # 应用入口
├── public/ # 公共资源目录
├── index.html # HTML 模板
├── package.json # 项目配置
├── vite.config.js # Vite 配置
└── node_modules/ # 依赖包目录
📚think
好的,我现在需要帮用户生成一个基于Vue3组合式API的侧边栏组件。用户已经提供了一个详细的属性和事件列表,并且要求将所有代码放在components/Sidebar文件夹下,使用普通JavaScript实现。
首先,我得分析用户的需求。他们需要一个功能全面的侧边栏,支持位置、宽度、折叠等功能,并且有各种事件和响应式设计。组件必须使用setup函数,所以我要考虑如何在组合式API中组织这些逻辑。
接下来,我会逐一处理每个属性。比如,position决定侧边栏的位置,left或right,这可以通过动态class来实现。width需要支持所有CSS单位,直接作为style的width应用即可。collapsible和defaultCollapsed会影响侧边栏是否可以折叠以及默认状态,这里可能需要用一个内部的状态变量来管理展开/折叠的状态。
然后是遮罩层部分,showOverlay控制遮罩层的显示与否。当组件在移动端模式下,点击遮罩层或外部区域会关闭侧边栏,这需要监听click事件,并根据条件决定是否关闭。同时,closeOnClickOutside和preventScroll属性也需要处理,可能需要添加事件监听器到document上。
动画部分,animationType和animationDuration决定了过渡效果。使用Vue的TransitionGroup或者自定义过渡类来实现滑动或渐变效果。这里可能需要动态切换class,根据当前状态应用不同的动画样式。
响应式设计方面,当屏幕宽度小于breakpoint时自动折叠。这需要用到useResizeObserver来监听页面大小变化,并在resize事件中调整侧边栏的状态。
关于modelValue和v-model的支持,我需要使用computed属性来处理双向绑定,同时在组件内部触发update:模型值事件。当用户手动打开或关闭侧边栏时,会派发这个事件更新父组件的状态。
事件部分,有open、close、toggle、overlay-click等事件,这些都需要通过emit函数来派发。例如,在点击遮罩层的时候,派发overlay-click事件,并在回调中处理关闭逻辑。
现在考虑内部状态管理,我会用ref定义isCollapsed和isOpen两个变量。isCollapsed表示当前是否折叠,isOpen可能用于控制显示隐藏的动画过渡。当组件挂载时,根据defaultCollapsed设置初始状态。
接下来是方法部分,toggleSidebar用来切换展开/折叠状态,并派发相应的事件。handleOverlayClick则处理点击遮罩层的情况,只有在closeOnClickOutside为true时才会关闭侧边栏。
然后是响应式处理,监听页面的resize事件,当宽度小于breakpoint时,自动折叠侧边栏。这可能需要使用useResizeObserver或直接监听window.resize事件,并根据当前状态和断点调整isCollapsed的值。
样式方面,我会动态绑定class,根据position决定left还是right,以及是否显示隐藏。width属性通过style对象应用到侧边栏容器上。遮罩层的透明度由overlayOpacity控制,添加对应的背景颜色。
最后是写示例组件,展示如何在父组件中使用这个侧边栏。例如,绑定modelValue、设置不同的位置和宽度,以及监听各种事件来响应状态变化。
在整个过程中,我需要确保代码结构清晰,逻辑正确,并且覆盖所有用户提供的属性和事件。同时,考虑到性能优化,避免不必要的计算或重复渲染。最后,测试组件在不同情况下的表现,比如移动端和桌面端的显示效果,动画是否流畅,点击外部区域是否正确关闭等。
📘组件代码
根据组件设计经验和最佳实践,以下是侧边栏组件的开发建议和完整方案:
src/components/Sidebar/Sidebar.vue
<template>
<transition :name="transitionName" :duration="animationDuration">
<div
v-show="isOpen"
class="sidebar"
:class="[positionClass, { collapsible }]"
:style="sidebarStyles"
>
<!-- 头部插槽 -->
<div v-if="$slots.header" class="sidebar-header">
<slot name="header"></slot>
</div>
<!-- 内容区域 -->
<div class="sidebar-body">
<slot></slot>
</div>
<!-- 底部插槽 -->
<div v-if="$slots.footer" class="sidebar-footer">
<slot name="footer"></slot>
</div>
</div>
</transition>
<!-- 遮罩层 -->
<transition name="fade" :duration="animationDuration">
<div
v-if="showOverlay && isOpen"
class="sidebar-overlay"
:style="overlayStyles"
@click="handleOverlayClick"
></div>
</transition>
</template>
<script setup>
import { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue'
const props = defineProps({
position: {
type: String,
default: 'left',
validator: v => ['left', 'right'].includes(v)
},
width: {
type: [String, Number],
default: '300px'
},
collapsible: Boolean,
defaultCollapsed: Boolean,
showOverlay: Boolean,
overlayOpacity: {
type: Number,
default: 0.5
},
closeOnClickOutside: Boolean,
preventScroll: Boolean,
animationType: {
type: String,
default: 'slide',
validator: v => ['slide', 'fade', 'none'].includes(v)
},
animationDuration: {
type: Number,
default: 300
},
responsive: Boolean,
breakpoint: {
type: Number,
default: 768
},
modelValue: Boolean
})
const emit = defineEmits([
'update:modelValue',
'open',
'close',
'toggle',
'overlay-click'
])
// 响应式状态
const isOpen = ref(!props.defaultCollapsed)
const windowWidth = ref(window.innerWidth)
// 计算属性
const positionClass = computed(() => `position-${props.position}`)
const transitionName = computed(() => props.animationType === 'slide' ? `slide-${props.position}` : props.animationType)
const sidebarStyles = computed(() => ({
width: typeof props.width === 'number' ? `${props.width}px` : props.width
}))
const overlayStyles = computed(() => ({
opacity: props.overlayOpacity,
backgroundColor: `rgba(0,0,0,${props.overlayOpacity})`
}))
// 方法
const toggle = (state) => {
const newState = typeof state === 'boolean' ? state : !isOpen.value
isOpen.value = newState
emit('update:modelValue', newState)
emit('toggle', newState)
newState ? emit('open') : emit('close')
// 处理滚动锁定
if (props.preventScroll) {
document.body.style.overflow = newState ? 'hidden' : ''
}
}
const handleOverlayClick = () => {
emit('overlay-click')
if (props.closeOnClickOutside) toggle(false)
}
// 响应式处理
const checkResponsive = () => {
if (props.responsive && windowWidth.value <= props.breakpoint) {
toggle(false)
}
}
// 生命周期
onMounted(() => {
window.addEventListener('resize', () => {
windowWidth.value = window.innerWidth
checkResponsive()
})
})
onBeforeUnmount(() => {
window.removeEventListener('resize')
document.body.style.overflow = '' // 清理滚动锁定
})
// 监听props变化
watch(() => props.modelValue, (val) => {
isOpen.value = val
})
watch(windowWidth, checkResponsive)
</script>
<style scoped>
.sidebar {
position: fixed;
top: 0;
height: 100vh;
background: #ffffff;
box-shadow: 2px 0 8px rgba(0,0,0,0.15);
z-index: 1000;
transition: transform 0.3s ease;
}
.position-left {
left: 0;
transform: translateX(-100%);
}
.position-right {
right: 0;
transform: translateX(100%);
}
.slide-left-enter-active,
.slide-left-leave-active {
transition: transform v-bind('animationDuration + "ms"') ease;
}
.slide-left-enter-to,
.slide-left-leave-from {
transform: translateX(0);
}
.slide-right-enter-active,
.slide-right-leave-active {
transition: transform v-bind('animationDuration + "ms"') ease;
}
.slide-right-enter-to,
.slide-right-leave-from {
transform: translateX(0);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity v-bind('animationDuration + "ms"') ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.sidebar-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
z-index: 999;
}
.sidebar-header {
padding: 16px;
border-bottom: 1px solid #f0f0f0;
}
.sidebar-body {
padding: 16px;
height: calc(100vh - 120px);
overflow-y: auto;
}
.sidebar-footer {
position: absolute;
bottom: 0;
width: 100%;
padding: 16px;
border-top: 1px solid #f0f0f0;
}
</style>
📘调用示例
<template>
<!-- 基本用法 -->
<Sidebar v-model="isOpen1">
<template #header>
<h3>导航菜单</h3>
</template>
<!-- 内容 -->
</Sidebar>
<!-- 响应式侧边栏 -->
<Sidebar
v-model="isOpen2"
position="right"
width="350px"
:responsive="true"
:breakpoint="1024"
>
<template #footer>
<button @click="isOpen2 = false">关闭</button>
</template>
</Sidebar>
<!-- 自定义动画 -->
<Sidebar
v-model="isOpen3"
animation-type="fade"
:animation-duration="500"
:show-overlay="false"
/>
</template>
<script setup>
import { ref } from 'vue'
import Sidebar from '@/components/Sidebar/Sidebar.vue'
const isOpen1 = ref(true)
const isOpen2 = ref(false)
const isOpen3 = ref(false)
</script>
📘扩展建议
-
键盘导航支持:
- 添加ESC键关闭支持
const handleKeydown = (e) => { if (e.key === 'Escape' && isOpen.value) toggle(false) }
-
手势支持(移动端):
let touchStartX = 0 const onTouchStart = (e) => { touchStartX = e.touches[0].clientX } const onTouchEnd = (e) => { const deltaX = e.changedTouches[0].clientX - touchStartX if (Math.abs(deltaX) > 50) toggle(deltaX > 0) }
-
可访问性增强:
<div role="navigation" aria-label="主侧边栏" :aria-expanded="isOpen" >
-
样式定制:
.sidebar { --sidebar-bg: #fff; --sidebar-shadow: 2px 0 8px rgba(0,0,0,0.15); background: var(--sidebar-bg); box-shadow: var(--sidebar-shadow); }
通过这种设计,侧边栏组件将具备以下优势:
- 完整的响应式支持
- 灵活的动画配置
- 完善的移动端体验
- 良好的可访问性
- 支持插槽内容定制
- 与Vue3生态完美集成
📚代码测试
有个报错,调整下代码
📚整理后主要代码
📘定义组件 Sidebar.vue
<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
const props = 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
}
})
const emit = defineEmits(['update:modelValue', 'open', 'close', 'toggle', 'overlay-click'])
// 计算样式
const sidebarStyles = computed(() => ({
width: typeof props.width === 'number' ? `${props.width}px` : props.width,
'--animation-duration': `${props.animationDuration}ms`
}))
const overlayStyles = computed(() => ({
backgroundColor: `rgba(0, 0, 0, ${props.overlayOpacity})`
}))
// 处理遮罩点击
const handleOverlayClick = () => {
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 = ''
}
})
const handleResize = () => {
if (window.innerWidth < props.breakpoint && props.modelValue) {
emit('update:modelValue', false)
}
}
// 监听状态变化
watch(() => props.modelValue, (val) => {
if (props.preventScroll) {
document.body.style.overflow = val ? 'hidden' : ''
}
emit(val ? 'open' : 'close')
})
</script>
<template>
<transition :name="animationType" :duration="animationDuration">
<div v-show="modelValue" class="sidebar-container">
<div
class="sidebar"
:class="[`sidebar-${position}`, { collapsible }]"
:style="sidebarStyles"
>
<slot name="header"></slot>
<div class="sidebar-content">
<slot></slot>
</div>
<slot name="footer"></slot>
</div>
<div
v-if="showOverlay"
class="sidebar-overlay"
:style="overlayStyles"
@click="handleOverlayClick"
></div>
</div>
</transition>
</template>
<style scoped>
.sidebar-container {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
}
.sidebar {
position: fixed;
top: 0;
bottom: 0;
background: #fff;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
z-index: 1001;
}
.sidebar-left { left: 0; }
.sidebar-right { right: 0; }
.sidebar-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1000;
}
.slide-enter-active,
.slide-leave-active {
transition: transform var(--animation-duration) ease;
}
.slide-enter-from.sidebar-left,
.slide-leave-to.sidebar-left {
transform: translateX(-100%);
}
.slide-enter-from.sidebar-right,
.slide-leave-to.sidebar-right {
transform: translateX(100%);
}
.fade-enter-active,
.fade-leave-active {
transition: opacity var(--animation-duration) ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
</style>
📘调用 SidebarView.vue
<script setup>
import { ref } from 'vue'
import Sidebar from '../components/Sidebar/Sidebar.vue'
// 基础示例状态
const isBasicOpen = ref(false)
// 响应式示例状态
const isResponsiveOpen = ref(false)
// 自定义主题示例状态
const isCustomOpen = ref(false)
// 处理菜单点击
const handleMenuClick = () => {
console.log('Menu item clicked')
}
</script>
<template>
<div class="sidebar-demo">
<!-- 基础示例 -->
<section class="demo-section">
<h3>基础示例</h3>
<button @click="isBasicOpen = true">打开左侧边栏</button>
<Sidebar v-model="isBasicOpen">
<template #header>
<h3>基础侧边栏</h3>
</template>
<div class="menu-items">
<div class="menu-item" @click="handleMenuClick">菜单项 1</div>
<div class="menu-item" @click="handleMenuClick">菜单项 2</div>
<div class="menu-item" @click="handleMenuClick">菜单项 3</div>
</div>
</Sidebar>
</section>
<!-- 响应式示例 -->
<section class="demo-section">
<h3>响应式示例</h3>
<button @click="isResponsiveOpen = true">打开右侧边栏</button>
<Sidebar
v-model="isResponsiveOpen"
position="right"
:responsive="true"
:breakpoint="768"
animationType="fade"
>
<template #header>
<h3>响应式侧边栏</h3>
</template>
<div class="responsive-content">
<p>在小屏幕下自动折叠</p>
<button @click="isResponsiveOpen = false">关闭</button>
</div>
</Sidebar>
</section>
<!-- 自定义主题示例 -->
<section class="demo-section">
<h3>自定义主题示例</h3>
<button @click="isCustomOpen = true">打开自定义侧边栏</button>
<Sidebar
v-model="isCustomOpen"
width="400px"
:overlay-opacity="0.7"
:animation-duration="500"
>
<template #header>
<div class="custom-header">
<h3>自定义主题</h3>
<button @click="isCustomOpen = false">×</button>
</div>
</template>
<div class="custom-content">
<p>自定义宽度和动画效果</p>
<div class="custom-menu">
<div class="custom-menu-item">设置</div>
<div class="custom-menu-item">个人信息</div>
<div class="custom-menu-item">退出</div>
</div>
</div>
</Sidebar>
</section>
</div>
</template>
<style scoped>
.sidebar-demo {
padding: 20px;
}
.demo-section {
margin-bottom: 30px;
}
button {
padding: 8px 16px;
margin: 10px 0;
border: none;
border-radius: 4px;
background: #409EFF;
color: white;
cursor: pointer;
}
.menu-items {
padding: 10px;
}
.menu-item {
padding: 10px;
cursor: pointer;
}
.menu-item:hover {
background: #f5f7fa;
}
.custom-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #eee;
}
.custom-content {
padding: 20px;
}
.custom-menu-item {
padding: 12px;
margin: 8px 0;
background: #f5f7fa;
border-radius: 4px;
cursor: pointer;
}
.custom-menu-item:hover {
background: #e4e7ed;
}
</style>
📚其他代码
📘编写 \router\index.js
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'progress',
component: () => import('../views/ProgressView.vue'),
},
{
path: '/tabs',
name: 'tabs',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
// 标签页(Tabs)
component: () => import('../views/TabsView.vue'),
},
{
path: '/accordion',
name: 'accordion',
// 折叠面板(Accordion)
component: () => import('../views/AccordionView.vue'),
},
{
path: '/timeline',
name: 'timeline',
// 时间线(Timeline)
component: () => import('../views/TimelineView.vue'),
},
{
path: '/backToTop',
name: 'backToTop',
component: () => import('../views/BackToTopView.vue')
},
{
path: '/notification',
name: 'notification',
component: () => import('../views/NotificationView.vue')
},
{
path: '/card',
name: 'card',
component: () => import('../views/CardView.vue')
},
{
path: '/infiniteScroll',
name: 'infiniteScroll',
component: () => import('../views/InfiniteScrollView.vue')
},
{
path: '/switch',
name: 'switch',
component: () => import('../views/SwitchView.vue')
},
{
path: '/sidebar',
name: 'sidebar',
component: () => import('../views/SidebarView.vue')
}
],
})
export default router
📘编写 App.vue
<script setup>
import { ref } from 'vue'
import Sidebar from '../components/Sidebar/Sidebar.vue'
// 基础示例状态
const isBasicOpen = ref(false)
// 响应式示例状态
const isResponsiveOpen = ref(false)
// 自定义主题示例状态
const isCustomOpen = ref(false)
// 处理菜单点击
const handleMenuClick = () => {
console.log('Menu item clicked')
}
</script>
<template>
<div class="sidebar-demo">
<!-- 基础示例 -->
<section class="demo-section">
<h3>基础示例</h3>
<button @click="isBasicOpen = true">打开左侧边栏</button>
<Sidebar v-model="isBasicOpen">
<template #header>
<h3>基础侧边栏</h3>
</template>
<div class="menu-items">
<div class="menu-item" @click="handleMenuClick">菜单项 1</div>
<div class="menu-item" @click="handleMenuClick">菜单项 2</div>
<div class="menu-item" @click="handleMenuClick">菜单项 3</div>
</div>
</Sidebar>
</section>
<!-- 响应式示例 -->
<section class="demo-section">
<h3>响应式示例</h3>
<button @click="isResponsiveOpen = true">打开右侧边栏</button>
<Sidebar
v-model="isResponsiveOpen"
position="right"
:responsive="true"
:breakpoint="768"
animationType="fade"
>
<template #header>
<h3>响应式侧边栏</h3>
</template>
<div class="responsive-content">
<p>在小屏幕下自动折叠</p>
<button @click="isResponsiveOpen = false">关闭</button>
</div>
</Sidebar>
</section>
<!-- 自定义主题示例 -->
<section class="demo-section">
<h3>自定义主题示例</h3>
<button @click="isCustomOpen = true">打开自定义侧边栏</button>
<Sidebar
v-model="isCustomOpen"
width="400px"
:overlay-opacity="0.7"
:animation-duration="500"
>
<template #header>
<div class="custom-header">
<h3>自定义主题</h3>
<button @click="isCustomOpen = false">×</button>
</div>
</template>
<div class="custom-content">
<p>自定义宽度和动画效果</p>
<div class="custom-menu">
<div class="custom-menu-item">设置</div>
<div class="custom-menu-item">个人信息</div>
<div class="custom-menu-item">退出</div>
</div>
</div>
</Sidebar>
</section>
</div>
</template>
<style scoped>
.sidebar-demo {
padding: 20px;
}
.demo-section {
margin-bottom: 30px;
}
button {
padding: 8px 16px;
margin: 10px 0;
border: none;
border-radius: 4px;
background: #409EFF;
color: white;
cursor: pointer;
}
.menu-items {
padding: 10px;
}
.menu-item {
padding: 10px;
cursor: pointer;
}
.menu-item:hover {
background: #f5f7fa;
}
.custom-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16px;
border-bottom: 1px solid #eee;
}
.custom-content {
padding: 20px;
}
.custom-menu-item {
padding: 12px;
margin: 8px 0;
background: #f5f7fa;
border-radius: 4px;
cursor: pointer;
}
.custom-menu-item:hover {
background: #e4e7ed;
}
</style>
📚页面效果
📚自己部署 DeepSeek 安装地址
蓝耘元生代智算云平台地址:https://cloud.lanyun.net/#/registerPage?promoterCode=07100c37a0
📚相关文章
-
0基础3步部署自己的DeepSeek安装步骤
-
DeepSeek 助力 Vue 开发:打造丝滑的步骤条
-
DeepSeek 助力 Vue 开发:打造丝滑的进度条(Progress Bar)
-
自己部署 DeepSeek 助力 Vue 开发:打造丝滑的标签页(Tabs)
-
自己部署 DeepSeek 助力 Vue 开发:打造丝滑的折叠面板(Accordion)
-
自己部署 DeepSeek 助力 Vue 开发:打造丝滑的时间线(Timeline )
-
DeepSeek 助力 Vue 开发:打造丝滑的返回顶部按钮(Back to Top)
-
DeepSeek 助力 Vue 开发:打造丝滑的通知栏(Notification Bar)
-
DeepSeek 助力 Vue 开发:打造丝滑的卡片(Card)
-
DeepSeek 助力 Vue 开发:打造丝滑的无限滚动(Infinite Scroll)
-
DeepSeek 助力 Vue 开发:打造丝滑的开关切换(Switch)
到此这篇文章就介绍到这了,更多精彩内容请关注本人以前的文章或继续浏览下面的文章,创作不易,如果能帮助到大家,希望大家多多支持宝码香车~💕,若转载本文,一定注明本文链接。
更多专栏订阅推荐:
👍 html+css+js 绚丽效果
💕 vue
✈️ Electron
⭐️ js
📝 字符串
✍️ 时间对象(Date())操作