如何实现支持动态传值、自适应内容的Vue Mazeletter背景组件
Mazeletter动态背景组件改造实现思路
- 第一步:定义动态文本Props
给组件新增backgroundText属性,支持外部传入自定义背景文本,设置默认值兜底避免空值异常。 - 第二步:自动计算单行文本重复次数
先通过临时DOM测量单份传入文本的渲染宽度,再结合当前视口宽度计算需要重复的次数,向上取整后重复拼接文本,保证单一行可以完全铺满水平方向视口。 - 第三步:自动计算所需行数
取当前视口高度除以样式中设置的行高,向上取整得到需要渲染的总行数,保证垂直方向可以完全铺满视口。 - 第四步:添加窗口resize监听
监听窗口尺寸变化事件,触发时重新计算行数和单行重复次数,更新渲染内容,适配窗口大小变化场景。 - 可选优化:如果需要适配页面内容高度超过视口的场景,可以把固定定位的高度参数替换为取
document.body.scrollHeight,保证滚动到底部也能正常显示背景。
改造后完整代码示例
<template> <div id="mz-background"> <p class="mz-text" v-for="(_, index) in lineCount" :key="index">{{ repeatedLineText }}</p> </div> </template> <script> export default { name: "UnderworldPattern", props: { backgroundText: { type: String, default: 'ThisIsATest' } }, data() { return { lineCount: 0, repeatedLineText: '' } }, mounted() { this.calcBackgroundParams() window.addEventListener('resize', this.calcBackgroundParams) }, beforeUnmount() { window.removeEventListener('resize', this.calcBackgroundParams) }, methods: { calcBackgroundParams() { // 测量单份文本的实际渲染宽度 const testSpan = document.createElement('span') testSpan.style.font = '90px mazeletter-underworld' testSpan.style.letterSpacing = '-0.409091px' testSpan.style.visibility = 'hidden' testSpan.innerText = this.backgroundText document.body.appendChild(testSpan) const singleTextWidth = testSpan.getBoundingClientRect().width document.body.removeChild(testSpan) // 计算单行需要重复的次数,多重复1次避免边界误差 const repeatTimes = Math.ceil(window.innerWidth / singleTextWidth) + 1 this.repeatedLineText = this.backgroundText.repeat(repeatTimes) // 计算需要的行数,多算1行避免边界误差,行高匹配样式中设置的89.5px this.lineCount = Math.ceil(window.innerHeight / 89.5) + 1 // 适配页面内容高度超过视口的场景可替换上方lineCount计算逻辑为: // const pageHeight = Math.max(window.innerHeight, document.body.scrollHeight) // this.lineCount = Math.ceil(pageHeight / 89.5) + 1 } } }; </script> <style scoped> #mz-background { z-index: 0; position: fixed; overflow: hidden; width: 100vw; height: 100vh; top: 0; left: 0; } .mz-text { line-height: 89.5px; font-family: "mazeletter-underworld"; font-size: 90px; z-index: 1; color: #000000; user-select: none; text-align: left; letter-spacing: -0.409091px; margin: 0; padding: 0; } </style>
内容的提问来源于stack exchange,提问作者BeeNag
相关产品推荐
相关产品推荐

