UniApp实现漂亮的音乐歌词滚动播放效果

在现代的音乐播放应用中,歌词的展示和滚动播放已经成为了一个非常常见的功能。今天,我们将通过UniApp来实现一个漂亮的歌词滚动播放功能。我们将使用UniApp提供的组件和API来完成这个任务。

页面结构

在页面的模板部分,我们需要创建一个音频播放器和歌词展示区域。使用<scroll-view>组件来实现歌词的滚动效果。

<template><view class="audio-container"><!-- 音频播放器 --><view class="audio-player"><audio :src="audioSrc" @timeupdate="updateTime" @ended="audioEnded"></audio><view class="controls"><button @click="playAudio">播放</button><button @click="pauseAudio">暂停</button></view><view class="time">{{ currentTime }} / {{ duration }}</view></view><!-- 歌词展示区域 --><scroll-view class="lyrics" scroll-y :scroll-top="scrollTop"><view v-for="(line, index) in lyrics" :key="index" :class="{ active: currentLineIndex === index }">{{ line.text }}</view></scroll-view></view>
</template>

脚本逻辑

在脚本部分,我们需要处理音频的播放、暂停、时间更新等事件,并根据当前播放时间更新歌词的显示和滚动位置。

<script>
export default {data() {return {audioSrc: 'https://example.com/audio.mp3', // 音频文件地址lyrics: [{ time: 0, text: '第一行歌词' },{ time: 5000, text: '第二行歌词' },{ time: 10000, text: '第三行歌词' },// 更多歌词行...],currentTime: '00:00', // 当前播放时间duration: '00:00', // 音频总时长currentLineIndex: 0, // 当前高亮的歌词行索引scrollTop: 0, // 歌词滚动位置};},methods: {playAudio() {const audio = document.querySelector('audio');audio.play();},pauseAudio() {const audio = document.querySelector('audio');audio.pause();},updateTime(event) {const audio = event.target;this.currentTime = this.formatTime(audio.currentTime);this.duration = this.formatTime(audio.duration);this.updateLyrics(audio.currentTime * 1000); // 转换为毫秒},audioEnded() {this.currentTime = '00:00';this.currentLineIndex = 0;this.scrollTop = 0;},updateLyrics(currentTime) {for (let i = 0; i < this.lyrics.length; i++) {if (currentTime >= this.lyrics[i].time) {this.currentLineIndex = i;} else {break;}}this.scrollLyrics();},scrollLyrics() {const lineHeight = 30; // 每行歌词的高度this.scrollTop = this.currentLineIndex * lineHeight;},formatTime(time) {const minutes = Math.floor(time / 60);const seconds = Math.floor(time % 60);return `${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`;},},
};
</script>

样式设计

在样式部分,我们可以设计音频播放器和歌词展示区域的样式,使其看起来更加美观。

<style scoped>
.audio-container {padding: 20px;
}.audio-player {margin-bottom: 20px;
}.controls {margin-bottom: 10px;
}.time {font-size: 14px;color: #666;
}.lyrics {height: 300px;overflow-y: auto;border: 1px solid #ccc;padding: 10px;font-size: 16px;line-height: 1.5;text-align: center;
}.lyrics view {transition: color 0.3s ease;
}.lyrics .active {color: #ff6600;font-weight: bold;
}
</style>

运行效果

通过以上步骤,你可以在UniApp中实现一个漂亮的音乐歌词滚动播放效果。运行项目后,你应该能够看到一个带有播放、暂停按钮的音频播放器,以及随着音乐播放自动滚动的歌词。

app体验地址

项目开源地址:imovie: 爱电影小程序uni-app

歌词解析

 网络上拿到的歌词,可能是类似如下格式:

{"songStatus":1,"lyricVersion":3,"lyric":"[by:有个陷阱他们早就已经沦陷]\n\n[00:09.23]\n[00:20.20]花的心藏在蕊中\n[00:23.80]空把花期都错过\n[00:27.26]\n[00:29.52]你的心忘了季节\n[00:33.12]从不轻易让人懂\n[00:37.24]\n[00:38.81]为何不牵我的手\n[00:42.49]共听日月唱首歌\n[00:46.09]\n[00:47.46]黑夜又白昼\n[00:49.72]黑夜又白昼\n[00:51.73]人生为欢有几何\n[00:55.54]\n[00:57.00]春去春会来\n[01:01.72]花谢花会再开\n[01:06.08]只要你愿意\n[01:08.39]只要你愿意\n[01:10.41]让梦划向你心海\n[01:15.65]春去春会来\n[01:20.32]花谢花会再开\n[01:24.73]只要你愿意\n[01:27.06]只要你愿意\n[01:29.02]让梦划向你心海\n[01:33.43]\n[02:12.13]花瓣泪飘落风中\n[02:15.73]虽有悲意也从容\n[02:19.33]\n[02:21.41]你的泪晶莹剔透\n[02:25.04]心中一定还有梦\n[02:29.30]\n[02:30.73]为何不牵我的手\n[02:34.38]同看海天成一色\n[02:39.36]潮起又潮落\n[02:41.68]潮起又潮落\n[02:43.68]送走人间许多愁\n[02:48.28]\n[02:48.99]春去春会来\n[02:53.61]花谢花会再开\n[02:57.98]只要你愿意\n[03:00.35]只要你愿意\n[03:02.32]让梦划向你心海\n[03:07.58]春去春会来\n[03:12.32]花谢花会再开\n[03:16.58]只要你愿意\n[03:18.95]只要你愿意\n[03:21.01]让梦划向你心海\n[03:26.23]只要你愿意\n[03:28.29]只要你愿意\n[03:30.26]让梦划向你心海\n[03:35.06]\n","code":200}

需要对其解析,解析为类似以下的格式:

lyrics: [{ time: 0, text: '第一行歌词' },{ time: 5000, text: '第二行歌词' },{ time: 10000, text: '第三行歌词' },// 更多歌词行...],

解析方法:

/*** 歌词解析* @param {lrcContent} string - 歌词内容* @returns {lyrics} 对象数组*/
function parseLyric(lrcContent) {const lines = lrcContent.split('\n');const lyrics = [];lines.forEach(line => {const match = line.match(/\[(\d{2}):(\d{2})\.(\d{2,3})\]/);if (match) {const minutes = parseInt(match[1]);const seconds = parseInt(match[2]);const milliseconds = parseInt(match[3]);const time = minutes * 60 * 1000 + seconds * 1000 + milliseconds;// 提取歌词文本const text = line.replace(/\[\d{2}:\d{2}\.\d{2,3}\]/g, '').trim();lyrics.push({ time, text });}});return lyrics;
}

完成audio组件源码

<template><view class="audio_container"><view class="audio-title"style="width: 100%; text-align: left; font-size: 36rpx;font-weight: bold;padding: 0rpx 0rpx; position: relative;"><uni-notice-bar single :scrollable="titleScroll" :size="titleFontSize":background-color="titleBackgroundColor" :color="titleColor" :speed="titleScrollSpeed" :text="title"class="uni-noticebar" style="padding: 0px; margin-bottom: 0px;"></uni-notice-bar><uni-fav v-show="isCollectBtn" :checked="isFavorited" class="favBtn"  bgColor="#dddddd" bgColorChecked="#ffaa00" @click="handleCollec"style="color:#848484; position: absolute;top: 0rpx;right: 0px;"></uni-fav></view><view class="audio-subTitle":style="'font-size: '+subTitleFontSize+';font-weight: bold;padding: 0rpx 0rpx 4rpx 0rpx;position: relative;'"><uni-notice-bar single :scrollable="titleScroll" :size="titleFontSize":background-color="titleBackgroundColor" :color="subTitleColor" :speed="titleScrollSpeed":text="localSubTitle" class="uni-noticebar"></uni-notice-bar><uni-icons v-show="isShareBtn" @click="handleShare" type="redo" size="20"style="color:#848484;position: absolute;top: 0rpx;right: 0px;"></uni-icons></view><view><slider :backgroundColor='backgroundColor' :activeColor='activeColor' @change="handleSliderChange":value="sliderIndex" :max="maxSliderIndex" block-color="#343434" block-size="16" /></view><view style="padding: 0rpx 15rpx 0rpx 15rpx ; display: block; "><view style="float: left; font-size: 20rpx;color:#848484;">{{currentTimeText}}</view><view style="float: right;font-size: 20rpx;color:#848484;">{{totalTimeText}}</view></view><view style="margin-top: 70rpx;"><uni-grid :column="5" :showBorder="false" :square="false"><uni-grid-item><view class="uni-grid-icon"><image @tap="handleFastRewind" src="../../static/images/playlist.svg"style="width: 48rpx;height: 48rpx;top:6rpx;"></image></view></uni-grid-item><uni-grid-item><view class="uni-grid-icon"><image @tap="handleFastRewind" src="../../static/images/get-back.svg"style="width: 48rpx;height: 48rpx;top:6rpx;"></image></view></uni-grid-item><uni-grid-item><view class="uni-grid-icon"><image @tap="handleChangeAudioState" v-show="!isPlaying" src="../../static/images/play.svg"style="width: 48rpx;height: 48rpx;top:6rpx;"></image><image @tap="handleChangeAudioState" v-show="isPlaying" src="../../static/images/pause.svg"style="width: 48rpx;height: 48rpx;top:6rpx;"></image></view></uni-grid-item><uni-grid-item><view class="uni-grid-icon"><image @tap="handleFastForward" src="../../static/images/fast-forward.svg"style="width: 48rpx;height: 48rpx;top:6rpx;"></image></view></uni-grid-item><uni-grid-item><view class="uni-grid-icon"><image @tap="handleLoopPlay" src="../../static/images/Loop.svg"style="width: 48rpx;height: 48rpx; top:6rpx; "></image></view></uni-grid-item></uni-grid></view><view v-show="isShowLrc"><scroll-view class="lyrics" scroll-y :scroll-top="scrollTop" :current="currentLineIndex" ref="lyricsContainer" ><block v-for="(line, index) in lyrics" :key="index"><view :class="{ 'active': currentLineIndex === index }">{{ line.text }}</view></block></scroll-view></view></view>
</template>
<script>export default {name: 'my-audio',//audioPlay开始播放//audioPause停止播放//audioEnd音频自然播放结束事件//audioCanplay音频进入可以播放状态,但不保证后面可以流畅播放//change播放状态改变 返回值false停止播放 true开始播放//audioError 播放器错误//audioCollec 音频收藏emits: ['audioPlay', 'audioPause', 'audioEnd', 'audioCanplay', 'change', 'audioError','audioCollec'],props: {//标题文字title: {type: String,default: '空'},//标题默认字体大小titleFontSize: {type: Number,default: 35},//标题文字颜色titleColor: {type: String,default: '#303030'},//标题背景色titleBackgroundColor: {type: String,default: 'white'},//标题是否滚动titleScroll: {type: Boolean,default: false},//标题滚动速度titleScrollSpeed: {type: Number,default: 100},subTitle: {type: String,default: '空'},subTitleColor: {type: String,default: '#6C7996'},subTitleFontSize: {type: String,default: "30rpx"},//是否自动播放autoplay: {type: Boolean,default: false},//滑块左侧已选择部分的线条颜色activeColor: {type: String,default: '#7C7C7C'},//滑块右侧背景条的颜色backgroundColor: {type: String,default: '#E5E5E5'},//音频地址src: {type: [String, Array],default: ''},//是否倒计时isCountDown: {type: Boolean,default: false},//音乐封面audioCover: {type: String,default: ''},//是否显示收藏按钮isCollectBtn: {type: Boolean,default: false},//状态是否是已收藏isFavorited: {type: Boolean,default: false},//是否显示分享按钮isShareBtn: {type: Boolean,default: false},//是否显示歌词isShowLrc: {type: Boolean,default: false},//歌词信息lyrics: {type: [Array],default: []},},data() {return {totalTimeText: '00:00', //视频总长度文字currentTimeText: '00:00:00', //视频已播放长度文字isPlaying: false, //播放状态sliderIndex: 0, //滑块当前值maxSliderIndex: 100, //滑块最大值IsReadyPlay: false, //是否已经准备好可以播放了isLoop: false, //是否循环播放speedValue: [0.5, 0.8, 1.0, 1.25, 1.5, 2.0],speedValueIndex: 2,playSpeed: '1.0', //播放倍速 可取值:0.5/0.8/1.0/1.25/1.5/2.0currentLineIndex: 0,localSubTitle:this.subTitle,shortLrc:'',scrollTop: 0, // 初始滚动位置stringObject: (data) => {return typeof(data)},innerAudioContext: uni.createInnerAudioContext()}},watch: {subTitle(newVal) {this.localSubTitle = newVal;}},async mounted() {this.innerAudioContext.src = typeof(this.src) == 'string' ? this.src : this.src[0];if (this.autoplay) {if (!this.src) return console.error('src cannot be empty,The target value is string or array')// #ifdef H5var ua = window.navigator.userAgent.toLowerCase();if (ua.match(/MicroMessenger/i) == 'micromessenger') {const jweixin = require('../../utils/jweixin');jweixin.config({});jweixin.ready(() => {WeixinJSBridge.invoke('getNetworkType', {}, (e) => {this.innerAudioContext.play();})})}// #endif// #ifndef H5this.innerAudioContext.autoplay = true;// #endif}//音频播放事件this.innerAudioContext.onPlay(() => {this.isPlaying = true;this.$emit('audioPlay')this.$emit('change', {state: true});setTimeout(() => {this.maxSliderIndex = parseFloat(this.innerAudioContext.duration).toFixed(2);}, 100)});//音频暂停事件this.innerAudioContext.onPause(() => {this.$emit('audioPause');this.$emit('change', {state: false});});//音频自然播放结束事件this.innerAudioContext.onEnded(() => {this.isPlaying = !this.isPlaying;this.$emit('audioEnd');if (this.isLoop) {this.changePlayProgress(0);this.innerAudioContext.play();}});//音频进入可以播放状态,但不保证后面可以流畅播放this.innerAudioContext.onCanplay((event) => {this.IsReadyPlay = true;this.$emit('audioCanplay');let duration = this.innerAudioContext.duration;//console.log('总时长', duration)//将当前音频长度秒转换为00:00:00格式this.totalTimeText = this.getFormateTime(duration);this.maxSliderIndex = parseFloat(duration).toFixed(2);//console.log(this.getFormateTime(duration))//console.log('总时长1', this.totalTimeText)//防止视频无法正确获取时长setTimeout(() => {duration = this.innerAudioContext.duration;//将当前音频长度秒转换为00:00:00格式this.totalTimeText = this.getFormateTime(duration);this.maxSliderIndex = parseFloat(duration).toFixed(2);//console.log('总时长2', this.totalTimeText)}, 300)});//音频播放错误事件this.innerAudioContext.onTimeUpdate((res) => {this.sliderIndex = parseFloat(this.innerAudioContext.currentTime).toFixed(2);this.currentTimeText = this.getFormateTime(this.innerAudioContext.currentTime);//更新歌词const currentTime = this.innerAudioContext.currentTime * 1000; // 转换为毫秒this.updateLyrics(currentTime);});//音频播放错误事件this.innerAudioContext.onError((res) => {console.log(res.errMsg);console.log(res.errCode);this.$emit('change', {state: false});this.audioPause();this.$emit('audioError', res);});},methods: {//销毁innerAudioContext()实例audioDestroy() {console.log("audioDestroy")if (this.innerAudioContext) {if (this.isPlaying && !this.innerAudioContext.paused) {this.audioPause();}this.innerAudioContext.destroy();this.isPlaying = false;}},//点击变更播放状态handleChangeAudioState() {if(this.src ===''){uni.showToast({title: '无播放资源',icon: 'none',duration: 1000});return;}if (this.isPlaying && !this.innerAudioContext.paused) {this.audioPause();} else {this.audioPlay();}},//开始播放audioPlay() {this.$nextTick(() => {this.innerAudioContext.src = this.src;setTimeout(() => {this.innerAudioContext.play();this.isPlaying = true;}, 100); // 100毫秒});},//暂停播放audioPause() {this.innerAudioContext.pause();this.isPlaying = false;},//变更滑块位置handleSliderChange(e) {this.changePlayProgress(e.detail ? e.detail.value : e)},//更改播放倍速handleChageSpeed() {//获取播放倍速列表长度let speedCount = this.speedValue.length;//如果当前是最大倍速,从-1开始if (this.speedValueIndex == (speedCount - 1)) {this.speedValueIndex = -1;}//最新倍速序号this.speedValueIndex += 1;//获取最新倍速文字this.playSpeed = this.speedValue[this.speedValueIndex].toFixed(1);//暂停播放this.audioPause();//变更播放倍速this.innerAudioContext.playbackRate(this.speedValue[this.speedValueIndex]);//开始播放this.audioPlay();},//快退15秒handleFastRewind() {if (this.IsReadyPlay) {let value = parseInt(this.sliderIndex) - 15;this.changePlayProgress(value >= 0 ? value : 0);}},//快进15秒handleFastForward() {if (this.IsReadyPlay) {let value = parseInt(this.sliderIndex) + 15;this.changePlayProgress(value <= this.innerAudioContext.duration ? value : this.innerAudioContext.duration);}},//开启循环播放handleLoopPlay() {this.isLoop = !this.isLoop;if (this.isLoop) {uni.showToast({title: '已开启循环播放',duration: 1000});} else {uni.showToast({title: '取消循环播放',duration: 1000});}},//更改播放进度changePlayProgress(value) {this.innerAudioContext.seek(value);this.sliderIndex = value;this.currentTimeText = this.getFormateTime(value);},//秒转换为00:00:00getFormateTime(time) {let ms = time * 1000; // 1485000毫秒let date = new Date(ms);// 注意这里是使用的getUTCHours()方法,转换成UTC(协调世界时)时间的小时let hour = date.getUTCHours();// let hour = date.getHours(); 如果直接使用getHours()方法,则得到的时分秒格式会多出来8个小时(在国内开发基本都是使用的是东八区时间),getHours()方法会把当前的时区给加上。let minute = date.getMinutes();let second = date.getSeconds();let formatTime =`${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}:${second.toString().padStart(2, '0')}`;return formatTime;},handleCollec() {this.$emit('audioCollec');},handleShare() {this.$emit('audioShare');},updateLyrics(currentTime) {for (let i = 0; i < this.lyrics.length; i++) {if (currentTime >= this.lyrics[i].time) {this.currentLineIndex = i;this.shortLrc = this.lyrics[i].text;this.localSubTitle = this.subTitle + ' : '+this.shortLrc} else {break;}}this.scrollLyrics();},scrollLyrics() {const lineHeight = 20; // 每行歌词的高度this.scrollTop = this.currentLineIndex * lineHeight;},},onLoad() {console.log("onLoad")},onUnload() {console.log("onUnload")this.audioDestroy()},onHide() {console.log("onHide")this.audioDestroy()},beforeDestroy() {console.log("beforeDestroy")this.audioDestroy()}}
</script><style lang="scss" scoped>.audio_container {box-shadow: 0 0 10rpx #c3c3c3;padding: 30rpx 20rpx 30rpx 20rpx;.audio-title {font-size: 28rpx;}.uni-noticebar {padding: 0px;padding-right: 50rpx;margin-bottom: 0px;display: inline-block;}.audio-subTitle {width: 100%;text-align: left;font-size: 40rpx;color: blue;}.speed-text {position: absolute;top: 0rpx;left: 30rpx;right: 0;color: #475266;font-size: 16rpx;font-weight: 600;}.uni-grid-icon {text-align: center;}.lyrics {margin-top: 20px;height: 660rpx; /* 设置歌词容器的高度 */// overflow: hidden; /* 隐藏溢出的歌词 */overflow-y: auto; /* 允许垂直滚动 */position: relative;font-size: 32rpx;line-height: 1.8;text-align: center;}.lyrics view {transition: color 1.2s ease; /* 添加平滑颜色变化效果 */}.lyrics .active {color: #00aa00;font-size: 45rpx;font-weight: bold;}}
</style>

总结

通过使用UniApp的组件和API,我们可以轻松实现音乐歌词的滚动播放效果。关键在于监听音频的播放时间,并根据时间更新歌词的显示和滚动位置。

这里面有个悬而未决的问题,就是这个滚动显示,有时候会滚动到最上方或最下方,导致在视野区域看不到。以下的处理,虽然简单, 但也粗暴。原因就出在这里:

scrollLyrics() {const lineHeight = 20; // 每行歌词的高度this.scrollTop = this.currentLineIndex * lineHeight;
},

如何让歌词能够根据进度居中显示?有知道的欢迎留言,感谢!

其他资源

vue实现歌词滚动_vue 实现一个歌词滚动效果-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1527386.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

基于MinerU的PDF解析API

基于MinerU的PDF解析API - MinerU的GPU镜像构建 - 基于FastAPI的PDF解析接口支持一键启动&#xff0c;已经打包到镜像中&#xff0c;自带模型权重&#xff0c;支持GPU推理加速&#xff0c;GPU速度相比CPU每页解析要快几十倍不等 主要功能 删除页眉、页脚、脚注、页码等元素&…

使用Python中的igraph为绘图添加标题和图例

在 igraph 中&#xff0c;可以通过添加标题和图例来增强图形的可读性和表达能力。我们可以使用 igraph.plot 函数进行绘图&#xff0c;并通过它的参数来指定标题和图例。 1、问题背景 在python中的igraph库中&#xff0c;能否为绘图添加图例和标题&#xff1f;在手册或教程中都…

Qt项目使用Inno Setup打包(关于打包中文乱码的解决)

​ 关于打包好的文件乱码解决方法 打包好的文件中文乱码&#xff0c;就是编码格式出现了问题&#xff0c;更改一下中文脚本编码格式&#xff0c;在官网Inno Setup Translations下载好中文脚本 点击下载&#xff0c;然后另存为 得到ChineseSimplified.isl.txt文件后&#…

《MaPLe: Multi-modal Prompt Learning》中文校对版

系列论文研读目录 文章目录 系列论文研读目录题目&#xff1a;《Maple&#xff1a;多模态提示学习》摘要1.简介2.相关工作视觉语言模型&#xff1a;提示学习&#xff1a;视觉语言模型中的提示学习&#xff1a; 3.方法3.1.回看CLIP编码图像&#xff1a;编码文本&#xff1a;Zero…

【H2O2|全栈】关于HTML(5)HTML基础(四)

HTML基础知识 目录 HTML基础知识 前言 准备工作 标签的具体分类&#xff08;四&#xff09; 本文中的标签在什么位置中使用&#xff1f; 表单&#xff08;一&#xff09; 表单标签 输入域标签 预告和回顾 后话 前言 本系列博客将分享HTML相关知识点。 这一期博客&…

mac|安装nginx

使用homebrew安装nginx brew install nginx 注意&#xff1a; 一般来说nginx会被默认安装在/usr/local/cellar,打开【访达】&#xff0c;前往【电脑】 由于/usr是隐藏文件&#xff0c;无法直接查看。通过 shiftommand. 即可查看 可以看到我的不在这里&#xff08;我也不知道…

python基础语法七-openpyxl操作excel

书接上回&#xff1a; python基础语法一-基本数据类型 python基础语法二-多维数据类型 python基础语法三-类 python基础语法四-数据可视化 python基础语法五-函数 python基础语法六-正则匹配 1. 打开文件 &#xff08;1&#xff09;创建新文件 from openpyxl import W…

仕考网:考公务员有什么好处?

公务员工作节奏不快&#xff0c;工作压力小&#xff0c;不用担心下岗待业工作很稳定。机关事业单位职工退休可拿到在职工资的80%至 90%。薪资待遇高&#xff0c;国家也在不断完善中央和地方公务员薪酬体系管理工作&#xff0c;提高公务员薪资。 1、公务员定义 (1)公务员考试,…

搭建Docker私有仓库管理本地的Docker镜像,通过harbor实现Web UI访问和管理私有仓库

要在本地搭建一个Docker私有仓库&#xff0c;你可以按照以下步骤进行设置&#xff1a; 安装Docker 确保你已经安装了Docker。如果还没有安装&#xff0c;可以按照官方指南进行安装&#xff1a; 对于Ubuntu系统&#xff0c;你可以运行以下命令来安装Docker&#xff1a; sudo ap…

【前端】animation动画以及利用vue制作简单的透明度改变动画,包含vue生命周期实现

一. 问题描述 想做一个文字透明度从1到0然后再从0到1的css动画。 二. 代码写法 2.1 animation写法 2.1.1 animation属性key 2.1.2 代码展示 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"…

利士策分享,逆境破局关键:精准策略

利士策分享&#xff0c;逆境破局关键&#xff1a;精准策略 在人生的征途上&#xff0c;逆境如同试炼场&#xff0c;考验着我们的智慧与勇气。 为了在这片试炼场上稳健前行&#xff0c;我们需要一套具体而精准的应对策略。 以下&#xff0c;是结合实践经验与智慧总结的应对策略…

【环境领域EI稳定 I 院士主讲】第九届能源与环境研究进展国际学术会议(ICAEER 2024)

ICAEER 2024会议投稿经过2-3位组委会专家严格审核之后&#xff0c;符合Springer ESE征稿要求的论文将由斯普林格&#xff08;Springer-Nature&#xff09;旗下的 Environmental Science and Engineering (ISSN: 1863-5520) 出版&#xff0c;出版后提交至EI Compendex&#xff…

最新SMS测压SMS源码 全新版本

php调至7.3 设置伪静态为thinkphp 设置网站运行目录为public 编辑根目录下的.env文件配置数据库信息 详细教程请看源码内置说明文本&#xff01; 亲测截图&#xff01;真实有效&#xff01; 源码下载&#xff1a;https://download.csdn.net/download/m0_66047725/8972239…

如何通过食堂采购小程序端降低成本,提升效率?

随着数字化管理工具的普及&#xff0c;越来越多的食堂正在引入小程序来优化采购流程&#xff0c;减少成本和提升效率。食堂采购小程序端通过技术手段实现了自动化、智能化的管理方式&#xff0c;为管理者提供了极大的便利。本文将探讨如何利用技术手段开发一个高效的食堂采购小…

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数

【鸿蒙HarmonyOS NEXT】页面之间相互传递参数 一、环境说明二、页面之间相互传参 一、环境说明 DevEco Studio 版本&#xff1a; API版本&#xff1a;以12为主 二、页面之间相互传参 说明&#xff1a; 页面间的导航可以通过页面路由router模块来实现。页面路由模块根据页…

828华为云征文|华为云Flexus X实例docker部署rancher并构建k8s集群

828华为云征文&#xff5c;华为云Flexus X实例docker部署rancher并构建k8s集群 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Nginx等服务的需求&#xff0c;一定…

打造可视化数据大屏供应链管理平台:基于食堂采购系统源码的开发方案

食堂采购系统作为供应链管理的一个关键组成部分&#xff0c;通过集成可视化数据大屏&#xff0c;可以有效提升采购和供应链各环节的管理效率。在本文中&#xff0c;我们将探讨如何基于食堂采购系统源码&#xff0c;开发一个高效的可视化数据大屏供应链管理平台。 一、可视化数据…

Java数组(详解版)

数组的定义&#xff1a; 什么是数组&#xff1a; 数组&#xff1a;可以看成是相同类型元素的一个集合。在内存中是一段连续的空间。 1. 数组中存放的元素其类型相同 2. 数组的空间是连在一起的 3. 每个空间有自己的编号&#xff0c;其实位置的编号为 0 &#xff0c;即数组…

C语言蓝桥杯

一、语言基础 竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&…

review——C++中的右值引用

目录 前言 一、什么是左值、什么是右值 二、右值引用 1.右值引用与右值引用的一些性质 2.解释一下左值引用与右值应用于程序员之间的关系 3.右值引用与移动语义 4.右值引用右值后变成左值的必要性与完美转发 1.右值引用引用右值后变为左值属性的必要性 2.完美转发 Ⅰ…