当前位置: 首页 > news >正文

vue3+ts封装类似于微信消息的组件

组件代码如下:

<template><div:class="['voice-message', { sent: isSent, received: !isSent }]":style="{ backgroundColor: backgroundColor }"@click="togglePlayback"><!-- isSent为false在左侧,为true在右侧--><!-- 语言条要按照语音时长显示不同的宽度,所以增加了一块宽度,发送者的时候,加在左侧,接收者的时候,加在右侧--><div v-if="isSent" :style="`width:${(duration / 10) * 30}px`"></div><span class="duration" v-if="isSent">{{ duration }}''&nbsp;</span><div :class="['voice-icon', { 'sent-icon': isSent }]"><div :class="['small']" :style="smallStyle"></div><div :class="['middle', { animate: isPlaying }]" :style="middleStyle"></div><div :class="['large', { animate: isPlaying }]" :style="largeStyle"></div></div><span class="duration" :style="{ color: iconColor }" v-if="!isSent">{{ duration }}&nbsp;''</span><div v-if="!isSent" :style="`width:${(duration / 10) * 30}px`"></div></div>
</template><script setup lang="ts">
import { ref, computed, withDefaults, onBeforeUnmount } from "vue";// 使用 withDefaults 提供默认值
const props = withDefaults(defineProps<{isSent?: boolean;iconColor?: string;backgroundColor?: string;smallSize?: number;middleSize?: number;largeSize?: number;duration?: number;audioSrc?: string;}>(),{isSent: false,iconColor: "#000000",backgroundColor: "",smallSize: 10,middleSize: 20,largeSize: 30,duration: 0,audioSrc: ""}
);const isPlaying = ref(false);
let audio: HTMLAudioElement | null = null;// 计算动态样式
const smallStyle = computed(() => ({color: props.iconColor,width: `${props.smallSize}px`,height: `${props.smallSize}px`,marginRight: -props.smallSize + "px"
}));const middleStyle = computed(() => ({color: props.iconColor,width: `${props.middleSize}px`,height: `${props.middleSize}px`,marginRight: -props.middleSize + "px"
}));const largeStyle = computed(() => ({color: props.iconColor,width: `${props.largeSize}px`,height: `${props.largeSize}px`,marginRight: "1px"
}));// 切换播放状态的函数
const togglePlayback = () => {if (isPlaying.value) {pauseVoice();} else {playVoice(props.audioSrc || "");}
};// 播放音频的函数
const playVoice = (voiceSrc: string) => {if (!voiceSrc) {console.error("音频源不能为空");return;}// 如果音频上下文不存在,则创建新的 HTMLAudioElementif (!audio) {audio = new Audio(voiceSrc);} else {audio.src = voiceSrc;}isPlaying.value = true;// 播放音频audio.play().catch(error => console.error("音频播放失败", error));// 监听播放结束事件audio.onended = () => {isPlaying.value = false;};
};// 暂停音频的函数
const pauseVoice = () => {isPlaying.value = false;if (audio) {audio.pause();}
};// 组件卸载时销毁音频上下文
onBeforeUnmount(() => {if (audio) {audio.pause();audio = null;}
});defineExpose({pauseVoice
});
</script><style scoped>
.voice-message {display: inline-flex;align-items: center;cursor: pointer;border-radius: 10px;padding: 4px 12px;
}.voice-message.sent {justify-content: flex-end;
}.voice-message.received {justify-content: flex-start;
}.voice-icon {display: flex;align-items: center;
}.voice-icon.sent-icon {transform: rotate(180deg);
}.small,
.middle,
.large {border-style: solid;border-top-color: transparent;border-left-color: transparent;border-bottom-color: transparent;border-radius: 50%;box-sizing: border-box;vertical-align: middle;display: inline-block;background-color: transparent; /* 默认背景颜色为透明 */
}.middle.animate {animation: show2 3s ease-in-out infinite;
}.large.animate {animation: show3 3s ease-in-out infinite;
}@keyframes show2 {0% {opacity: 0;}30% {opacity: 1;}100% {opacity: 0;}
}@keyframes show3 {0% {opacity: 0;}60% {opacity: 1;}100% {opacity: 0;}
}.duration {margin-left: 8px;font-size: 20px;color: #ffffff;font-weight: 400;
}
</style>

使用时:

