【Nova UI】十六、打造組件庫之滾動條組件(中):探秘滑塊的計算邏輯

序言

在上篇文章中,我們完成了滾動條組件開發的前期準備工作,包括理論推導、布局規劃和基礎設置。現在,我們將把這些準備轉化為實際代碼,開啟滾動條組件的具體開發之旅🌟。我們會詳細闡述如何實現各項功能,解決開發中的技術挑戰,為用戶帶來更好的滾動體驗🌐。

滾動條

在設計滾動條組件時,我們需要考慮橫向和縱向兩個方向的滾動條。這兩個方向的滾動條在功能實現和表現形式上有諸多相似之處,但也存在一些細微的差異。為了提高代碼的可維護性、可復用性和可擴展性,我們決定將滾動條單獨提取出來,作為一個獨立的組件進行開發。基于此,我們在?packages/components/scrollbar/src?目錄下創建了?bar.ts?和?bar.vue?文件,它們將作為實現滾動條功能的核心文件,為后續的開發工作提供強有力的支撐 🏗?。

bar.ts

import { ExtractPropTypes } from 'vue'
import { useDirectionProp } from '@nova-ui/hooks'
import type bar from './bar.vue'export const barProps = {direction: useDirectionProp(),always: Boolean,
} as constexport type BarType = ExtractPropTypes<typeof barProps>export type BarInstance = InstanceType<typeof bar>

在?bar.ts?文件中,barProps?包含?direction?和?always?兩個屬性。direction?用于確定滾動條的方向,并且可以在其他組件中復用 🔄。always?這個屬性用于控制滾動條是否始終顯示,以此來滿足不同的使用場景 🔧。通過?InstanceType<typeof bar>?導出的?BarInstance?類型,有助于在操作滾動條組件實例時確保類型的準確性,避免出現類型錯誤,而且會在?scrollbar?組件中使用 🌟。

bar.vue

<template><divv-show="visible"ref="barRef":class="[n.b(),n.m(direction),n.is('always', always)]"><divref="thumbRef":class="n.e('thumb')"></div></div>
</template><script lang="ts" setup>
const n = useNamespace('bar')
defineOptions({name: 'NBar',
})
const props = defineProps(barProps)
</script>

bar.vue?的基本 DOM 結構由兩個?div?元素組成,一個作為軌道,另一個作為滑塊。首先,我們會定義以下幾個重要的變量:

  • size:用于存儲滑塊的長或寬,方便后續的樣式調整 📏。
  • ratio:表示視圖區域與可視區域的比例,這是計算滑塊大小的關鍵數據 🔢。
  • visible:決定滾動條是否顯示,會根據不同的情況進行調整 👁?。
  • distance:表示滑塊滾動的距離,它會根據用戶的操作而變化呢 📏。

滑塊大小計算

我們需要獲取視圖區域和可視區域的 DOM 元素。在?scrollbar?組件中通過?provide?傳遞,在?bar?組件中通過?inject?獲取,以下是以縱向滾動條為例的代碼,完整代碼可查看相應的倉庫 🔍。

const scrollbar = inject(scrollbarInjectionKey)
const visible = ref(false)
const size = ref(0)
const ratio = ref(1)const updateHandler = () => {const wrap = scrollbar?.wrapElementif (!wrap) returnconst { offsetHeight, scrollHeight }  = wrapconst _ratio = offsetHeight / scrollHeightconst height = _ratio * offsetHeightsize.value = heightratio.value = _ratiovisible.value = offsetHeight < scrollHeight
}

通過上述計算,我們可以得到所需的數值,進而為滑塊添加合適的樣式 🌟。

const thumbStyle = computed(() => {return {[props.direction === 'vertical' ? 'height' : 'width']: size.value ? addUnit(size.value) : undefined} 
})

滑塊滾動距離

在完成滑塊大小的計算和相關屬性的獲取之后,我們要計算滑塊滾動的距離 🔢。

const scrollHandler = () => {const wrap = scrollbar?.wrapElementif (!wrap) returndistance.value = wrap.scrollTop * ratio.value
}

