如何搭建一個(gè)個(gè)人網(wǎng)站學(xué)校招生網(wǎng)絡(luò)營銷方案
組件效果圖
- 未達(dá)到最大高度
- 達(dá)到設(shè)置的最大高度
- 進(jìn)行展開
實(shí)現(xiàn)代碼
- 組件代碼
備注:通過
tailwindcss
設(shè)置的樣式,通過@element-plus/icons-vue
設(shè)置的圖標(biāo),可根據(jù)情況進(jìn)行替換
<template><!-- 限制高度組件 --><div ref="restrictionBox" class="relative overflow-hidden bg-blue-300" :class="control.isUnfold ? '' : max"><div ref="restrictionChil"><slot></slot></div><!-- 漸變 --><div v-if="control.isExceed && !control.isUnfold" class="absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-white"></div></div><!-- 控制按鈕 --><div v-if="control.isExceed"><div class="flex h-12 cursor-pointer select-none items-center justify-center space-x-1 pb-2 text-blue-500 active:text-blue-400" @click="changeUnfold"><span class="text-sm">{{ control.isUnfold ? '收起' : '展開' }}</span><el-icon><ArrowUp v-if="control.isUnfold" /><ArrowDown v-else /></el-icon></div></div>
</template><script setup>
import { ref, reactive, onMounted, onUnmounted } from 'vue'
import { ArrowUp, ArrowDown } from '@element-plus/icons-vue'// 接收參數(shù)
const props = defineProps({// 最大高度 - 收起前max: {type: String,default: 'max-h-48'}
})// 組件控制參數(shù)
const control = reactive({boxHeight: 0,chilHeight: 0,isExceed: false, // 是否超出高度isUnfold: false // 是否展開
})// 改變展開方式
const changeUnfold = () => (control.isUnfold = !control.isUnfold)// 獲取元素
const restrictionBox = ref(null)
const restrictionChil = ref(null)// 創(chuàng)建高度監(jiān)聽 及監(jiān)聽銷毀
let observerBox = null
let observerChil = null// 銷毀監(jiān)聽
const destroyedObserver = () => {if (observerBox) {observerBox.disconnect()observerBox = null}if (observerChil) {observerChil.disconnect()observerChil = null}
}// 比較高度的函數(shù)
const compareHeights = () => {if (control.boxHeight > 0 && control.chilHeight > 0) {// 高度超出,出現(xiàn)下拉if (control.chilHeight > control.boxHeight) {destroyedObserver()console.log('超出高度')control.isExceed = true}}
}// 頁面加載完成
onMounted(() => {// 父級(jí)監(jiān)聽observerBox = new ResizeObserver(entries => {entries.forEach(entry => {control.boxHeight = entry.contentRect.heightcompareHeights()})})// 內(nèi)容監(jiān)聽observerChil = new ResizeObserver(entries => {entries.forEach(entry => {control.chilHeight = entry.contentRect.heightcompareHeights()})})// 開始監(jiān)聽兩個(gè)元素observerBox.observe(restrictionBox.value)observerChil.observe(restrictionChil.value)
})
onUnmounted(() => {destroyedObserver()
})
</script>
外層引用
<script setup>
import HeightRestriction from '../../components/HeightRestriction/HeightRestriction.vue'const ttt1 = ref(0)
const tttt = () => {ttt1.value++
}
</script><template><HeightRestriction><button @click="tttt">測(cè)試</button><div v-for="i in ttt1" :key="i">{{ 'ttt1ttt1ttt1' }}</div></HeightRestriction>
</template>