<VoicePlayback:isSent="false"iconColor="#ffffff"backgroundColor="rgba(255 255 255 / 20%)":smallSize="5":middleSize="16":largeSize="28":duration="30"audioSrc="http://music.163.com/song/media/outer/url?id=447925558.mp3"
/>

相关文章:

vue3+ts封装类似于微信消息的组件

组件代码如下&#xff1a; <template><div:class"[voice-message, { sent: isSent, received: !isSent }]":style"{ backgroundColor: backgroundColor }"click"togglePlayback"><!-- isSent为false在左侧&#xff0c;为true在右…...

ES6 reduce方法详解:示例、应用场景与实用技巧

在JavaScript中&#xff0c;reduce 方法是一个非常强大的数组方法&#xff0c;它允许你将数组中的元素归并&#xff08;reduce&#xff09;为单个值。reduce 方法执行一个由你提供的reducer函数&#xff08;归并函数&#xff09;&#xff0c;将其结果汇总为单一的返回值。 一.…...

java后端保存的本地图片通过ip+端口直接访问

直接上代码吧 package com.ydx.emms.datapro.controller;import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.…...

2024 年高教社杯全国大学生数学建模竞赛B题4小问解题思路(第二版)

原文链接&#xff1a;https://www.cnblogs.com/qimoxuan/articles/18399415 问题 1&#xff1a;抽样检测方案设计 详细解题思路&#xff1a; 确定抽样检测目标&#xff1a;企业需要确定一个可接受的次品率上限&#xff08;标称值&#xff09;&#xff0c;以及在该次品率下&am…...

docker-nginx数据卷挂载

一、案例1-利用Nginx容器部署静态资源 1.1、需求: 创建Nginx容器&#xff0c; 修改nginx容器内的html目录下的index.html文件,查看变化将静态资源部署到nginx的html目录 1.2、修改html目录下的index.html文件,查看变化 因为docker运用得最小化系统环境&#xff0c;解决办法就…...

项目实战 ---- 商用落地视频搜索系统(8)---优化(2)---查询逻辑层优化

目录 背景 技术衡量与方案 一种可实现方案 可实现方案及设计描述 可能存在的问题 一种创新实现方案 方案的改良设计 策略公式 优化的实现 完整代码 代码解释 异常场景的考量 处理方式 运行注意事项 运行结果 结果优化对比与解释 背景 在项目实战 ---- 商用落地…...

山东大学机试试题合集

&#x1f370;&#x1f370;&#x1f370;高分篇已经涵盖了绝大多数的机试考点&#xff0c;由于临近预推免&#xff0c;各校的机试蜂拥而至&#xff0c;我们接下来先更一些各高校机试题合集&#xff0c;算是对前边学习成果的深入学习&#xff0c;也是对我们代码能力的锻炼。加油…...

餐厅食品留样管理系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;窗口负责人管理&#xff0c;窗口员工管理&#xff0c;冰柜管理&#xff0c;排班信息管理&#xff0c;留样食品管理&#xff0c;教育宣传管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统…...

亚马逊运营:如何提高亚马逊销量和运营效率?

不少亚马逊卖家们为了扩大业务规模和提高销量&#xff0c;会创建多个卖家账户来同时运营多个亚马逊店铺。问题是&#xff0c;这种多店铺运营模式并非没有风险——亚马逊运营的一个重要方面就是账户的健康管理。一旦某个账户出现问题&#xff0c;亚马逊的算法就可能会启动关联检…...

设计模式背后的设计原则和思想

设计模式背后的设计原则和思想是一套指导我们如何设计高质量软件系统的准则和方法论。这些原则和思想不仅有助于提升软件的可维护性、可扩展性和可复用性&#xff0c;还能帮助开发团队更好地应对复杂多变的需求。以下是一些核心的设计原则和思想&#xff1a; 1. 设计原则 设计…...

项目总体框架

一.后端&#xff08;包装servlet&#xff09; 使用BaseServlet进行请求的初步处理&#xff08;利用继承进行执行这个&#xff09; 在BaseServlet中 处理请求的类型找到对象的方法&#xff0c;并使用注解找到参数名&#xff0c;执行参数自动注入。 package com.csdn.controlle…...

k8s Prometheus

一、部署 Prometheus kubectl create ns kube-ops# 创建 prometheus-cm.yaml apiVersion: v1 kind: ConfigMap metadata:name: prometheus-confignamespace: kube-ops data:prometheus.yml: |global:scrape_interval: 15s # 表示 prometheus 抓取指标数据的频率&#xff0c;默…...

