最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue3如何實(shí)現(xiàn)超絲滑打字機(jī)效果組件(可復(fù)用、高定制)

 更新時(shí)間:2026年03月12日 09:21:43   作者:小馬_xiaoen  
最近遇到一個(gè)需求就是使用Web網(wǎng)頁實(shí)現(xiàn)打字機(jī)特效,覺著還不錯(cuò),這篇文章主要介紹了Vue3如何實(shí)現(xiàn)超絲滑打字機(jī)效果組件的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在前端開發(fā)中,打字機(jī)效果能極大提升頁面的交互趣味性和視覺體驗(yàn),比如 AI 聊天回復(fù)、個(gè)性化介紹頁等場景都非常適用。本文將分享一個(gè)基于 Vue3 + Composition API 開發(fā)的高性能、高定制化打字機(jī)組件,支持打字/刪除循環(huán)、光標(biāo)閃爍、自定義樣式等核心功能,且代碼結(jié)構(gòu)清晰、易于擴(kuò)展。

組件特性

  • ? 自定義打字速度、刪除速度、循環(huán)延遲
  • ? 支持光標(biāo)顯示/隱藏、閃爍效果開關(guān)
  • ? 打字完成后自動(dòng)刪除(可選)+ 循環(huán)播放
  • ? 完全自定義樣式(字體、顏色、大小等)
  • ? 暴露控制方法(開始/暫停),支持手動(dòng)干預(yù)
  • ? 無第三方依賴,純原生 Vue3 實(shí)現(xiàn)
  • ? 性能優(yōu)化:組件卸載自動(dòng)清理定時(shí)器,避免內(nèi)存泄漏

完整組件代碼

<template>
  <div class="typewriter-container" :style="fontsConStyle">
    <!-- 打字文本 - 逐字符渲染 -->
    <span class="typewriter-text">
      <span 
        v-for="(char, index) in displayedText" 
        :key="index" 
        class="character"
        :data-index="index"
      >
        {{ char }}
      </span>
    </span>
    
    <!-- 光標(biāo) - 精準(zhǔn)控制顯示/閃爍 -->
    <span 
      v-if="showCursor && isCursorVisible"
      class="cursor"
      :class="{ 'blink': showBlinkCursor }"
      aria-hidden="true"
    />
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount, computed, watch, watchEffect } from "vue";

// 組件 Props 定義(帶完整校驗(yàn))
const props = defineProps({
  // 要顯示的文本內(nèi)容
  text: {
    type: String,
    required: true,
    default: ""
  },
  // 打字速度(ms/字符)
  speed: {
    type: Number,
    default: 80,
    validator: (value) => value > 0
  },
  // 是否顯示光標(biāo)
  showCursor: {
    type: Boolean,
    default: true
  },
  // 光標(biāo)是否閃爍
  blinkCursor: {
    type: Boolean,
    default: true
  },
  // 是否自動(dòng)開始打字
  autoStart: {
    type: Boolean,
    default: true
  },
  // 是否循環(huán)播放
  loop: {
    type: Boolean,
    default: false
  },
  // 循環(huán)延遲(打字完成后等待時(shí)間)
  loopDelay: {
    type: Number,
    default: 1000,
    validator: (value) => value >= 0
  },
  // 容器樣式(自定義字體、顏色等)
  fontsConStyle: {
    type: Object,
    default: () => ({
      fontSize: "2rem",
      fontFamily: "'Courier New', monospace",
      color: "#333",
      lineHeight: "1.5"
    })
  },
  // 是否開啟刪除效果
  deleteEffect: {
    type: Boolean,
    default: false
  },
  // 刪除速度(ms/字符)
  deleteSpeed: {
    type: Number,
    default: 30,
    validator: (value) => value > 0
  },
  // 字符入場動(dòng)畫開關(guān)
  charAnimation: {
    type: Boolean,
    default: true
  }
});

// 響應(yīng)式狀態(tài)
const displayedText = ref("");    // 當(dāng)前顯示的文本
const currentIndex = ref(0);      // 當(dāng)前字符索引
const isPlaying = ref(false);     // 是否正在播放
const isDeleting = ref(false);    // 是否正在刪除
const isCursorVisible = ref(true);// 光標(biāo)是否顯示

// 定時(shí)器標(biāo)識(用于清理)
let intervalId = null;
let timeoutId = null;
let cursorTimer = null;

// 計(jì)算屬性:控制光標(biāo)閃爍狀態(tài)
const showBlinkCursor = computed(() => {
  return props.blinkCursor && 
         !isDeleting.value &&
         (displayedText.value.length === props.text.length || displayedText.value.length === 0);
});

// 工具函數(shù):清除所有定時(shí)器
const clearAllTimers = () => {
  if (intervalId) clearInterval(intervalId);
  if (timeoutId) clearTimeout(timeoutId);
  if (cursorTimer) clearInterval(cursorTimer);
  intervalId = null;
  timeoutId = null;
  cursorTimer = null;
};

