uniapp?實現(xiàn)自定義縮略滾動條效果
<template> <view class="container-scroll"> <!-- 文字導(dǎo)航 --> <scroll-view class="scroll-view-text" scroll-x="true" v-if="type === 1"> <navigator :url="item.url" class="scroll-view-item" :style="`width:${itemWidth}px`" v-for="(item, index) in tarbarList" :key="index" > <!-- 必須得多包一層 --> <view class="text-container" :style="`width:${itemWidth}px`"> <view class="text-nav"> {{ item.title }} </view> </view> </navigator> </scroll-view> <!-- 圖文導(dǎo)航 --> <scroll-view class="img-scroll-view" scroll-x="true" @scroll="handleScroll" ref="scrollView" v-if="type === 2" > <view class="scroll-view-container"> <navigator :url="item.url" class="scroll-view-item" :style="`width:${itemWidth}px`" v-for="(item, index) in tarbarList" :key="index" > <view class="nav-item"> <view class="image-container" :style="imageStyle"> <image class="image" :src="item.image" mode="widthFix" lazy-load="false" :style="imageStyle" > </image> </view> <view class="text-title"> {{ item.title }} </view> </view> </navigator> </view> </scroll-view> </view> <!-- 圖文導(dǎo)航自定義滾動條 --> <view class="custom-scroll-container" v-if="type === 2 && showNumber < tarbarList.length" > <view class="custom-scroll"> <view class="scroll" :style="`transform:translateX(${translateXValue}px)`" /> </view> </view> </template> <script setup name="imageTextNavigator"> import { onMounted, ref, getCurrentInstance, computed } from "vue"; const props = defineProps({ type: { // 1 圖文導(dǎo)航 2 文字導(dǎo)航 type: Number, default: 2, }, // 首屏展示數(shù)量 showNumber: { type: Number, default: 4, }, // 一屏顯示的數(shù)量 tarbarList: { type: Array, default: () => [ { title: "導(dǎo)航導(dǎo)航導(dǎo)航導(dǎo)航", image: "", url: "", }, { title: "導(dǎo)航導(dǎo)航導(dǎo)航導(dǎo)航", image: "", url: "", }, { title: "導(dǎo)航導(dǎo)航導(dǎo)航導(dǎo)航", image: "", url: "", }, { title: "導(dǎo)航導(dǎo)航導(dǎo)航導(dǎo)航", image: "", url: "", }, { title: "導(dǎo)航5", image: "", url: "", }, { title: "導(dǎo)航6", image: "", url: "", }, ], }, }); const instance = getCurrentInstance(); // 活動距離 const translateXValue = ref(0); const itemWidth = ref(0); // 計算滾動距離 function handleScroll(event) { // 30 滑塊父盒子的寬度 // 8 滑塊的寬度 // scrollLeft 是 scroll-view 滾動的距離 const scrollLeft = event.detail.scrollLeft; // 獲取scroll-view滾動的距離 const scrollWidth = event.detail.scrollWidth; // 獲取scroll-view內(nèi)容的總寬度 const viewWidth = 375; // scroll-view的視口寬度 // 滑塊父容器的寬度為30,滑塊的寬度為8,計算出滑塊可移動的最大距離 const maxTranslateX = 30 - 8; // 最大滑動距離 22 // 計算滾動條的移動比例,將內(nèi)容滾動的比例映射到滑塊的移動范圍內(nèi) const moveRatio = maxTranslateX / (scrollWidth - viewWidth); // 滑塊能夠移動距離 比上 大容器能夠滑動的距離,映射出 比率,最高就是 100% 嘛,等比換算 // 計算滑塊的實際位置,確保不會超過最大移動距離 translateXValue.value = Math.min(scrollLeft * moveRatio, maxTranslateX); } // 圖片樣式 const imageStyle = computed(() => { return { width: props.showNumber === 4 ? `44px` : `36px`, height: props.showNumber === 4 ? `44px` : `36px`, }; }); function getElementInfo(id, context) { return new Promise((resolve, reject) => { let query = uni.createSelectorQuery().in(context); query .select(id) .boundingClientRect((rect) => { if (rect) { // 獲取的元素都是 px 需要乘以 2 resolve(rect); } else { reject(); } }) .exec(); }); } async function setNavItemWidth() { const eleInfo = await getElementInfo(".container-scroll", instance); const phoneWidth = eleInfo.width; itemWidth.value = phoneWidth / props.showNumber; } onMounted(async () => { await setNavItemWidth(); }); </script> <style lang="scss" scoped> .container-scroll { width: 750rpx; position: relative; .scroll-view-text { white-space: nowrap; width: 750rpx; display: flex; .scroll-view-item { display: inline-block; background: #ffffff; .text-container { width: 150rpx; height: 100%; display: flex; justify-content: center; align-items: center; .text-nav { width: 112rpx; font-weight: 400; font-size: 28rpx; color: #b2945e; line-height: 28rpx; font-style: normal; text-transform: none; white-space: break-spaces; } } } } .img-scroll-view { display: flex; flex-wrap: nowrap; white-space: nowrap; box-sizing: border-box; width: 750rpx; .scroll-view-container { // padding-left: 64rpx; display: inline-block; .scroll-view-item { display: inline-block; min-height: 154rpx; background: #ffffff; text-align: center; .nav-item { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; flex-direction: column; .text-title { width: 112rpx; font-weight: 400; font-size: 28rpx; color: #333333; line-height: 28rpx; white-space: break-spaces; margin-top: 24rpx; } .image-container { display: flex; justify-content: center; align-items: center; .image { background: #f3f3f3; border-radius: 0px 0px 0px 0px; } } } } } } } // 兩種方案 絕對定位 \ 使用translateX .custom-scroll-container { width: 100%; display: flex; justify-content: center; align-items: center; padding-top: 24rpx; .custom-scroll { width: 60rpx; overflow: hidden; height: 6rpx; background: #f3f3f3; border-radius: 4px 4px 4px 4px; position: relative; .scroll { width: 16rpx; height: 6rpx; background: #b2945e; border-radius: 4px 4px 4px 4px; /* 初始位置 */ transform: translateX(0rpx); } } } </style>
補(bǔ)充:Vue3 通過 axios 獲取項目本地圖片文件進(jìn)行上傳
<template> <input type="file" ref="imageInput" style="display: none" @change="uploadImage" /> </template> <script lang="tsx" setup> import axios from 'axios' import { ref, defineExpose, reactive } from 'vue' import { ElMessage } from 'element-plus' const imageInput = ref<any>(null) // 1、項目本地實現(xiàn)上傳 方法 async function localUplaod() { const imageUrl = require('@/assets/wxapp-icon/test.png') // 本地項目的路徑 const file = await getLocalImageAsFile(imageUrl) const response = await uploadAPI(file) } // 2、模擬點擊事件,實現(xiàn) 本地電腦選擇讓圖片上傳 function handleClick(e) { imageInput.value && imageInput.value.click() } // 自定義圖片上傳 async function uploadImage(event) { const files = event.target.files if (files.length === 0) { ElMessage.error('沒有選擇文件') return } // 讀取第一個文件(假設(shè)用戶只選擇一個文件) const file = files[0] if (!file.type.match('image/*')) { ElMessage.error('請選擇一個圖片文件') return } // 調(diào)用上傳API函數(shù) try { const response = await uploadAPI(file) console.log('上傳成功', response) ElMessage.success('上傳成功') close() } catch (error) { console.log('error', error) ElMessage.error('上傳失敗') } } // 獲取本地圖片 async function getLocalImageAsFile(imagePath) { try { const response = await axios.get(imagePath, { responseType: 'blob' // 指定響應(yīng)類型為blob }) if (response.status === 200) { // 使用 Blob 創(chuàng)建 File 對象 const file = new File([response.data], 'image.png', { type: 'image/png' }) return file } } catch (error) { console.error('獲取圖片文件失敗:', error) throw error } } // 上傳API function uploadAPI(dataFile) { const file = dataFile // 組裝成文件格式進(jìn)行上傳 const formDatas = new FormData() formDatas.append('file', file) return new Promise((resolve, reject) => { axios .post<any, any>({ url: `xxx/xxx/xxx/xxx/xxx/xxx 上傳地址`, data: formDatas, headers: { 'Content-Type': 'multipart/form-data' } }) .then((res) => { resolve(res.data) }) .catch((err) => { reject(err) }) }) } defineExpose({ open, close }) </script> <style lang="scss" scoped></style>
到此這篇關(guān)于uniapp 實現(xiàn)自定義縮略滾動條的文章就介紹到這了,更多相關(guān)uniapp滾動條內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用bootstrap-paginator.js 分頁來進(jìn)行ajax 異步分頁請求示例
本篇文章主要介紹了使用bootstrap-paginator.js 分頁來進(jìn)行ajax 異步分頁請求示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03JavaScript知識點總結(jié)(十一)之js中的Object類詳解
這篇文章主要介紹了JavaScript知識點總結(jié)(十一)之js中的Object類詳解的相關(guān)資料,需要的朋友可以參考下2016-05-05input輸入框限制只能輸入數(shù)字的方法實例(個人認(rèn)為最好的)
在很多業(yè)務(wù)中需要對輸入框進(jìn)行字符限制,比如金額輸入框、手機(jī)號碼輸入框等,下面這篇文章主要給大家介紹了關(guān)于input輸入框限制只能輸入數(shù)字的相關(guān)資料,文中介紹的方法個人認(rèn)為最好的,需要的朋友可以參考下2022-10-10ionic在開發(fā)ios系統(tǒng)微信時鍵盤擋住輸入框的解決方法(鍵盤彈出問題)
在使用ionic開發(fā)ios系統(tǒng)微信的時候遇到一個bug,在填寫表單的時候鍵盤會擋住輸入框。下面小編給大家?guī)砹薸onic在開發(fā)ios系統(tǒng)微信時鍵盤擋住輸入框的解決方法(鍵盤彈出問題),非常不錯,有需要的朋友參考下吧2016-09-09《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 圖片庫
這篇文章主要介紹了《JavaScript DOM 編程藝術(shù)》讀書筆記之JavaScript 圖片庫,需要的朋友可以參考下2015-01-01