Vue 封裝公告滾動(dòng)的方法
需求
系統(tǒng)中需要有一個(gè)公告展示,且這個(gè)公告位于頁面上方,每個(gè)頁面都要看到

分析
1. 創(chuàng)建公告組件Notice.vue
第一種
在你的項(xiàng)目的合適組件目錄下(比如components目錄)創(chuàng)建Notice.vue文件,內(nèi)容如下:
<template>
<div class="notice-bar-container">
<div class="notice-bar" v-if="showNotice">
<div class="notice-content-wrapper">
<div class="notice-content" ref="noticeContent">
<span v-if="isScrolling">{{ noticeText }}</span>
</div>
</div>
<button class="close-btn" @click="closeNotice">×</button>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, nextTick, onBeforeMount } from 'vue';
import { onMounted as onWindowMounted } from '@vue/runtime-core';
// 控制公告欄是否顯示的響應(yīng)式變量
const showNotice = ref(true);
// 公告內(nèi)容
const noticeText = ref('這里是公告內(nèi)容示例,可替換哦');
const noticeContent = ref(null);
// 用于存儲(chǔ)頁面寬度
const pageWidth = ref(window.innerWidth);
// 用來存儲(chǔ)滾動(dòng)定時(shí)器
const scrollInterval = ref(null);
// 控制公告內(nèi)容是否開始滾動(dòng)展示的變量
const isScrolling = ref(false);
// 關(guān)閉公告的方法
const closeNotice = () => {
showNotice.value = false;
if (scrollInterval.value) {
clearInterval(scrollInterval.value);
}
};
// 在組件掛載前獲取頁面寬度(首次)
onBeforeMount(() => {
pageWidth.value = window.innerWidth;
});
// 當(dāng)窗口大小變化時(shí),更新頁面寬度
onWindowMounted(() => {
window.addEventListener('resize', () => {
pageWidth.value = window.innerWidth;
});
});
onMounted(() => {
nextTick(() => {
// 獲取滾動(dòng)內(nèi)容的寬度
const contentWidth = noticeContent.value.offsetWidth;
// 設(shè)置外層容器寬度為頁面寬度的50%,并開啟滾動(dòng)
noticeContent.value.parentNode.parentNode.style.width = `${pageWidth.value * 0.5}px`;
noticeContent.value.parentNode.parentNode.style.marginLeft = 'auto';
noticeContent.value.parentNode.parentNode.style.marginRight = 'auto';
noticeContent.value.parentNode.parentNode.style.overflow = 'hidden';
// 克隆一份內(nèi)容用于滾動(dòng)銜接
const cloneNode = noticeContent.value.cloneNode(true);
noticeContent.value.parentNode.appendChild(cloneNode);
// 滾動(dòng)動(dòng)畫邏輯
let scrollDistance = pageWidth.value * 0.5;
const scrollSpeed = 2; // 調(diào)整滾動(dòng)速度,可按需修改
scrollInterval.value = setInterval(() => {
scrollDistance -= scrollSpeed;
if (scrollDistance < -contentWidth) {
scrollDistance = pageWidth.value * 0.5;
}
noticeContent.value.style.transform = `translateX(${scrollDistance}px)`;
// 隱藏頁面展示的文字,只展示滾動(dòng)的文字
noticeContent.value.parentNode.style.overflow = 'hidden';
// 清除公告內(nèi)容區(qū)域可能存在的文本節(jié)點(diǎn)(除了綁定的 noticeText 內(nèi)容)
const childNodes = noticeContent.value.childNodes;
for (let i = 0; i < childNodes.length; i++) {
if (childNodes[i].nodeType === 3 && childNodes[i].textContent.trim()!== noticeText.value.trim()) {
noticeContent.value.removeChild(childNodes[i]);
}
}
// 開始滾動(dòng)時(shí)設(shè)置 isScrolling 為 true,展示公告內(nèi)容
isScrolling.value = true;
}, 30);
});
});
</script>
<style scoped>
.notice-bar-container {
width: 100%;
display: flex;
justify-content: center;
}
.notice-bar {
position: fixed;
top: 0;
background-color: #f8d7da;
color: #721c24;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 999;
}
.notice-content-wrapper {
flex: 1;
overflow: hidden;
}
.notice-content {
white-space: nowrap;
display: inline-block;
}
.close-btn {
background-color: transparent;
border: none;
color: inherit;
font-size: 16px;
cursor: pointer;
}
</style>亮點(diǎn):
- 通過showNotice這個(gè)ref來控制公告欄是否顯示,初始化為true表示默認(rèn)顯示。
- noticeText用來存放公告的具體文本內(nèi)容,這里提供了一個(gè)示例文本,實(shí)際使用時(shí)可以替換成真實(shí)的公告內(nèi)容來源(比如從接口獲取等)。
- closeNotice方法用于點(diǎn)擊關(guān)閉按鈕時(shí)隱藏公告欄,即將showNotice設(shè)置為false。
- 樣式部分,設(shè)置公告欄為固定定位在頁面頂部,設(shè)置了合適的背景色、文字顏色、內(nèi)邊距等,并且讓關(guān)閉按鈕靠右對(duì)齊,同時(shí)給了較高的z-index值確保它能顯示在頁面上方。
第二種
<template>
<div v-if="visible" class="announcement-container">
<div class="announcement-content" :style="{ width: contentWidth + 'px' }">
<span>{{ message }}</span>
</div>
<button class="close-btn" @click="closeAnnouncement">x</button>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
const visible = ref(true); // 公告是否顯示
const message = ref("這是一條滾動(dòng)公告,您可以設(shè)置任何內(nèi)容顯示在這里。");
const contentWidth = ref(0); // 動(dòng)態(tài)計(jì)算公告內(nèi)容的寬度
// 頁面加載時(shí)計(jì)算公告的寬度
onMounted(() => {
contentWidth.value = window.innerWidth / 2; // 公告寬度為頁面寬度的50%
});
// 關(guān)閉公告的邏輯
const closeAnnouncement = () => {
visible.value = false;
};
</script>
<style scoped>
.announcement-container {
position: fixed;
top: 22%;
left: 50%;
transform: translateX(-50%);
width: 50%;
background-color: #ff9800;
color: white;
padding: 10px;
display: flex;
justify-content: space-between;
align-items: center;
z-index: 9999;
font-size: 16px;
border-radius: 5px;
overflow: hidden;
}
.announcement-content {
white-space: nowrap;
overflow: hidden;
animation: scroll-left 20s linear infinite;
}
@keyframes scroll-left {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
.close-btn {
background: transparent;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
padding: 5px;
margin-left: 10px;
}
</style>2. 注冊(cè)全局組件
在你的項(xiàng)目的入口文件(比如main.js或者main.ts,如果是 Vue 3 + TypeScript 的話)中進(jìn)行全局組件注冊(cè),示例如下:
import { createApp } from 'vue';
import App from './App.vue';
import Notice from './components/Notice.vue';
const app = createApp(App);
// 注冊(cè)全局公告組件
app.component('Notice', Notice);
app.mount('#app');通過app.component方法將Notice組件注冊(cè)為全局組件,這樣在項(xiàng)目的任何頁面(組件)中都可以直接使用標(biāo)簽來展示公告欄了。
3. 使用
例如在App.vue或者其他頁面組件中使用:
<template>
<div id="app">
<Notice />
<router-view></router-view>
</div>
</template>到此這篇關(guān)于Vue 封裝公告滾動(dòng)的方法的文章就介紹到這了,更多相關(guān)Vue 公告滾動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
el-date-picker默認(rèn)結(jié)束為當(dāng)前時(shí)分秒的操作方法
在element?ui中的日期時(shí)間選擇組件中默認(rèn)是00:00,現(xiàn)在需求是點(diǎn)擊默認(rèn)結(jié)束時(shí)間為當(dāng)前時(shí)分秒,查了很多資料寫的都不準(zhǔn)確?,今天給大家分享el-date-picker默認(rèn)結(jié)束為當(dāng)前時(shí)分秒的操作方法,感興趣的朋友一起看看吧2024-01-01
Vue 模板中 ref 的自動(dòng)解包機(jī)制及常見誤區(qū)
從Vue 3的Composition API開始,ref成為了處理響應(yīng)式數(shù)據(jù)的核心方式之一,本文給大家介紹Vue模板中ref的自動(dòng)解包機(jī)制及常見誤區(qū),感興趣的朋友跟隨小編一起看看吧2026-03-03
Vue項(xiàng)目中Element UI組件未注冊(cè)的問題原因及解決方法
在 Vue 項(xiàng)目中使用 Element UI 組件庫時(shí),開發(fā)者可能會(huì)遇到一些常見問題,例如組件未正確注冊(cè)導(dǎo)致的警告或錯(cuò)誤,本文將詳細(xì)探討這些問題的原因、解決方法,以及如何在需要時(shí)撤銷相關(guān)操作,需要的朋友可以參考下2025-01-01
在 Vue 3 中設(shè)置 `@` 指向根目錄的幾種常見方法匯總
在 Vue 3 項(xiàng)目開發(fā)中,為了方便管理和引用文件路徑,設(shè)置 @ 指向根目錄是一項(xiàng)常見的需求,下面給大家分享在Vue3中設(shè)置 `@` 指向根目錄的方法匯總,感興趣的朋友一起看看吧2024-06-06
vue中ts無法識(shí)別引入的vue文件,提示找不到xxx.vue模塊的解決
這篇文章主要介紹了vue中ts無法識(shí)別引入的vue文件,提示找不到xxx.vue模塊的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09
vue實(shí)現(xiàn)添加標(biāo)簽demo示例代碼
本篇文章主要介紹了vue實(shí)現(xiàn)添加標(biāo)簽demo示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
vue依賴包報(bào)錯(cuò)問題eslint\lib\cli-engine\cli-engine.js:421
這篇文章主要介紹了vue依賴包報(bào)錯(cuò)問題eslint\lib\cli-engine\cli-engine.js:421,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

