DeepSeek 助力 Vue 开发:打造丝滑的侧边栏(Sidebar)

发布于:2025-02-16 ⋅ 阅读:(67) ⋅ 点赞:(0)

前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦 💕

共同探索软件研发!敬请关注【宝码香车】
关注描述

csdngif标识


📚📗📕📘📖🕮💡📝🗂️✍️🛠️💻🚀🎉🏗️🌐🖼️🔗📊👉🔖⚠️🌟🔐⬇️·正文开始⬇️·🎥😊🎓📩😺🌈🤝🤖📜📋🔍✅🧰❓📄📢📈 🙋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应用。

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>

📘扩展建议

  1. 键盘导航支持

    • 添加ESC键关闭支持
    const handleKeydown = (e) => {
      if (e.key === 'Escape' && isOpen.value) toggle(false)
    }
    
  2. 手势支持(移动端):

    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)
    }
    
  3. 可访问性增强

    <div 
      role="navigation"
      aria-label="主侧边栏"
      :aria-expanded="isOpen"
    >
    
  4. 样式定制

    .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

📚相关文章

 

———— 相 关 文 章 ————

 

  1. 0基础3步部署自己的DeepSeek安装步骤

  2. DeepSeek 助力 Vue 开发:打造丝滑的步骤条

  3. DeepSeek 助力 Vue 开发:打造丝滑的进度条(Progress Bar)

  4. 自己部署 DeepSeek 助力 Vue 开发:打造丝滑的标签页(Tabs)

  5. 自己部署 DeepSeek 助力 Vue 开发:打造丝滑的折叠面板(Accordion)

  6. 自己部署 DeepSeek 助力 Vue 开发:打造丝滑的时间线(Timeline )

  7. DeepSeek 助力 Vue 开发:打造丝滑的返回顶部按钮(Back to Top)

  8. DeepSeek 助力 Vue 开发:打造丝滑的通知栏(Notification Bar)

  9. DeepSeek 助力 Vue 开发:打造丝滑的卡片(Card)

  10. DeepSeek 助力 Vue 开发:打造丝滑的无限滚动(Infinite Scroll)

  11. DeepSeek 助力 Vue 开发:打造丝滑的开关切换(Switch)

到此这篇文章就介绍到这了,更多精彩内容请关注本人以前的文章或继续浏览下面的文章,创作不易,如果能帮助到大家,希望大家多多支持宝码香车~💕,若转载本文,一定注明本文链接。


整理不易,点赞关注宝码香车

更多专栏订阅推荐:
👍 html+css+js 绚丽效果
💕 vue
✈️ Electron
⭐️ js
📝 字符串
✍️ 时间对象(Date())操作


网站公告

今日签到

点亮在社区的每一天
去签到