用 Vue 3.5 TypeScript 做了一個日期選擇器(改進版)

上一篇?已經實現了一個日期選擇器,只不過是模態窗的形式,這個版本改為文本框彈出,點擊空白處可關閉日歷

代碼也增加了不少

<template><div><!-- 添加文本框 --><div class="date-picker-input-wrapper"><inputtype="text"v-model="selectedDateText"@click="showCalendar = true"readonlyplaceholder="請選擇日期"class="date-picker-input"ref="inputRef"/><span class="clear-date-button" @click="clearDate" v-if="selectedDateText"><svg viewBox="0 0 24 24"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path></svg></span></div><!-- 日期選擇器 --><div class="e-calendar" v-show="showCalendar" ref="calendarRef"><div class="e-date-year"><transition name="fadeY"><div:key="selectDate.year"class="e-date-year-select"@click="openYearList":class="{ active: showYear }">{{ selectDate.year }}</div></transition></div><div class="e-date-monthday"><transition name="fadeY"><div:key="selectDate.day"class="e-date-monthday-select":class="{ active: !showYear }"@click="openCalendarList"><span>{{ keepDoubleDigit(selectDate.month) }}-{{ keepDoubleDigit(selectDate.day) }}</span>&nbsp;<span style="cursor: pointer;" @click="openMonthList">{{ showDate.monthStr }}</span></div></transition></div><div class="e-calendar-container" v-show="!showYear && !showMonth"><div class="e-calendar-toolbar"><div class="e-calendar-svg" @click="prevMonth"><svg viewBox="0 0 24 24" class="e-calendar-svg-icon"><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path></svg><transition name="e_calendar_svg_btn"><div class="e-calendar-svg-cover" v-if="prevMonthClick"></div></transition></div><div class="e-calendar-toolbar-title"><transition :name="fadeXType"><div:key="showDate.monthStr"class="e-calendar-toolbar-title-content"><strong>{{ showDate.year }}</strong>&nbsp;<span style="cursor: pointer;" @click="openMonthList">{{ showDate.monthStr }}</span></div></transition></div><div class="e-calendar-svg" @click="nextMonth"><svg viewBox="0 0 24 24" class="e-calendar-svg-icon"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></svg><transition name="e_calendar_svg_btn"><div class="e-calendar-svg-cover" v-if="nextMonthClick"></div></transition></div></div><div class="e-calendar-week"><span class="e-calendar-week-day">一</span><span class="e-calendar-week-day">二</span><span class="e-calendar-week-day">三</span><span class="e-calendar-week-day">四</span><span class="e-calendar-week-day">五</span><span class="e-calendar-week-day">六</span><span class="e-calendar-week-day">日</span></div><div class="e-calendar-monthday"><transition :name="fadeXType"><div:key="showDate.monthStr"class="e-calendar-monthday-wrapper"><divv-for="(row, index) in rows":key="index"class="e-calendar-monthday-row"><spanv-for="(day, dayIndex) in row":key="dayIndex"class="e-calendar-monthday-row-day"@click="selectDay(day)"@mouseenter="handleDayMouseEnter(dayIndex, index)"@mouseleave="handleDayMouseLeave(dayIndex, index)":class="{active: day.selected,disabled: day.disabled,pointer: day.value!== '',hover: isDayHovered(dayIndex, index)}"><spanv-text="day.value"class="e-calendar-monthday-row-day-value"></span><transition name="e_calendar_day"><spanclass="e-calendar-monthday-row-day-cover"v-if="day.selected"></span></transition></span></div></div></transition></div></div><ul class="e-calendar-year" v-show="showYear" ref="yearList"><liv-for="(item, index) in yearList":key="index":class="{active: item === selectDate.year,hover: isYearHovered(index)}"@click="selectYear(item)"@mouseenter="handleYearMouseEnter(index)"@mouseleave="handleYearMouseLeave()">{{ item }}</li></ul><ul class="e-calendar-year" v-show="showMonth" ref="monthList"><liv-for="(item, index) in monthList":key="index":class="{active: item === selectDate.month,hover: isMonthHovered(index)}"@click="selectMonth(item)"@mouseenter="handleMonthMouseEnter(index)"@mouseleave="handleMonthMouseLeave()">{{ item }}</li></ul></div></div>
</template><script lang="ts">
import { defineComponent, ref, computed, onBeforeMount, onMounted, onUnmounted } from 'vue';// 阿拉伯數字 轉 漢字數字的基本庫
const weekJson = {1: '星期一',2: '星期二',3: '星期三',4: '星期四',5: '星期五',6: '星期六',7: '星期日',
};
const monthJson = {1: '一月',2: '二月',3: '三月',4: '四月',5: '五月',6: '六月',7: '七月',8: '八月',9: '九月',10: '十月',11: '十一月',12: '十二月',
};export default defineComponent({props: {// 打開date picker的初始值,必傳,格式是(2017-08-11)date: {type: String,required: true,},// 日期最小值minDate: String,// 日期最大值maxDate: String,},setup(props, { emit }) {// 定義響應式數據let selectDate = ref({year: 0,month: 0,day: 0,week: 0,date: '',weekStr: '',monthStr: '',});let showDate = ref({year: 0,month: 0,day: 0,week: 0,date: '',monthStr: '',weekStr: '',});let copyMinDate = ref({year: 0,month: 0,day: 0,});let copyMaxDate = ref({year: 0,month: 0,day: 0,});const fadeXType = ref('fadeX_Prev');const nextMonthClick = ref(false);const prevMonthClick = ref(false);const showYear = ref(false);const showMonth = ref(false);const yearListRef = ref<HTMLUListElement | null>(null);const monthListRef = ref<HTMLUListElement | null>(null);const showCalendar = ref(false); // 控制日期選擇器的顯示和隱藏const selectedDateText = ref(''); // 文本框顯示的日期const calendarRef = ref<HTMLDivElement | null>(null); // 日期組件的引用const inputRef = ref<HTMLInputElement | null>(null); // 新增文本框引用const hoveredYearIndex = ref(-1);const hoveredMonthIndex = ref(-1);const hoveredDayIndex = ref({ row: -1, col: -1 });const yearList = computed(() => {const result: number[] = [];for (let i = copyMinDate.value.year; i <= copyMaxDate.value.year; i += 1) {result.push(i);}return result;});const monthList = computed(() => {const result: number[] = [];for (let i = 1; i <= 12; i += 1) {result.push(i);}return result;});const rows = computed(() => {const { year, month } = showDate.value;const months = new Date(year, month, 0).getDate();const result: {value: number | string;selected?: boolean;disabled?: boolean;}[][] = [];let row: {value: number | string;selected?: boolean;disabled?: boolean;}[] = [];let weekValue: number;// 按照星期分組for (let i = 1; i <= months; i += 1) {// 根據日期獲取星期,并讓開頭是1,而非0weekValue = new Date(year, month - 1, i).getDay() + 1;// 判斷月第一天在星期幾,并填充前面的空白區域if (i === 1 && weekValue!== 1) {addRowEmptyValue(row, weekValue);addRowDayValue(row, i);} else {addRowDayValue(row, i);// 判斷月最后一天在星期幾,并填充后面的空白區域if (i === months && weekValue!== 7) {addRowEmptyValue(row, (7 - weekValue) + 1);}}// 按照一周分組if (weekValue % 7 === 0 || i === months) {result.push(row);row = [];}}showDate.value.monthStr = monthJson[showDate.value.month as keyof typeof monthJson];return result;});// 初始化日期選擇器const initDatePicker = () => {const splitResult = splitDate(props.date, true);showDate.value = {...splitResult,date: `${splitResult.year}-${keepDoubleDigit(splitResult.month)}-${keepDoubleDigit(splitResult.day)}`,week: splitResult.week || 0,monthStr: splitResult.monthStr || '',weekStr: splitResult.weekStr || '',};copyMinDate.value = { ...splitDate(props.minDate || '1970-01-01') };copyMaxDate.value = { ...splitDate(props.maxDate || '2099-12-31') };selectDate.value = { ...showDate.value };selectedDateText.value = showDate.value.date;};onBeforeMount(() => {initDatePicker();});// 拆分日期const splitDate = (date: string, addStr = false) => {let result: {year: number;month: number;day: number;week?: number;monthStr?: string;weekStr?: string;} = {year: 0,month: 0,day: 0,};const splitValue = date.split('-');try {if (!splitValue || splitValue.length < 3) {throw new Error('時間格式不正確');}result = {year: Number(splitValue[0]),month: Number(splitValue[1]),day: Number(splitValue[2]),};if (addStr) {result.week = new Date(result.year, result.month - 1, result.day).getDay() + 1;result.monthStr = monthJson[result.month as keyof typeof monthJson];result.weekStr = weekJson[result.week as 1 | 2 | 3 | 4 | 5 | 6 | 7];}} catch (error) {console.error(error);}return result;};// 添加空值const addRowEmptyValue = (row: {value: number | string;selected?: boolean;disabled?: boolean;}[],count: number) => {for (let w = 1; w < count; w += 1) {row.push({value: '',});}};// 添加日期值const addRowDayValue = (row: {value: number | string;selected?: boolean;disabled?: boolean;}[],i: number) => {const value = { value: i };const { day, month, year } = selectDate.value;const showDateValue = showDate.value;// 判斷已經選擇的if (year === showDateValue.year && month === showDateValue.month && day === i) {// 為對象添加 selected 屬性const newValue = { ...value, selected: true };row.push(newValue);}// 當日期在最小值之外,禁止點擊if (isMinLimitMonth() && i < copyMinDate.value.day) {// 修復:添加 disabled 屬性const newValue = { ...value, disabled: true };row.push(newValue);}// 當日期在最大值之外,禁止點擊if (isMaxLimitMonth() && i > copyMaxDate.value.day) {// 修復:添加 disabled 屬性const newValue = { ...value, disabled: true };row.push(newValue);}row.push(value);};// 切換到上一個月const prevMonth = () => {if (prevMonthClick.value) {return;}prevMonthClick.value = true;setTimeout(() => {prevMonthClick.value = false;}, 500);fadeXType.value = 'fadeX_Prev';// 如何當前月份已經小于等于minMonth 就不讓其在執行if (isMinLimitMonth()) {return;}const { year, month } = showDate.value;// 判斷當前月份,如果已經等于1(1就是一月,而不是二月)if (month <= 1) {showDate.value.year = year - 1;showDate.value.month = 12;} else {showDate.value.month -= 1;}};// 切換到下一個月const nextMonth = () => {if (nextMonthClick.value) {return;}nextMonthClick.value = true;setTimeout(() => {nextMonthClick.value = false;}, 500);fadeXType.value = 'fadeX_Next';// 如何當前月份已經大于等于maxMonth 就不讓其在執行if (isMaxLimitMonth()) {return;}const { year, month } = showDate.value;// 判斷當前月份,如果已經等于12(12就是十二月)if (month >= 12) {showDate.value.year = year + 1;showDate.value.month = 1;} else {showDate.value.month += 1;}};// 重置選擇日期let resetSelectDate = (dayValue: number) => {selectDate.value = { ...showDate.value };selectDate.value.day = dayValue;selectDate.value.week = new Date(showDate.value.year, showDate.value.month - 1, dayValue).getDay() + 1;selectDate.value.weekStr = weekJson[selectDate.value.week as keyof typeof weekJson];selectedDateText.value = `${selectDate.value.year}-${keepDoubleDigit(selectDate.value.month)}-${keepDoubleDigit(selectDate.value.day)}`;showCalendar.value = false; // 選擇日期后隱藏日期選擇器};// 選擇日期const selectDay = (days: { value: number | string; disabled?: boolean }) => {if (days.disabled || days.value === '') {return;}resetSelectDate(Number(days.value));const { year, month, day, week, weekStr, monthStr } = selectDate.value;emit('confirm', {date: `${year}-${keepDoubleDigit(month)}-${keepDoubleDigit(day)}`,year,month,week,monthStr,weekStr,day,});};// 選擇月份const selectMonth = (value: number) => {showYear.value = false;showMonth.value = false;showDate.value.month = value;let type: 'copyMinDate' | 'copyMaxDate' | undefined;// 當月份在最小值之外,日期換成最小值日期 或者 當月份在最大值之外,日期換成最大值日期if (isMinLimitMonth()) {type = 'copyMinDate';} else if (isMaxLimitMonth()) {type = 'copyMaxDate';}if (type) {showDate.value.day = type === 'copyMinDate'? copyMinDate.value.day : copyMaxDate.value.day;resetSelectDate(showDate.value.day);return;}let dayValue = selectDate.value.day;// 判斷日是最大值,防止另一個月沒有這個日期const daysInMonth = new Date(showDate.value.year, showDate.value.month + 1, 0).getDate();if (selectDate.value.day > daysInMonth) {dayValue = daysInMonth;}resetSelectDate(dayValue);};// 選擇年份const selectYear = (value: number) => {showYear.value = false;showMonth.value = false;showDate.value.year = value;let type: 'copyMinDate' | 'copyMaxDate' | undefined;// 當日期在最小值之外,月份換成最小值月份 或者 當日期在最大值之外,月份換成最大值月份if (isMinLimitMonth()) {type = 'copyMinDate';} else if (isMaxLimitMonth()) {type = 'copyMaxDate';}if (type) {showDate.value.month = copyMinDate.value.month;showDate.value.day = copyMinDate.value.day;resetSelectDate(showDate.value.day);return;}let dayValue = selectDate.value.day;// 判斷日是最大值,防止另一個月沒有這個日期if (selectDate.value.day > 28) {const months = new Date(showDate.value.year, showDate.value.month, 0).getDate();// 當前月份沒有這么多天,就把當前月份最大值賦值給daydayValue = months < dayValue? months : dayValue;}resetSelectDate(dayValue);};// 判斷是否為最小月份限制const isMinLimitMonth = () => {return showDate.value.year <= copyMinDate.value.year && showDate.value.month <= copyMinDate.value.month;};// 判斷是否為最大月份限制const isMaxLimitMonth = () => {return showDate.value.year >= copyMaxDate.value.year && showDate.value.month >= copyMaxDate.value.month;};// 打開年份列表const openYearList = () => {if (showYear.value) {showYear.value = false;showMonth.value = false;return;}const index = yearList.value.indexOf(selectDate.value.year);showYear.value = true;showMonth.value = false;setTimeout(() => {if (yearListRef.value) {yearListRef.value.scrollTop = (index - 3) * 40;}});};// 打開月份列表const openMonthList = () => {if (showMonth.value) {showYear.value = false;showMonth.value = false;return;}const index = monthList.value.indexOf(selectDate.value.month);showMonth.value = true;showYear.value = false;setTimeout(() => {if (monthListRef.value) {monthListRef.value.scrollTop = (index - 3) * 20;}});};const openCalendarList = () => {showYear.value = false;};// 定義函數,接收一個 number 類型的參數,返回一個 string 類型的值const keepDoubleDigit = (number: number): string => {// 判斷傳入的數字是否大于 9return number > 9? String(number) : `0${number}`;};// 清除日期的方法const clearDate = () => {selectedDateText.value = '';showCalendar.value = false;};// 點擊文本框和日期組件以外的區域,隱藏日期組件const handleClickOutside = (event: MouseEvent) => {if (calendarRef.value &&inputRef.value &&!calendarRef.value.contains(event.target as Node) &&!inputRef.value.contains(event.target as Node)) {showCalendar.value = false;}};const isYearHovered = (index: number) => hoveredYearIndex.value === index;const isMonthHovered = (index: number) => hoveredMonthIndex.value === index;const isDayHovered = (col: number, row: number) =>hoveredDayIndex.value.row === row && hoveredDayIndex.value.col === col;const handleYearMouseEnter = (index: number) => {hoveredYearIndex.value = index;};const handleYearMouseLeave = () => {hoveredYearIndex.value = -1;};const handleMonthMouseEnter = (index: number) => {hoveredMonthIndex.value = index;};const handleMonthMouseLeave = () => {hoveredMonthIndex.value = -1;};const handleDayMouseEnter = (col: number, row: number) => {hoveredDayIndex.value = { row, col };};const handleDayMouseLeave = () => {hoveredDayIndex.value = { row: -1, col: -1 };};onMounted(() => {document.addEventListener('click', handleClickOutside);});onUnmounted(() => {document.removeEventListener('click', handleClickOutside);});return {selectDate,showDate,copyMinDate,copyMaxDate,fadeXType,nextMonthClick,prevMonthClick,keepDoubleDigit,showYear,yearList,rows,yearListRef,prevMonth,nextMonth,selectDay,selectYear,openYearList,openMonthList,monthList,monthListRef,showMonth,selectMonth,openCalendarList,showCalendar,selectedDateText,clearDate,calendarRef,inputRef,isYearHovered,isMonthHovered,isDayHovered,handleYearMouseEnter,handleYearMouseLeave,handleMonthMouseEnter,handleMonthMouseLeave,handleDayMouseEnter,handleDayMouseLeave};},
});
</script><style lang="scss" scoped>
.e-calendar {background-color: #ffffff;width: 310px;border: 1px solid #ccc;box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}.date-picker-input-wrapper {position: relative;display: inline-block;
}.date-picker-input {width: 200px;padding: 10px 15px;border: 1px solid #ccc;border-radius: 4px;font-size: 14px;color: #333;box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);transition: border-color 0.3s ease;
}.date-picker-input:focus {outline: none;border-color: #00bcd4;box-shadow: 0 0 5px rgba(0, 188, 212, 0.5);
}.clear-date-button {position: absolute;right: 10px;top: 50%;transform: translateY(-50%);cursor: pointer;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;
}.clear-date-button svg {fill: #999;width: 16px;height: 16px;
}.clear-date-button:hover svg {fill: #333;
}.e-date-year {font-size: 18px;padding-bottom: 4px;position: relative;width: 66px;height: 25px;overflow: hidden;cursor: pointer;
}.e-date-year-select {position: absolute;opacity: 0.7;font-size: 20px;
}.e-date-year-select.active {opacity: 1;
}.e-date-monthday {font-size: 26px;position: relative;width: 100%;height: 36px;overflow: hidden;
}.e-date-monthday-select {position: absolute;opacity: 0.7;
}.e-date-monthday-select.active {opacity: 1;
}.e-calendar-toolbar {margin: 5px 10px 5px 10px;height: 40px;display: flex;justify-content: space-between;align-items: center;
}.e-calendar-toolbar-title {position: relative;width: 100px;height: 22px;text-align: center;
}.e-calendar-toolbar-title-content {position: absolute;width: 100%;font-size: 16px;
}.e-calendar-svg {padding: 8px;position: relative;height: 40px;width: 40px;display: flex;justify-content: center;align-items: center;
}.e-calendar-svg-icon {display: block;fill: currentColor;height: 24px;width: 24px;user-select: none;position: relative;z-index: 2;
}.e-calendar-svg-cover {position: absolute;left: 0;top: 0;z-index: 1;width: 100%;height: 100%;background-color: #e0e0e0;border-radius: 50%;opacity: 0;display: inline-block;
}.e-calendar-week {width: 100%;font-size: 12px;color: rgba(0, 0, 0, 0.87);opacity: 0.5;display: flex;justify-content: center;align-items: center;height: 16px;
}.e-calendar-week-day {flex: 1;text-align: center;
}.e-calendar-monthday {padding-top: 10px;font-size: 14px;position: relative;width: 100%;min-height: 210px;overflow: hidden;
}.e-calendar-monthday-wrapper {position: absolute;width: 100%;height: 100%;
}.e-calendar-monthday-row {display: flex;justify-content: center;align-items: center;
}.e-calendar-monthday-row-day {display: flex;justify-content: center;align-items: center;flex: 1;position: relative;height: 35px;
}.e-calendar-monthday-row-day.pointer {cursor: pointer;
}.e-calendar-monthday-row-day.active {color: #ffffff;
}.e-calendar-monthday-row-day.disabled {opacity: 0.4;cursor: not-allowed;
}.e-calendar-monthday-row-day-value {position: relative;z-index: 1;
}.e-calendar-monthday-row-day-cover {width: 25px;height: 25px;background-color: #00bcd4;position: absolute;left: 10px;top: 5px;transform: translate3d(0, 0, 0);z-index: 0;border-radius: 50%;opacity: 1;display: block;
}.e-calendar-monthday-row-day.hover {background-color: #e0e0e0; /* 鼠標懸停時的背景顏色,可按需調整 */
}.e-calendar-year {height: 276px;overflow: auto;
}.e-calendar-year li {padding: 10px;text-align: center;font-size: 16px;cursor: pointer;
}.e-calendar-year li.active {color: #00bcd4;font-size: 20px;font-weight: bold;
}.e-calendar-year li.hover {background-color: #e0e0e0; /* 這里設置鼠標懸停時的背景顏色,可按需調整 */
}.fadeX_Prev-enter-active,
.fadeX_Prev-leave-active,
.fadeX_Next-enter-active,
.fadeX_Next-leave-active,
.fadeY-enter-active,
.fadeY-leave-active {transition: all 0.5s;
}.fadeX_Prev-enter {transform: translateX(-100px);opacity: 0;
}.fadeX_Prev-leave-active {transform: translateX(100px);opacity: 0;
}.fadeX_Next-enter {transform: translateX(100px);opacity: 0;
}.fadeX_Next-leave-active {transform: translateX(-100px);opacity: 0;
}.fadeY-enter {transform: translateY(30px);opacity: 0;
}.fadeY-leave-active {transform: translateY(-30px);opacity: 0;
}.e_calendar_svg_btn-enter-active,
.e_calendar_svg_btn-leave-active {transition: all 1s;
}.e_calendar_svg_btn-enter {opacity: 1;
}.e_calendar_day-enter-active {transition: all 0.2s;
}.e_calendar_svg_btn-leave-active,
.e_calendar_day-enter {opacity: 0;
}.e_calendar_day-enter {width: 0;height: 0;transform: translate3d(12px, 12px, 0);
}
</style>

?調用的地方變化不大

<template><DatePicker:date="selectedDate":minDate="minDate":maxDate="maxDate"@confirm="onDateConfirm"@cancel="hideDatePicker"/>
</template><script setup lang="ts"> 
import { ref } from 'vue'; 
import DatePicker from './components/gantt/DatePicker.vue';  
import dayjs from 'dayjs'; // 存儲當前選擇的日期,初始值為空 
let selectedDate = ref(dayjs().format('YYYY-MM-DD')); 
// 日期的最小值 
const minDate = ref('2000-01-01'); 
// 日期的最大值 
const maxDate = ref('2030-12-31'); // 處理日期選擇確認事件 
const onDateConfirm = (dateInfo: { date: string; }) => { selectedDate.value  = dateInfo.date;  console.log('選擇的日期信息:', dateInfo);
}; 
const hideDatePicker = () => { // 可以根據需求添加隱藏邏輯,這里暫時不做處理
}; 
</script> 

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/71950.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/71950.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/71950.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【09】單片機編程核心技巧:變量賦值,從定義到存儲的底層邏輯

【09】單片機編程核心技巧&#xff1a;變量賦值&#xff0c;從定義到存儲的底層邏輯 &#x1f31f; 核心概念 單片機變量的定義與賦值是程序設計的基礎&#xff0c;其本質是通過 RAM&#xff08;隨機存儲器&#xff09; 和 ROM&#xff08;只讀存儲器&#xff09; 的協作實現…

【爬蟲】開篇詞

一、網絡爬蟲概述 二、網絡爬蟲的應用場景 三、爬蟲的痛點 四、需要掌握哪些技術&#xff1f; 在這個信息爆炸的時代&#xff0c;如何高效地獲取和處理海量數據成為一項核心技能。無論是數據分析、商業情報、學術研究&#xff0c;還是人工智能訓練&#xff0c;網絡爬蟲&…

文字轉語音chat-tts-ui

去年已經使用過chattts了&#xff0c;但是昨晚想用的時候卻記怎么打開了&#xff0c;找了一下以前的筆記 MacOS 下源碼部署chat-tts-ui 配置好 python3.9-3.11 環境,安裝git &#xff0c;執行命令 brew install libsndfile git python3.10 繼續執行 brew install ffmpeg ? …

基于SpringBoot+Vue的瑜伽課體驗課預約系統【附源碼】

基于SpringBootVue的瑜伽課體驗課預約系統 一、系統技術說明二、運行說明三、系統的演示四、系統的核心代碼演示 一、系統技術說明 框架&#xff1a;SpringbootVue 數據庫&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 數據庫工具&#xff1a;Navicat11 開發軟…

sparkTTS window 安裝

SparkTTS 的簡介 Spark-TTS是一種基于SpardAudio團隊提出的 BiCodec 構建的新系統&#xff0c;BiCodec 是一種單流語音編解碼器&#xff0c;可將語音策略性地分解為兩種互補的標記類型&#xff1a;用于語言內容的低比特率語義標記和用于說話者特定屬性的固定長度全局標記。這種…

從零開始:使用 Python 實現機器學習的基礎與實踐

文章大綱&#xff1a; 引言 機器學習的定義與應用場景。Python 在機器學習領域的優勢。本文目標&#xff1a;通過 Python 實現一個簡單的機器學習項目。 環境準備 安裝 Python 和必要的庫&#xff08;如 NumPy、Pandas、Scikit-learn&#xff09;。使用 Jupyter Notebook 或 V…

ApoorvCTF Rust語言逆向實戰

上周參加了國外的比賽&#xff0c;名稱叫&#xff1a;ApoorvCTF 看一下老外的比賽跟我們有什么不同&#xff0c;然后我根據國內比賽對比發現&#xff0c;他們考點還是很有意思的&#xff0c;反正都是逆向&#xff0c;哈哈哈 Rusty Vault 題目描述&#xff1a; In the heart…

Git和GitHub基礎教學

文章目錄 1. 前言2. 歷史3. 下載安裝Git3.1 下載Git3.2 安裝Git3.3 驗證安裝是否成功 4. 配置Git5. Git基礎使用5.1 通過Git Bash使用5.1.1 創建一個新的倉庫。5.1.1.1 克隆別人的倉庫5.1.1.2 自己創建一個本地倉庫 5.1.2 管理存檔 5.2 通過Visual Studio Code使用 6. Git完成遠…

MySQL中like模糊查詢如何優化?

大家好&#xff0c;我是鋒哥。今天分享關于【MySQL中like模糊查詢如何優化?】面試題。希望對大家有幫助&#xff1b; MySQL中like模糊查詢如何優化? 1000道 互聯網大廠Java工程師 精選面試題-Java資源分享網 在 MySQL 中&#xff0c;LIKE 模糊查詢雖然非常常見&#xff0c;…

?LeetCode(數學分類) 2. 兩數相加——暴力與優化?

?LeetCode(數學分類) 2. 兩數相加——暴力與優化? 提示&#xff1a; 每個鏈表中的節點數在范圍 [1, 100] 內 0 < Node.val < 9 題目數據保證列表表示的數字不含前導零 題解&#xff1a; 暴力與優化&#xff0c;暴力即轉換為十進制解題&#xff0c;優化即直接在鏈表上進…

①Modbus TCP轉Modbus RTU/ASCII網關同步采集無需編程高速輕松組網

Modbus TCP轉Modbus RTU/ASCII網關同步采集無需編程高速輕松組網https://item.taobao.com/item.htm?ftt&id784749793551 MODBUS TCP 通信單元 MODBUS TCP 轉 RS485 MS-A1-50X1 系列概述 MS-A1-50X1 系列概述 MS-A1-50X1系列作為MODBUS TCP通信的服務器進行動作。可通…

基于PyTorch的深度學習——機器學習3

激活函數在神經網絡中作用有很多&#xff0c;主要作用是給神經網絡提供非線性建模能力。如果沒有激活函數&#xff0c;那么再多層的神經網絡也只能處理線性可分問題。 在搭建神經網絡時&#xff0c;如何選擇激活函數&#xff1f;如果搭建的神經網絡層數不多&#xff0c;選擇si…

力扣:找到一個數字的 K 美麗值(C++)

一個整數 num 的 k 美麗值定義為 num 中符合以下條件的 子字符串 數目&#xff1a; 子字符串長度為 k 。子字符串能整除 num 。 給你整數 num 和 k &#xff0c;請你返回 num 的 k 美麗值。 注意&#xff1a; 允許有 前綴 0 。0 不能整除任何值。 一個 子字符串 是一個字符串里…

C/C++藍橋杯算法真題打卡(Day3)

一、P8598 [藍橋杯 2013 省 AB] 錯誤票據 - 洛谷 算法代碼&#xff1a; #include<bits/stdc.h> using namespace std;int main() {int N;cin >> N; // 讀取數據行數unordered_map<int, int> idCount; // 用于統計每個ID出現的次數vector<int> ids; …

<建模軟件安裝教程1>Blender4.2系列

Blender4.2安裝教程 0注意&#xff1a;Windows環境下安裝 第一步&#xff0c;百度網盤提取安裝包。百度網盤鏈接&#xff1a;通過網盤分享的文件&#xff1a;blender.zip 鏈接: https://pan.baidu.com/s/1OG0jMMtN0qWDSQ6z_rE-9w 提取碼: 0309 --來自百度網盤超級會員v3的分…

C語言八股---預處理,編譯,匯編與鏈接篇

前言 從多個.c文件到達一個可執行文件的四步: ??預處理–>編譯–>匯編–>鏈接 預處理 預處理過程就是預處理器處理這些預處理指令(要不然編譯器完全不認識),最終會生成 main.i的文件 主要做的事情有如下幾點: 展開頭文件展開宏條件編譯刪除注釋添加行號等信息保留…

用Deepseek寫一個 HTML 和 JavaScript 實現一個簡單的飛機游戲

大家好&#xff01;今天我將分享如何使用 HTML 和 JavaScript 編寫一個簡單的飛機游戲。這個游戲的核心功能包括&#xff1a;控制飛機移動、發射子彈、敵機生成、碰撞檢測和得分統計。代碼簡潔易懂&#xff0c;適合初學者學習和實踐。 游戲功能概述 玩家控制&#xff1a;使用鍵…

面向高質量視頻生成的擴散模型方法-算法、架構與實現【附核心代碼】

目錄 算法原理 架構 代碼示例 算法原理 正向擴散過程&#xff1a;從真實的視頻數據開始&#xff0c;逐步向其中添加噪聲&#xff0c;隨著時間步 t 的增加&#xff0c;噪聲添加得越來越多&#xff0c;最終將原始視頻數據變成純噪聲。數學上&#xff0c;t 時刻的視頻數據與 t…

水下機器人推進器PID參數整定與MATLAB仿真

水下機器人推進器PID參數整定與MATLAB仿真 1. PID控制原理 目標:通過調節比例(P)、積分(I)、微分(D)參數,使推進器輸出力快速穩定跟蹤期望值。傳遞函數(示例):推進器動力學模型可簡化為: [ G(s) = \frac{K}{\tau s + 1} \cdot e^{-Ts} ] 其中:K為增益,τ為時間常…

游戲引擎學習第149天

今日回顧與計劃 在今天的直播中&#xff0c;我們將繼續進行游戲的開發工作&#xff0c;目標是完成資產文件&#xff08;pack file&#xff09;的測試版本。目前&#xff0c;游戲的資源&#xff08;如位圖和聲音文件&#xff09;是直接從磁盤加載的&#xff0c;而我們正在將其轉…