// 核心方法:開始打字
const startTyping = () => {
  // 重置狀態(tài)
  clearAllTimers();
  isPlaying.value = true;
  isDeleting.value = false;
  currentIndex.value = 0;
  displayedText.value = "";
  isCursorVisible.value = true;
  
  // 打字邏輯
  intervalId = setInterval(() => {
    if (currentIndex.value < props.text.length) {
      displayedText.value = props.text.substring(0, currentIndex.value + 1);
      currentIndex.value++;
    } else {
      // 打字完成
      clearInterval(intervalId);
      isPlaying.value = false;
      
      // 循環(huán)邏輯
      if (props.loop) {
        if (props.deleteEffect) {
          timeoutId = setTimeout(startDeleting, props.loopDelay);
        } else {
          timeoutId = setTimeout(startTyping, props.loopDelay);
        }
      }
    }
  }, props.speed);
};

// 核心方法:開始刪除
const startDeleting = () => {
  clearAllTimers();
  isDeleting.value = true;
  
  intervalId = setInterval(() => {
    if (currentIndex.value > 0) {
      currentIndex.value--;
      displayedText.value = props.text.substring(0, currentIndex.value);
    } else {
      // 刪除完成
      clearInterval(intervalId);
      isDeleting.value = false;
      
      // 循環(huán)打字
      if (props.loop) {
        timeoutId = setTimeout(startTyping, props.loopDelay);
      } else {
        isCursorVisible.value = false; // 非循環(huán)模式下刪除完成隱藏光標(biāo)
      }
    }
  }, props.deleteSpeed);
};

// 監(jiān)聽文本變化:自動(dòng)重啟打字(適配動(dòng)態(tài)文本場景)
watch(() => props.text, (newText) => {
  if (newText && props.autoStart) {
    startTyping();
  }
}, { immediate: true });

// 初始化光標(biāo)閃爍(非閃爍模式下固定顯示)
watchEffect(() => {
  if (props.showCursor && !cursorTimer) {
    cursorTimer = setInterval(() => {
      if (!showBlinkCursor.value) {
        isCursorVisible.value = true;
      } else {
        isCursorVisible.value = !isCursorVisible.value;
      }
    }, 500);
  }
});

// 組件掛載:自動(dòng)開始打字
onMounted(() => {
  if (props.autoStart && props.text) {
    startTyping();
  }
});

// 組件卸載:清理所有定時(shí)器(避免內(nèi)存泄漏)
onBeforeUnmount(() => {
  clearAllTimers();
});

// 暴露組件方法(供父組件調(diào)用)
defineExpose({
  start: startTyping,        // 手動(dòng)開始
  pause: clearAllTimers,     // 暫停
  restart: () => {           // 重啟
    clearAllTimers();
    startTyping();
  },
  isPlaying,                 // 當(dāng)前播放狀態(tài)
  isDeleting                 // 當(dāng)前刪除狀態(tài)
});
</script>

<style scoped>
/* 容器樣式 - 適配行內(nèi)/塊級顯示 */
.typewriter-container {
  display: inline-flex;
  align-items: center;
  position: relative;
  font-size: inherit;
  line-height: inherit;
  font-family: inherit;
  white-space: pre-wrap; /* 支持換行符 */
  word-break: break-all; /* 防止長文本溢出 */
}

/* 文本容器 */
.typewriter-text {
  display: inline;
  font-size: inherit;
  line-height: inherit;
  font-family: inherit;
  color: inherit;
}

/* 字符樣式 - 入場動(dòng)畫 */
.character {
  display: inline-block;
  animation: typeIn 0.1s ease-out forwards;
  opacity: 0;
}

/* 字符入場動(dòng)畫 */
@keyframes typeIn {
  0% {
    transform: translateY(5px);
    opacity: 0;
  }
  100% {
    transform: translateY(0);
    opacity: 1;
  }
}

/* 光標(biāo)樣式 - 垂直居中優(yōu)化 */
.cursor {
  display: inline-block;
  width: 2px;
  height: 1.2em; /* 匹配字體高度 */
  background-color: currentColor;
  margin-left: 2px;
  vertical-align: middle;
  position: relative;
  top: 0;
  opacity: 1;
}

/* 光標(biāo)閃爍動(dòng)畫 */
.cursor.blink {
  animation: blink 1s infinite step-end;
}

@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

/* 禁用字符動(dòng)畫的樣式 */
:deep(.character) {
  animation: none !important;
  opacity: 1 !important;
}
</style>

核心優(yōu)化點(diǎn)說明

1. 功能增強(qiáng)

  • 新增 charAnimation 屬性:可開關(guān)字符入場動(dòng)畫,適配不同場景
  • 支持動(dòng)態(tài)文本:監(jiān)聽 text 屬性變化,文本更新自動(dòng)重啟打字
  • 優(yōu)化光標(biāo)邏輯:非閃爍模式下光標(biāo)固定顯示,避免閃爍干擾
  • 新增 restart 方法:支持手動(dòng)重啟打字效果
  • 文本換行支持:添加 white-space: pre-wrap,兼容帶換行符的文本