glsl着色器学习(九)屏幕像素空间和设置颜色

在上一篇文章中&#xff0c;使用的是裁剪空间进行绘制&#xff0c;这篇文章使用屏幕像素空间的坐标进行绘制。 上一篇的顶点着色器大概是这样子的 回归一下顶点着色的主要任务&#xff1a; 通常情况下&#xff0c;顶点着色器会进行一系列的矩阵变换操作&#xff0c;将输入的顶…...

前端框架有哪些?

前言 用户体验是每个开发网站的企业中的重中之重。无论后台有多方面的操作和功能&#xff0c;用户的视图和体验都必须是无缝的最友好的。这需要使用前端框架来简化交互式、以用户为中心的网站的开发。 前端框架是一种用于简化Web开发的工具&#xff0c;它提供了一套预定义的代…...

分类预测|基于黑翅鸢优化轻量级梯度提升机算法数据预测Matlab程序BKA-LightGBM多特征输入多类别输出 含对比

分类预测|基于黑翅鸢优化轻量级梯度提升机算法数据预测Matlab程序BKA-LightGBM多特征输入多类别输出 含对比 文章目录 一、基本原理BKA&#xff08;Black Kite Algorithm&#xff09;的原理LightGBM分类预测模型的原理BKA与LightGBM的模型流程总结 二、实验结果三、核心代码四、…...

利用大模型实时提取和检索多模态数据探索-利用 Indexify 进行文档分析

概览 传统的文本提取方法常常无法理解非结构化内容&#xff0c;因此提取数据的数据往往是错误的。本文将探讨使用 Indexify&#xff0c;一个用于实时多模态数据提取的开源框架&#xff0c;来更好地分析pdf等非结构化文件。我将介绍如何设置 Indexify&#xff0c;包括服务器设置…...

函数式接口实现策略模式

函数式接口实现策略模式 1.案例背景 我们在日常开发中&#xff0c;大多会写if、else if、else 这样的代码&#xff0c;但条件太多时&#xff0c;往往嵌套无数层if else,阅读性很差&#xff0c;比如如下案例&#xff0c;统计学生的数学课程的成绩&#xff1a; 90-100分&#…...

鸿蒙Next-拉起支付宝的三种方式——教程

鸿蒙Next-拉起支付宝的三种方式——教程 鸿蒙Next系统即将上线&#xff0c;应用市场逐渐丰富、很多APP都准备接入支付宝做支付功能&#xff0c;目前来说有三种方式拉起支付宝&#xff1a;通过支付宝SDK拉起、使用OpenLink拉起、传入支付宝包名使用startAbility拉起。以上的三种…...

Vue.js 组件化开发:父子组件通信与组件注册详解

Vue.js 组件化开发&#xff1a;父子组件通信与组件注册详解 简介&#xff1a; 在 Vue.js 的开发中&#xff0c;组件是构建应用的重要基础。掌握组件的创建与使用&#xff0c;尤其是父子组件的通信和组件的注册与命名&#xff0c;是开发中不可或缺的技能。本文将详细探讨这些内容…...

【HTTP、Web常用协议等等】前端八股文面试题

HTTP、Web常用协议等等 更新日志 2024年9月5日 —— 什么情况下会导致浏览器内存泄漏&#xff1f; 文章目录 HTTP、Web常用协议等等更新日志1. 网络请求的状态码有哪些&#xff1f;1&#xff09;1xx 信息性状态码2&#xff09;2xx 成功状态码3&#xff09;3xx 重定向状态码4&…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Yolov8 目标检测蒸馏学习记录

yolov8系列模型蒸馏基本流程&#xff0c;代码下载&#xff1a;这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中&#xff0c;**知识蒸馏&#xff08;Knowledge Distillation&#xff09;**被广泛应用&#xff0c;作为提升模型…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

Vue3 PC端 UI组件库我更推荐Naive UI

一、Vue3生态现状与UI库选择的重要性 随着Vue3的稳定发布和Composition API的广泛采用&#xff0c;前端开发者面临着UI组件库的重新选择。一个好的UI库不仅能提升开发效率&#xff0c;还能确保项目的长期可维护性。本文将对比三大主流Vue3 UI库&#xff08;Naive UI、Element …...