??????前言:今天來分享一下移動端Slider劃動active狀態(tài)切換樣式的相關(guān)處理方案。
開整
1. src/views/main/components/navigation/mobile/index.vue
<!-- 滑塊 -->
<li
ref="sliderTarget"
class="absolute h-[22px] bg-zinc-900 rounded-lg duration-200"
:style="sliderStyle"
></li>
<script setup>
import { ref } from 'vue'
// 滑塊
const sliderStyle = ref({
transform: 'translateX(0px)',
width: '60px'
})
</script>
??????分析一波:通過
translateX來控制Slider的切換,所以我們需要計算除當(dāng)前點擊的item的位置和寬度。
- 裝備一:選中的item下標(biāo):currentCategoryIndex
- 裝備二:所有的items元素:itemRefs
- 裝備三:最外層父元素 ul 的橫向滾動偏離位置:ulScrollLeft
- 裝備四:currentCategoryIndex改變時,獲取
items下標(biāo)元素的left和width,計算 sliderStyle
??????插播一條小知識點:Element.getBoundingClientRect() - Web API 接口參考 | MDN (mozilla.org) 返回元素的大小及其相對于視口的位置。
??????插播一條小知識點:useScroll | VueUse中文文檔 (vueusejs.com) 響應(yīng)式獲取滾動位置和狀態(tài)。
<ul ref="ulTarget">
<!-- 滑塊 -->
<li
:style="sliderStyle"
></li>
<!-- category item -->
<li
:ref="setItemRef"
:class="{
'text-zinc-100 ': currentCategoryIndex === index // 選中文字高亮
}"
@click="onItemClick(index)"
>
{{ item.name }}
</li>
</ul>
<script setup>
import { ref, watch, onBeforeUpdate } from 'vue'
import { useScroll } from '@vueuse/core'
// 滑塊
const sliderStyle = ref({
transform: 'translateX(0px)',
width: '60px'
})
// 選中的 item 下標(biāo)
const currentCategoryIndex = ref(0)
// 獲取填充的所有 item 元素
let itemRefs = []
const setItemRef = (el) => {
if (el) {
itemRefs.push(el)
}
}
onBeforeUpdate(() => {
itemRefs = []
})
// 獲取 ul 元素,以計算偏移位置
const ulTarget = ref(null)
const { x: ulScrollLeft } = useScroll(ulTarget)
watch(currentCategoryIndex, (val) => {
// 獲取選中元素的 left、width
const { left, width } = itemRefs[val].getBoundingClientRect()
// 為 sliderStyle 設(shè)置屬性
sliderStyle.value = {
// ul 橫向滾動位置 + 當(dāng)前元素的 left 偏移量
transform: `translateX(${ulScrollLeft.value + left - 10 + 'px'})`,
width: width + 'px'
}
})
// item 點擊事件
const onItemClick = (index) => {
currentCategoryIndex.value = index
}
??????完事兒

販賣快樂~.png