最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3實(shí)現(xiàn)折疊面板組件的示例代碼

 更新時(shí)間:2024年01月08日 15:25:54   作者:前端老K  
折疊面板大家都不陌生,很多時(shí)候需要實(shí)現(xiàn)一些復(fù)雜的交互,就會(huì)用到它,簡潔直觀還美觀,下面就跟隨小編一起學(xué)習(xí)一下如果使用Vue3實(shí)現(xiàn)折疊面板組件吧

背景

折疊面板大家都不陌生,很多時(shí)候需要實(shí)現(xiàn)一些復(fù)雜的交互,就會(huì)用到它,簡潔直觀還美觀,通常我們直接用第三方組件庫就行了,不過只會(huì)用還不行,還要會(huì)寫才行,下面我們一起手寫一個(gè)折疊面板組件。

最終效果

實(shí)現(xiàn)功能

  • 手風(fēng)琴模式
  • 自定義標(biāo)題
  • 自定義內(nèi)容
  • 數(shù)據(jù)綁定,支持string | array

實(shí)現(xiàn)邏輯

首先創(chuàng)建組件目錄,如下:

index.vue 實(shí)現(xiàn)代碼:

<template>
  <div class="collapse-panel">
    <slot></slot>
  </div>
</template>

<script setup lang="ts">
import { useSlots, ref, onMounted, provide } from 'vue'

const slots = useSlots()
const props = defineProps({
  modelValue: {
    type: [String, Array, Number]
  }, // 數(shù)據(jù)綁定
  accordion: {
    type: Boolean
  } // 是否開啟手風(fēng)琴模式,默認(rèn)不開啟
})
const emits = defineEmits(['update:modelValue', 'change'])

const activeNames = ref([])

onMounted(() => {
  setValueLists()
})

// 初始化設(shè)置激活項(xiàng)
const setValueLists = () => {
  if (!Array.isArray(props.modelValue)) {
    activeNames['value'] = [props.modelValue]
  } else {
    activeNames['value'] = props.modelValue
  }
}
// 點(diǎn)擊每項(xiàng)處理函數(shù)
const toggle = (name) => {
  if (activeNames['value'].includes(name)) {
    // 收起時(shí) 
    activeNames['value'] = activeNames['value'].filter((item) => item != name)
  } else {
    // 展開時(shí)
    if (props.accordion) {
      activeNames['value'] = [name]
    } else {
      activeNames['value'].push(name)
    }
  }
  emits('update:modelValue', activeNames['value'])
  emits('change', activeNames['value'])
}

// 提供父組件指定方法
provide('toggle', toggle)
provide('activeNames', activeNames)
</script>

<style lang="less" scoped></style>

CollapseItem.vue 實(shí)現(xiàn)代碼

<template>
  <div class="collapse-item">
    <div class="collapse-head">
      <el-icon class="caret-down"
               :class="{ 'caret-open': isCollapse }"
               @click.stop="handlePanelItemClick">
        <CaretRight />
      </el-icon>
      <div class="collapse-head-right">
        <span v-if="!slots.title"
              class="collapse-title">{{ attrs.title }}</span>
        <slot name="title"></slot>
      </div>
    </div>
    <CollapseTransition>
      <div v-show="isCollapse"
           class="collapse-content">
        <slot name="content"></slot>
      </div>
    </CollapseTransition>
  </div>
</template>

<script setup lang="ts">
import { ref, useSlots, useAttrs, inject, computed } from 'vue'
import CollapseTransition from './CollapseTransition.vue'
const slots = useSlots()
const attrs = useAttrs()
const activeNames = inject('activeNames')
const handleToggle = inject('toggle')

const status = ref(false) // 開展?fàn)顟B(tài)

const isCollapse = computed(() => {
  return activeNames['value'].includes(attrs.name)
})

const handlePanelItemClick = () => {
  handleToggle(attrs.name)
}
</script>

<style scoped lang="less">
.collapse-item {
  display: flex;
  flex-flow: column;
  .collapse-head {
    display: flex;
    flex-flow: row nowrap;
    align-items: center;
    height: 42px;
    background: #d9d9d9;
    padding: 0 14px;
    border: 1px solid #cccccc;
    border-bottom: none;
    border-radius: 4px 4px 0px 0px;
    overflow: hidden;
    .caret-down {
      font-size: 20px;
      color: #1b1b1b;
      margin-right: 6px;
      cursor: pointer;
      transition: transform 0.3s;
      transform-origin: center center;
      &.caret-open {
        transform: rotate(90deg);
      }
    }
    .collapse-head-right {
      flex: 1;
      width: 0;
      .collapse-title {
        font-size: 14px;
        color: #1b1b1b;
      }
    }
  }
  .collapse-content {
  }
}
</style>

CollapseTransition.vue 展開收起動(dòng)畫組件

<template>
  <transition @before-enter="beforeEnter"
              @enter="enter"
              @leave="leave"
              @after-leave="afterLeave">
    <slot></slot>
  </transition>
</template>

<script setup lang="ts">
const beforeEnter = (el) => {
  el.classList.add('collapse-transition')
  el.dataset.oldPaddingTop = el.style.paddingTop
  el.dataset.oldPaddingBottom = el.style.paddingBottom
  el.dataset.oldOverflow = el.style.overflow
  el.style.overflow = 'hidden'
  el.style.height = '0'
  el.style.paddingTop = 0
  el.style.paddingBottom = 0
}
const enter = (el) => {
  el.style.height = el.scrollHeight + 'px'
  el.style.paddingTop = el.dataset.oldPaddingTop
  el.style.paddingBottom = el.dataset.oldPaddingBottom
}

const afterEnter = (el) => {
  el.classList.remove('collapse-transition')
  el.style.height = ''
  el.style.overflow = el.dataset.oldOverflow
}