這個計算很簡單,就是將視圖區域滾動的距離與比例相乘。根據這個結果,我們將修改滑塊的樣式:

const thumbStyle = computed(() => {return {[props.direction === 'vertical' ? 'height' : 'width']: size.value ? addUnit(size.value) : undefined,transform: `translate${ props.direction === 'vertical' ? 'Y' : 'X' }(${ distance.value }px)`}
})

至此,基本功能已成型 👏。接下來,我們來看看如何觸發這些方法。

scrollbar 更新 bar的 滑塊

在 VNode 更新之后,我們需要調用相應的方法,這里使用?onUpdated?生命周期來完成。為了更好地兼容不同的場景,當視圖區域大小發生變化時,我們會使用?useResizeObserver?來監聽 DOM 變化并調用?updateHandler?。

const update = () => {barUpdateHandler()barScrollHandler()
}let stopResizeObserver: (() => void) | undefined = undefined
watch(() => props.noresize, (noresize) => {if (noresize) {stopResizeObserver?.()} else {const { stop } = useResizeObserver(wrapRef as unknown as MaybeComputedElementRef, update)stopResizeObserver = stop}
}, { immediate: true })onUpdated(() => {update()
})

scrollbar 更新 bar的 滾動距離

在設置好滑塊的大小之后,我們需要處理滾動距離。我們會對滾動區域進行監聽,觸發?bar?的相關函數。

const barScrollHandler = () => {barVerticalRef.value?.scroll()barHorizontalRef.value?.scroll()
}
const onScroll = () => {barScrollHandler()emits('scroll', {scrollTop: wrapRef.value?.scrollTop || 0,scrollLeft: wrapRef.value?.scrollLeft || 0,})
}

🦀🦀感謝看官看到這里,如果覺得文章不錯的話🙌,點個關注不迷路?。
誠邀您加入我的微信技術交流群🎉,群里都是志同道合的開發者👨?💻,大家能一起交流分享摸魚🐟。期待與您在群里相見🚀,咱們攜手在開發路上共同進步? !
👉點我

感謝各位大俠一路相伴,實在感激! 不瞞您說,在下還有幾個開源項目 📦,它們就像精心培育的幼苗 🌱,急需您的澆灌。要是您瞧著還不錯,麻煩動動手指,給它們點亮幾顆 Star ?,您的支持就是它們成長的最大動力,在此謝過各位大俠啦!

  • Nova UI組件庫:https://github.com/gmingchen/nova-ui
  • 基于 Vue3 + Element-plus 管理后臺基礎功能框架
  • 預覽:https://admin.gumingchen.icu
    • Github:https://github.com/gmingchen/agile-admin
    • Gitee:https://gitee.com/shychen/agile-admin
    • 基礎版后端:https://github.com/gmingchen/java-spring-boot-admin
    • 文檔:http://admin.gumingchen.icu/doc/
  • 基于 Vue3 + Element-plus + websocket 即時聊天系統
    • 預覽:https://chatterbox.gumingchen.icu/
    • Github:https://github.com/gmingchen/chatterbox
    • Gitee:https://gitee.com/shychen/chatterbox
  • 基于 node 開發的后端服務:https://github.com/gmingchen/node-server

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80598.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80598.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80598.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

laravel 使用異步隊列,context帶的上下文造成反序列化出問題

2025年5月8日17:03:44 如果你是單個應用&#xff0c;異步遞交任務&#xff0c;是在應用內部使用&#xff0c;一般不會發生這樣的問題 但是現在app項目是 app是一個應用&#xff0c;admin是一個應用&#xff0c;app吧為了接口性能吧異步任務丟給admin去執行&#xff0c;如果兩個…

深入剖析 MyBatis 位運算查詢:從原理到最佳實踐

深入剖析 MyBatis 位運算查詢&#xff1a;從原理到最佳實踐 引言 在數據庫設計中&#xff0c;位運算是一種高效存儲和查詢多選字段的常用技術。然而&#xff0c;在實際開發中&#xff0c;特別是在使用 MyBatis 這樣的 ORM 框架時&#xff0c;位運算查詢往往會遇到一些意想不到…

