vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > Vue 公告滚动

Vue 封装公告滚动的方法

作者:博客zhu虎康

文章介绍了如何在需求系统中创建一个位于页面上方的公告展示组件,展示了如何在App.vue或其他页面组件中使用这个公告组件,感兴趣的朋友一起看看吧

需求

系统中需要有一个公告展示,且这个公告位于页面上方,每个页面都要看到

分析

1. 创建公告组件Notice.vue

第一种

在你的项目的合适组件目录下(比如components目录)创建Notice.vue文件,内容如下:

<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';
// 控制公告栏是否显示的响应式变量
const showNotice = ref(true);
// 公告内容
const noticeText = ref('这里是公告内容示例,可替换哦');
const noticeContent = ref(null);
// 用于存储页面宽度
const pageWidth = ref(window.innerWidth);
// 用来存储滚动定时器
const scrollInterval = ref(null);
// 控制公告内容是否开始滚动展示的变量
const isScrolling = ref(false);
// 关闭公告的方法
const closeNotice = () => {
  showNotice.value = false;
  if (scrollInterval.value) {
    clearInterval(scrollInterval.value);
  }
};
// 在组件挂载前获取页面宽度(首次)
onBeforeMount(() => {
  pageWidth.value = window.innerWidth;
});
// 当窗口大小变化时,更新页面宽度
onWindowMounted(() => {
  window.addEventListener('resize', () => {
    pageWidth.value = window.innerWidth;
  });
});
onMounted(() => {
  nextTick(() => {
    // 获取滚动内容的宽度
    const contentWidth = noticeContent.value.offsetWidth;
    // 设置外层容器宽度为页面宽度的50%,并开启滚动
    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';
    // 克隆一份内容用于滚动衔接
    const cloneNode = noticeContent.value.cloneNode(true);
    noticeContent.value.parentNode.appendChild(cloneNode);
    // 滚动动画逻辑
    let scrollDistance = pageWidth.value * 0.5;
    const scrollSpeed = 2; // 调整滚动速度,可按需修改
    scrollInterval.value = setInterval(() => {
      scrollDistance -= scrollSpeed;
      if (scrollDistance < -contentWidth) {
        scrollDistance = pageWidth.value * 0.5;
      }
      noticeContent.value.style.transform = `translateX(${scrollDistance}px)`;
      // 隐藏页面展示的文字,只展示滚动的文字
      noticeContent.value.parentNode.style.overflow = 'hidden';
      // 清除公告内容区域可能存在的文本节点(除了绑定的 noticeText 内容)
      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]);
        }
      }
      // 开始滚动时设置 isScrolling 为 true,展示公告内容
      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>

亮点:

  • 通过showNotice这个ref来控制公告栏是否显示,初始化为true表示默认显示。
  • noticeText用来存放公告的具体文本内容,这里提供了一个示例文本,实际使用时可以替换成真实的公告内容来源(比如从接口获取等)。
  • closeNotice方法用于点击关闭按钮时隐藏公告栏,即将showNotice设置为false。
  • 样式部分,设置公告栏为固定定位在页面顶部,设置了合适的背景色、文字颜色、内边距等,并且让关闭按钮靠右对齐,同时给了较高的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("这是一条滚动公告,您可以设置任何内容显示在这里。");
const contentWidth = ref(0); // 动态计算公告内容的宽度
// 页面加载时计算公告的宽度
onMounted(() => {
  contentWidth.value = window.innerWidth / 2; // 公告宽度为页面宽度的50%
});
// 关闭公告的逻辑
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. 注册全局组件

在你的项目的入口文件(比如main.js或者main.ts,如果是 Vue 3 + TypeScript 的话)中进行全局组件注册,示例如下:

import { createApp } from 'vue';
import App from './App.vue';
import Notice from './components/Notice.vue';
const app = createApp(App);
// 注册全局公告组件
app.component('Notice', Notice);
app.mount('#app');

通过app.component方法将Notice组件注册为全局组件,这样在项目的任何页面(组件)中都可以直接使用标签来展示公告栏了。

3. 使用

例如在App.vue或者其他页面组件中使用:

<template>
  <div id="app">
    <Notice />
    <router-view></router-view>
  </div>
</template>

到此这篇关于Vue 封装公告滚动的方法的文章就介绍到这了,更多相关Vue 公告滚动内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文