const beforeLeave = (el) => {
  el.dataset.oldPaddingTop = el.style.paddingTop
  el.dataset.oldPaddingBottom = el.style.paddingBottom
  el.dataset.oldOverflow = el.style.overflow
  el.style.height = el.scrollHeight + 'px'
  el.style.overflow = 'hidden'
}

const leave = (el) => {
  el.classList.add('collapse-transition')
  el.style.height = 0
  el.style.paddingTop = 0
  el.style.paddingBottom = 0
}

const afterLeave = (el) => {
  el.classList.remove('collapse-transition')
  el.style.height = ''
  el.style.overflow = el.dataset.oldOverflow
  el.style.paddingTop = el.dataset.oldPaddingTop
  el.style.paddingBottom = el.dataset.oldPaddingBottom
}
</script>

<style scoped lang="less">
.collapse-transition {
  transition: all 0.3s ease-in-out;
}
</style>

組件的使用

// template
<CollapsePanel v-model="activeName" @change="change" :accordion="accordion">
  <collapse-item :name="1">
    <template #title>
      <!-- 自定義title -->
    </template>
    <template #content>
      <!-- 自定義內(nèi)容 -->
    </template>
  </collapse-item>
  
  <collapse-item :name="2">
    <template #title>
      <!-- 自定義title -->
    </template>
    <template #content>
      <!-- 自定義內(nèi)容 -->
    </template>
  </collapse-item>
</CollapsePanel>

//script
const activeName = ref([2])
const accordion ref(true) // 是否開啟手風(fēng)琴模式

// 點(diǎn)擊觸發(fā)
const change = (value) => {
    console.log(value)
}

以上就是Vue3實(shí)現(xiàn)折疊面板組件的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Vue3折疊面板組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Sass功能特性、常用方法與最佳實(shí)踐(最新整理)

    Sass功能特性、常用方法與最佳實(shí)踐(最新整理)

    Sass作為一種CSS預(yù)處理器,已經(jīng)從最初的簡單擴(kuò)展發(fā)展成為功能豐富的樣式編程語言,本文給大家介紹Sass功能特性、常用方法與最佳實(shí)踐,感興趣的朋友一起看看吧
    2025-07-07
  • Vue+Element-UI中el-table動(dòng)態(tài)合并單元格:span-method方法代碼詳解

    Vue+Element-UI中el-table動(dòng)態(tài)合并單元格:span-method方法代碼詳解

    el-table是element-ui提供的表格組件,可以用于展示和操作數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于Vue+Element-UI中el-table動(dòng)態(tài)合并單元格:span-method方法的相關(guān)資料,需要的朋友可以參考下
    2023-09-09
  • vue導(dǎo)出excel文件流中文亂碼問題及解決

    vue導(dǎo)出excel文件流中文亂碼問題及解決

    這篇文章主要介紹了vue導(dǎo)出excel文件流中文亂碼問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue在.js文件中引入store和router問題

    vue在.js文件中引入store和router問題

    這篇文章主要介紹了vue在.js文件中引入store和router問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 淺入深出Vue之自動(dòng)化路由

    淺入深出Vue之自動(dòng)化路由

    這篇文章主要介紹了淺入深出Vue之自動(dòng)化路由,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 利用Vue實(shí)現(xiàn)將圖片轉(zhuǎn)換為Base64編碼的方法

    利用Vue實(shí)現(xiàn)將圖片轉(zhuǎn)換為Base64編碼的方法

    這篇文章主要介紹了利用Vue實(shí)現(xiàn)將圖片轉(zhuǎn)換為Base64編碼的方法,Base64是一種編碼方式,用于將二進(jìn)制數(shù)據(jù)轉(zhuǎn)換成64個(gè)基于ASCII的可打印字符,這種編碼可嵌入圖像到HTML或CSS中,減少加載時(shí)間,解決跨域問題,并支持離線應(yīng)用開發(fā),需要的朋友可以參考下
    2024-10-10
  • vue基于better-scroll仿京東分類列表

    vue基于better-scroll仿京東分類列表

    這篇文章主要為大家詳細(xì)介紹了vue基于better-scroll仿京東分類列表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • uniapp定義new plus.nativeObj.View實(shí)現(xiàn)APP端全局彈窗功能

    uniapp定義new plus.nativeObj.View實(shí)現(xiàn)APP端全局彈窗功能

    文章介紹了在UniApp中使用`newplus.nativeObj.View`實(shí)現(xiàn)彈窗的原因和方法,它定義了一個(gè)`AppPopupView`彈窗函數(shù),并在`main.js`中掛載到全局頁面,以便在任何地方調(diào)用,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • Vue router重定向redirect如何傳值問題

    Vue router重定向redirect如何傳值問題

    這篇文章主要介紹了Vue router重定向redirect如何傳值問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • bootstrap vue.js實(shí)現(xiàn)tab效果

    bootstrap vue.js實(shí)現(xiàn)tab效果

    這篇文章主要為大家詳細(xì)介紹了bootstrap vue.js實(shí)現(xiàn)tab效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02

最新評論

芦溪县| 稻城县| 海安县| 佛冈县| 鄂伦春自治旗| 汶川县| 乌鲁木齐县| 湛江市| 贵溪市| 邵阳市| 治县。| 南和县| 资源县| 丽江市| 鸡东县| 成安县| 贡觉县| 东乡族自治县| 缙云县| 班玛县| 镇康县| 常熟市| 会宁县| 太谷县| 清丰县| 英德市| 简阳市| 马山县| 磐石市| 砀山县| 舞钢市| 都匀市| 会东县| 本溪市| 思茅市| 皮山县| 托克逊县| 兴宁市| 桂平市| 廊坊市| 大埔县|