2. 性能優(yōu)化

  • 定時(shí)器統(tǒng)一管理:所有定時(shí)器集中清理,避免內(nèi)存泄漏
  • 減少不必要渲染:通過 watchEffect 精準(zhǔn)控制光標(biāo)定時(shí)器創(chuàng)建/銷毀
  • 樣式優(yōu)化:使用 currentColor 繼承文本顏色,光標(biāo)顏色與文本一致
  • 邊界處理:添加 word-break: break-all,防止長文本溢出

3. 代碼健壯性

  • 完善 Prop 校驗(yàn):所有數(shù)值類型添加范圍校驗(yàn),避免非法值
  • 狀態(tài)重置:每次開始打字前重置所有狀態(tài),避免多輪執(zhí)行沖突
  • 注釋完善:關(guān)鍵邏輯添加注釋,提升代碼可讀性

使用示例

基礎(chǔ)使用

<template>
  <Typewriter 
    text="Hello Vue3! 這是一個(gè)超絲滑的打字機(jī)效果組件?"
    speed="50"
  />
</template>

<script setup>
import Typewriter from './components/Typewriter.vue';
</script>

高級使用(循環(huán)+刪除效果)

<template>
  <div>
    <Typewriter 
      ref="typewriterRef"
      text="Vue3 打字機(jī)組件 | 支持循環(huán)刪除 | 自定義樣式"
      :speed="60"
      :deleteSpeed="40"
      :loop="true"
      :deleteEffect="true"
      :loopDelay="1500"
      :fontsConStyle="{
        fontSize: '1.5rem',
        color: '#409eff',
        fontFamily: '微軟雅黑'
      }"
    />
    <button @click="handleRestart">重啟打字</button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import Typewriter from './components/Typewriter.vue';

const typewriterRef = ref();

// 手動(dòng)重啟打字
const handleRestart = () => {
  typewriterRef.value.restart();
};
</script>

樣式自定義說明

屬性說明默認(rèn)值
fontSize字體大小2rem
fontFamily字體'Courier New', monospace
color文本顏色#333
lineHeight行高1.5

你可以通過 fontsConStyle 屬性完全自定義組件樣式,例如:

fontsConStyle: {
  fontSize: "18px",
  color: "#e6a23c",
  fontWeight: "bold",
  background: "#f5f7fa",
  padding: "10px 15px",
  borderRadius: "8px"
}

擴(kuò)展方向

  1. 自定義字符動(dòng)畫:通過 Prop 傳入動(dòng)畫類名,支持不同的字符入場效果
  2. 分段打字:支持?jǐn)?shù)組形式的文本,分段打字+間隔
  3. 速度漸變:實(shí)現(xiàn)打字速度由快到慢/由慢到快的效果
  4. 暫停/繼續(xù):擴(kuò)展暫停后繼續(xù)打字的功能(記錄當(dāng)前索引)
  5. 結(jié)合 AI 流式響應(yīng):對接 AI 接口的流式返回,實(shí)時(shí)更新打字文本

總結(jié)

這個(gè)打字機(jī)組件基于 Vue3 Composition API 開發(fā),具備高復(fù)用性、高定制性的特點(diǎn),核心優(yōu)化點(diǎn)如下:

  1. 完善的定時(shí)器管理,避免內(nèi)存泄漏
  2. 精準(zhǔn)的狀態(tài)控制,支持打字/刪除/循環(huán)全流程
  3. 靈活的樣式自定義,適配不同業(yè)務(wù)場景
  4. 暴露控制方法,支持父組件手動(dòng)干預(yù)

組件可直接集成到 Vue3 項(xiàng)目中,適用于 AI 聊天、個(gè)人主頁、產(chǎn)品介紹等需要打字機(jī)效果的場景,開箱即用!

到此這篇關(guān)于Vue3如何實(shí)現(xiàn)超絲滑打字機(jī)效果組件的文章就介紹到這了,更多相關(guān)Vue3超絲滑打字機(jī)效果組件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

海盐县| 塘沽区| 息烽县| 昆山市| 鄂托克前旗| 和静县| 安龙县| 南陵县| 平湖市| 邳州市| 高尔夫| 桓台县| 丽水市| 烟台市| 西乌珠穆沁旗| 永兴县| 西乌珠穆沁旗| 朝阳市| 织金县| 天柱县| 泸溪县| 讷河市| 剑河县| 鄂伦春自治旗| 北碚区| 盱眙县| 广水市| 武乡县| 华亭县| 广德县| 皋兰县| 仲巴县| 龙井市| 鸡东县| 浑源县| 邵武市| 宁阳县| 剑河县| 乐清市| 望城县| 包头市|