手把手教你用VUE封裝一個(gè)文本滾動(dòng)組件
一、引言
項(xiàng)目有文本滾動(dòng)展示的需求,一開(kāi)始使用marquee標(biāo)簽來(lái)實(shí)現(xiàn)需求,但是看一下MDN對(duì)該標(biāo)簽的描述:
這個(gè)標(biāo)簽已經(jīng)不再推薦使用了,那就自己封裝一個(gè)類似的組件來(lái)用。
二、實(shí)現(xiàn)思路
1.如何讓文本滾動(dòng)起來(lái)?
通過(guò)動(dòng)畫我們?cè)O(shè)置過(guò)渡transform:translateX(a) => transfrom:translateX(b)來(lái)實(shí)現(xiàn)向左或向右的滾動(dòng)效果。transform:translateY(c) => transfrom:translateY(d)來(lái)實(shí)現(xiàn)向下或向上的滾動(dòng)效果。
2.組件需要哪些配置?
(1)滾動(dòng)的方向:上右下左
(2)滾動(dòng)的速度:這里我以px/s作為單位
三、實(shí)現(xiàn)過(guò)程
1.html
2.css
最外層的div為滾動(dòng)的可視區(qū),里面的div為文本滾動(dòng)區(qū)。可視區(qū)寬度高度均為100%使用時(shí)大小由外部容器決定,overflow設(shè)為hidden,防止文本滾動(dòng)區(qū)滾動(dòng)出可視區(qū)外仍可見(jiàn)。文本滾動(dòng)區(qū)設(shè)置寬高都為fit-content使大小隨內(nèi)容自適應(yīng),內(nèi)部設(shè)置插槽使用組件時(shí)插入滾動(dòng)內(nèi)容。
3.動(dòng)畫
動(dòng)畫應(yīng)設(shè)置在文本滾動(dòng)區(qū)上
需要上右下左四個(gè)方向滾動(dòng)的動(dòng)畫,我們只需要定義上左兩個(gè)方向,另外兩個(gè)方向直接反轉(zhuǎn)即可。先來(lái)想想向上滾動(dòng)的動(dòng)畫怎么寫,向上滾動(dòng)的話文本滾動(dòng)區(qū)的起點(diǎn)應(yīng)設(shè)置在可視區(qū)外正下方,所以動(dòng)畫的起點(diǎn)應(yīng)為 transform: translateY(可視區(qū)的高度),終點(diǎn)應(yīng)設(shè)置在可視區(qū)外正上方應(yīng)為transform: translateY(-100%)。
向上向左動(dòng)畫即為:
--text-scroll-height、--text-scroll-width兩個(gè)css變量的值是可視區(qū)的高度和寬度,由于可視區(qū)的寬高不確定,所以需要通過(guò)js獲取并設(shè)置這兩個(gè)css變量。
注意: 動(dòng)畫樣式不能加上scoped,否則不生效!
4.js
(1)組件配置
通過(guò)props傳入組件配置
(2)計(jì)算得到滾動(dòng)動(dòng)畫
scrollLength為一次動(dòng)畫的實(shí)際滾動(dòng)的長(zhǎng)度,time為一次動(dòng)畫的持續(xù)時(shí)間。我們可以算出scrollLength應(yīng)為:可視區(qū)的寬或高加上文本滾動(dòng)區(qū)的寬或高(根據(jù)滾動(dòng)的方向來(lái)判斷是寬還是高)。time應(yīng)為 scrollLegnth / 組件配置的滾動(dòng)速度。
(3)生命周期
在mounted里調(diào)用上面的方法初始化組件。在updated里同樣調(diào)用該方法,當(dāng)組件寬高改變或插槽內(nèi)容變動(dòng)重新計(jì)算動(dòng)畫樣式。
三、完整代碼
<template> <!-- 文本滾動(dòng) --> <div class="text-scroll" ref="textScroll"> <div class="content" ref="content" :style="scrollAnimation"> <!-- 默認(rèn)插槽,插入滾動(dòng)內(nèi)容 --> <slot></slot> </div> </div> </template> <script> export default { name: "TextScroll", props: { /* 滾動(dòng)方向 * value: up、down、left、right */ direction: { default: "up", type: String, }, //滾動(dòng)速度 單位px/s speed: { default: 60, type: Number, }, }, data() { return { //滾動(dòng)動(dòng)畫 scrollAnimation: {}, }; }, methods: { getScrollAnimation() { //獲取文本滾動(dòng)實(shí)際顯示寬度高度,設(shè)為css變量,用于設(shè)置動(dòng)畫開(kāi)始起始位置 let height = this.$refs.textScroll.offsetHeight; let width = this.$refs.textScroll.offsetWidth; this.$refs.content.style.setProperty( "--text-scroll-height", `${height}px` ); this.$refs.content.style.setProperty("--text-scroll-width", `${width}px`); //滾動(dòng)長(zhǎng)度、時(shí)間 let scrollLength, time; //根據(jù)滾動(dòng)方向來(lái)設(shè)置不同的滾動(dòng)動(dòng)畫 switch (this.direction) { case "up": scrollLength = this.$refs.content.offsetHeight + height; time = scrollLength / this.speed; this.scrollAnimation.animation = `up-scroll linear ${time}s infinite`; break; case "down": scrollLength = this.$refs.content.offsetHeight + height; time = scrollLength / this.speed; this.scrollAnimation.animation = `up-scroll linear ${time}s infinite reverse`; break; case "left": scrollLength = this.$refs.content.offsetWidth + width; time = scrollLength / this.speed; this.scrollAnimation.animation = `left-scroll linear ${time}s infinite`; break; case "right": scrollLength = this.$refs.content.offsetWidth + width; time = scrollLength / this.speed; this.scrollAnimation.animation = `left-scroll linear ${time}s infinite reverse`; break; } }, }, async mounted() { //設(shè)置文本滾動(dòng)動(dòng)畫 this.getScrollAnimation(); }, updated() { //當(dāng)插槽內(nèi)容更新重新計(jì)算滾動(dòng)動(dòng)畫 this.getScrollAnimation(); }, }; </script> <style scoped lang="scss"> .text-scroll { width: 100%; height: 100%; overflow: hidden; .content { height: fit-content; width: fit-content; } } </style> <style lang="scss"> .text-scroll { .content { @keyframes up-scroll { 0% { transform: translateY(var(--text-scroll-height)); } 100% { transform: translateY(-100%); } } @keyframes left-scroll { 0% { transform: translateX(var(--text-scroll-width)); } 100% { transform: translateX(-100%); } } } } </style>
總結(jié)
到此這篇關(guān)于用VUE封裝一個(gè)文本滾動(dòng)組件的文章就介紹到這了,更多相關(guān)VUE封裝文本滾動(dòng)組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3實(shí)現(xiàn)無(wú)縫滾動(dòng)組件的示例代碼
- vue 支持百萬(wàn)量級(jí)的無(wú)限滾動(dòng)組件詳解
- 簡(jiǎn)單方法實(shí)現(xiàn)Vue?無(wú)限滾動(dòng)組件示例
- 基于Vue3實(shí)現(xiàn)無(wú)限滾動(dòng)組件的示例代碼
- vue-seamless-scroll無(wú)縫滾動(dòng)組件使用方法詳解
- 詳解vue 自定義marquee無(wú)縫滾動(dòng)組件
- vue的無(wú)縫滾動(dòng)組件vue-seamless-scroll實(shí)例
- VUE中使用滾動(dòng)組件-vueSeamlessScroll
相關(guān)文章
Vue中ElementUI結(jié)合transform使用時(shí)如何修復(fù)el-select彈框定位不準(zhǔn)確問(wèn)題
這篇文章主要介紹了Vue中ElementUI結(jié)合transform使用時(shí)如何修復(fù)el-select彈框定位不準(zhǔn)確問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-01-01vue實(shí)現(xiàn)無(wú)縫滾動(dòng)的示例詳解
這篇文章主要為大家詳細(xì)介紹了vue非組件如何實(shí)現(xiàn)列表的無(wú)縫滾動(dòng)效果,文中的示例代碼簡(jiǎn)潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-09-09vue開(kāi)發(fā)頁(yè)面自適應(yīng)屏幕尺寸的實(shí)例代碼
使用vue開(kāi)發(fā)的頁(yè)面都是通過(guò)px設(shè)置它的尺寸,如果換了一個(gè)不同尺寸的屏幕就會(huì)出現(xiàn)頁(yè)面排版錯(cuò)亂,顯示不完整等情況,下面通過(guò)插件將px裝換為rem單位適應(yīng)不同尺寸的屏幕,需要的朋友可以參考下2022-12-12element中el-table表頭通過(guò)header-row-style設(shè)置樣式
有些時(shí)候需要給element-ui表頭設(shè)置不同樣式,本文主要介紹了element中el-table表頭通過(guò)header-row-style設(shè)置樣式,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01vue-router?導(dǎo)航完成后獲取數(shù)據(jù)的實(shí)現(xiàn)方法
這篇文章主要介紹了vue-router?導(dǎo)航完成后獲取數(shù)據(jù),通過(guò)使用生命周期的 created() 函數(shù),在組件創(chuàng)建完成后調(diào)用該方法,本文結(jié)合實(shí)例代碼給大家講解的非常詳細(xì)需要的朋友可以參考下2022-11-11