01 | 大模型微調 | 從0學習到實戰微調 | AI發展與模型技術介紹

一、導讀 作為非AI專業技術開發者&#xff08;我是小小爬蟲開發工程師&#x1f60b;&#xff09; 本系列文章將圍繞《大模型微調》進行學習&#xff08;也是我個人學習的筆記&#xff0c;所以會持續更新&#xff09;&#xff0c;最后以上手實操模型微調的目的。 (本文如若有…

代碼隨想錄算法訓練營第三十八天|動態規劃part6(完全背包2)

322. 零錢兌換 題目鏈接&#xff1a; 322. 零錢兌換 - 力扣&#xff08;LeetCode&#xff09; 文章講解&#xff1a; 代碼隨想錄 思路&#xff1a; 確定遞推公式&#xff1a; dp[j]min(dp[j],dp[j-coins[i]]1); 由于是完全背包 &#xff0c;所以遍歷順序是正序 還存在另一…

使用 ECharts GL 實現交互式 3D 餅圖:技術解析與實踐

一、效果概覽 本文基于 Vue 3 和 ECharts GL&#xff0c;實現了一個具有以下特性的 3D 餅圖&#xff1a; 立體視覺效果&#xff1a;通過參數方程構建 3D 扇形與底座動態交互&#xff1a;支持點擊選中&#xff08;位移效果&#xff09;和懸停高亮&#xff08;放大效果&#xff…

Transformer Decoder-Only 參數量計算

Transformer 的 Decoder-Only 架構&#xff08;如 GPT 系列模型&#xff09;是當前大語言模型的主流架構&#xff0c;其參數量主要由以下幾個部分組成&#xff1a; 嵌入層&#xff08;Embedding Layer&#xff09;自注意力層&#xff08;Self-Attention Layers&#xff09;前饋…

(自用)Java學習-5.8(總結,springboot)

一、MySQL 數據庫 表關系 一對一、一對多、多對多關系設計外鍵約束與級聯操作 DML 操作 INSERT INTO table VALUES(...) DELETE FROM table WHERE... UPDATE table SET colval WHERE...DQL 查詢 基礎查詢&#xff1a;SELECT * FROM table WHERE...聚合函數&#xff1a;COUNT()…

【日擼 Java 三百行】Day 11(順序表(一))

目錄 Day 11&#xff1a;順序表&#xff08;一&#xff09; 一、關于順序表 二、關于面向對象 三、代碼模塊分析 1. 順序表的屬性 2. 順序表的方法 四、代碼及測試 拓展&#xff1a; 小結 Day 11&#xff1a;順序表&#xff08;一&#xff09; Task&#xff1a; 在《數…

Spring Boot動態配置修改全攻略

精心整理了最新的面試資料和簡歷模板&#xff0c;有需要的可以自行獲取 點擊前往百度網盤獲取 點擊前往夸克網盤獲取 無需重啟應用&#xff0c;實時更新配置的終極指南 在微服務架構中&#xff0c;動態配置管理是提高系統靈活性的關鍵技術。本文將通過4種主流方案&#xff0c…

精益數據分析(55/126):雙邊市場模式的挑戰、策略與創業階段關聯

精益數據分析&#xff08;55/126&#xff09;&#xff1a;雙邊市場模式的挑戰、策略與創業階段關聯 在創業和數據分析的學習旅程中&#xff0c;我們持續探索不同商業模式的奧秘。今天&#xff0c;依舊懷揣著與大家共同進步的想法&#xff0c;深入研讀《精益數據分析》&#xf…

linux內核pinctrl/gpio子系統驅動筆記

目錄 一、簡單介紹二、主要源碼文件和目錄gpio子系統pinctrl子系統兩個子系統之間的關系設備樹例子 三、主要的數據結構gpio子系統pinctrl子系統 四、驅動初始化流程五、難點說明 一、簡單介紹 GPIO子系統: Linux GPIO子系統是Linux內核中負責處理GPIO&#xff08;通用輸入輸出…

Vue 2 項目中配置 Tailwind CSS、Font Awesome和daisyUI

Vue 2 項目中配置 Tailwind CSS 和 安裝 daisyUI 首先重點注意&#xff0c;Vue2中安裝Tailwind和daisyui一定要注意版本。 最佳版本 使用 Vue 2 TailwindCSS v2 DaisyUI v1 的兼容版本 "tailwindcss": "npm:tailwindcss/postcss7-compat^2.2.17", &q…

5.11 - 5.12 JDBC+Mybatis+StringBoot項目配置文件

JDBC&#xff1a; 預編譯SQL優點&#xff1a;安全&#xff0c;性能更高。 在cmd里面輸入java-jar就可以運行jar包。 Mybatis&#xff1a; 持久層框架。用于簡化JDBC的開發。 數據庫連接池里面放置的是一個一個Connection連接對象。&#xff08;連接池中的連接可以復用&#…

探索科技的前沿動態:科技愛好者周刊

探索科技的前沿動態:科技愛好者周刊 在信息爆炸的時代,我們每時每刻都被新技術、新理念包圍。而如何在這紛繁復雜的信息中找到對自己有價值的內容,成了一大挑戰。今天,我們要介紹的是一個寶貴的資源——科技愛好者周刊,它致力于為科技愛好者提供優質的科技資訊,每周五發…

Vue3 官方宣布淘汰 Axios,擁抱Alova.js

過去十年,Axios 憑借其簡潔的API設計和瀏覽器/Node.js雙環境支持,成為前端開發者的首選請求庫。但隨著現代前端框架的演進和工程化需求的升級,Alova.js 以更輕量、更智能、更符合現代開發范式的姿態登場。 一、Axios的痛點 1,冗余的適配邏輯,比如Axios的通用配置(但實際…

Spring AI 與 Groq 的深度集成:解鎖高效 AI 推理新體驗

Spring AI 與 Groq 的深度集成&#xff1a;解鎖高效 AI 推理新體驗 前言 在人工智能飛速發展的當下&#xff0c;AI 推理的效率和性能成為開發者關注的焦點。Groq 作為一款基于 LPU? 的超快速 AI 推理引擎&#xff0c;憑借其強大的性能&#xff0c;能夠支持各類 AI 模型&…

風車OVF鏡像:解放AI開發限制的Ubuntu精簡系統

風車OVF鏡像&#xff1a;解放AI開發限制的Ubuntu精簡系統 AI白嫖續杯一站式-風車ovf AI白嫖續杯一站式解決-風車ovf 前言 作為一名AI開發者&#xff0c;我經常在Windows和Linux環境之間切換開發。然而&#xff0c;Windows平臺上的各種免費版限制逐漸成為我工作效率的瓶頸。在尋…

第十部分:文件與動靜態庫

目錄 1、文件系統 1.1、磁盤 1.2、文件系統 1.3、文件的增刪查改 2、軟硬鏈接 2.1、軟鏈接 2.2、硬鏈接 3、物理內存與文件 4、動靜態庫 4.1、靜態庫 4.1.1、靜態庫的制作 4.1.2、靜態庫的使用 4.2、動態庫 4.2.1、動態庫的制作 4.2.2、動態庫的使用 4.3、動靜…

android14優化ntp時間同步

簡介 網絡時間協議NTP&#xff08;Network Time Protocol&#xff09;是TCP/IP協議族里面的一個應用層協議&#xff0c;用來使客戶端和服務器之間進行時鐘同步&#xff0c;提供高精準度的時間校正。 當機器的ntp時間同步出現問題時&#xff0c;可以從ntp配置方面進行優化&…

ZYNQ筆記(二十):Clocking Wizard 動態配置

版本&#xff1a;Vivado2020.2&#xff08;Vitis&#xff09; 任務&#xff1a;ZYNQ PS端 通過 AXI4Lite 接口配置 Clocking Wizard IP核輸出時鐘頻率 目錄 一、介紹 二、寄存器定義 三、配置 四、PS端代碼 一、介紹 Xilinx 的 Clock Wizard IP核 用于在 FPGA 中生成和管理…