「Vue 項目中實現智能時間選擇:帶業務規則的級聯選擇器」

#創作靈感

公司業務需要,某個時間節點前可以選擇到月,某個時間節點后只能選擇季度

vue2? Vant2

javascript

import { Cascader, Field, Form, Popup, Button } from 'vant';
import 'vant/lib/index.css';export default {name: 'CascaderPage',components: {VanCascader: Cascader,VanField: Field,VanForm: Form,VanPopup: Popup,VanButton: Button},props: {title: {type: String,default: '選擇時間'},// 起始年份,默認從當前年往前5年startYear: {type: Number,default: new Date().getFullYear() - 5},// 結束年份,默認從當前年往后5年endYear: {type: Number,default: new Date().getFullYear() + 5}},data() {return {showPopup: false,cascaderValue: '',fieldValue: '',selectedResult: '',fieldNames: {text: 'label',value: 'value',children: 'children'}};},computed: {// 生成級聯選擇的選項options() {const yearOptions = [];// 生成年份選項for (let year = this.startYear; year <= this.endYear; year++) {const quarterOptions = [];// 生成季度選項for (let quarter = 1; quarter <= 4; quarter++) {const quarterObj = {label: `${year}年第${quarter}季度`,value: `${year}-Q${quarter}`// 移除默認children屬性,避免空選項};// 判斷是否需要生成月份選項// 規則:2025年9月及之前需要月份,之后不需要if (year < 2025) {// 2025年之前,所有季度都需要月份quarterObj.children = this.getMonthsByQuarter(quarter);} else if (year === 2025) {// 2025年,只有前3季度需要月份if (quarter <= 3) {quarterObj.children = this.getMonthsByQuarter(quarter);}}// 2025年之后的年份,不生成月份選項quarterOptions.push(quarterObj);}yearOptions.push({label: `${year}年`,value: year.toString(),children: quarterOptions});}return yearOptions;}},methods: {// 根據季度獲取對應的月份getMonthsByQuarter(quarter) {const months = [];let startMonth, endMonth;switch (quarter) {case 1:startMonth = 1;endMonth = 3;break;case 2:startMonth = 4;endMonth = 6;break;case 3:startMonth = 7;endMonth = 9;break;case 4:startMonth = 10;endMonth = 12;break;default:return [];}for (let month = startMonth; month <= endMonth; month++) {months.push({label: `${month}月`,value: month.toString()});}return months;},// 處理選擇變化 - 只在選擇完最后一級選項時關閉handleChange(value) {const { selectedOptions, tabIndex } = value;console.log('選擇變化:', value, selectedOptions, tabIndex);// 如果沒有選擇值,不處理if (!selectedOptions || selectedOptions.length === 0) return;// 獲取當前選中的年份const selectedYear = parseInt(selectedOptions[0].value);// 構建正確格式的selectedValues數組const selectedValues = [];selectedValues.push(selectedOptions[0].value); // 年份if (selectedOptions.length >= 2) {// 對于季度,提取數字部分const quarterStr = selectedOptions[1].value;if (quarterStr.includes('-Q')) {selectedValues.push(quarterStr.split('-Q')[1]); // 只提取季度數字} else {selectedValues.push(quarterStr);}}if (selectedOptions.length === 3) {selectedValues.push(selectedOptions[2].value); // 月份}// 檢查是否已經選擇到最后一級if (selectedOptions.length === 2) {// 情況1: 如果是2025年之后或2025年第4季度,選擇完季度就關閉const quarterValue = selectedOptions[1].value;const quarter = parseInt(quarterValue.includes('-Q') ? quarterValue.split('-Q')[1] : quarterValue);if (selectedYear > 2025 || (selectedYear === 2025 && quarter === 4)) {this.onConfirm(selectedValues, selectedOptions);}// 其他情況:選擇完季度后繼續選擇月份,不關閉} else if (selectedOptions.length === 3) {// 情況2: 選擇完月份后關閉this.onConfirm(selectedValues, selectedOptions);}},// 確認選擇onConfirm(selectedValues, selectedOptions) {if (!selectedValues || selectedValues.length === 0) return;// 格式化選中的結果const formattedResult = this.formatSelectedResult(selectedValues);this.fieldValue = formattedResult;this.selectedResult = `您選擇了:${formattedResult}`;this.showPopup = false;},// 格式化選中的結果formatSelectedResult(selectedValues) {if (!selectedValues || selectedValues.length === 0) return '';// 處理selectedValues可能是字符串的情況let values = Array.isArray(selectedValues) ? selectedValues : [selectedValues];// 如果只有一個值,嘗試從值中解析出年份if (values.length === 1) {const value = values[0];// 檢查是否是季度格式if (typeof value === 'string' && value.includes('-Q')) {const parts = value.split('-Q');const year = parts[0];const quarter = parts[1];return `${year}年第${quarter}季度`;}// 只顯示年份return `${value}年`;}let result = '';// 年份result += `${values[0]}年`;// 季度if (values.length >= 2) {let quarter;if (typeof values[1] === 'string' && values[1].includes('-Q')) {// 處理字符串格式的季度值quarter = values[1].split('-Q')[1];} else {// 直接使用季度值quarter = values[1];}result += `第${quarter}季度`;}// 月份 - 確保月份顯示為兩位數格式if (values.length === 3) {const month = parseInt(values[2]);// 格式化月份為兩位數const formattedMonth = month < 10 ? `0${month}` : `${month}`;result += `${formattedMonth}月`;}return result;},// 表單提交onSubmit(values) {if (!this.fieldValue) {this.$toast('請選擇時間');return;}this.$toast(`提交成功:${this.fieldValue}`);}},mounted() {// 生命周期鉤子:設置默認選中最后一項try {if (this.options.length > 0) {const lastYear = this.options[this.options.length - 1];if (lastYear.children && lastYear.children.length > 0) {const lastQuarter = lastYear.children[lastYear.children.length - 1];const selected = [lastYear.value,lastQuarter.value];// 如果有月份選項,也選中最后一個if (lastQuarter.children && lastQuarter.children.length > 0) {selected.push(lastQuarter.children[lastQuarter.children.length - 1].value);}this.cascaderValue = selected.join('/');this.fieldValue = this.formatSelectedResult(selected);this.selectedResult = `您選擇了:${this.fieldValue}`;}}} catch (error) {console.error('設置默認選中項失敗:', error);}}
};

HTML

  <div class="cascader-container"><h2>Vant 時間級聯選擇器示例</h2><van-form @submit="onSubmit"><div class="field-container"><van-fieldv-model="fieldValue"readonlylabel="時間選擇"placeholder="請選擇時間":value="fieldValue"/><van-button type="primary" @click="showPopup = true"style="margin-left: 10px; min-width: 100px;">選擇時間</van-button></div></van-form><!-- Popup彈窗 --><van-popupv-model="showPopup"roundposition="bottom":style="{ height: '80%' }"><div class="popup-header"><h3>{{ title }}</h3><van-button type="text" @click="showPopup = false"style="position: absolute; right: 16px; top: 16px;">取消</van-button></div><van-cascaderv-model="cascaderValue":options="options":field-names="fieldNames"@change="handleChange"@close="showPopup = false"placeholder=""/></van-popup><div class="result-section" v-if="selectedResult"><h3>選擇結果</h3><p>{{ selectedResult }}</p></div></div>

css

.cascader-container {padding: 20px;max-width: 600px;margin: 0 auto;
}.field-container {display: flex;align-items: center;
}.popup-header {padding: 16px;border-bottom: 1px solid #eee;position: relative;text-align: center;
}.popup-header h3 {margin: 0;color: #333;font-size: 16px;
}.cascader-container h2 {text-align: center;margin-bottom: 20px;color: #333;
}.result-section {margin-top: 30px;padding: 15px;background-color: #f5f5f5;border-radius: 8px;
}.result-section h3 {margin-bottom: 10px;color: #666;
}.result-section p {color: #333;font-size: 16px;
}

vue3 vant4

HTML TS?

<template><div class="date-cascader-container"><!-- 添加激活按鈕觸發顯示 --><van-button @click="show = true">選擇時間</van-button><van-popup v-model:show="show" round position="bottom"><van-cascaderv-model:selected-values="selectedValues":options="options":title="title"@change="handleChange"@close="show = false":field-names="fieldNames"placeholder=""/></van-popup><div v-if="selectedValues.length" class="selected-result">已選擇: {{ formatSelectedResult() }}</div></div>
</template><script setup>
import { ref, computed, watch, onMounted } from 'vue';// 先定義show變量
const show = ref(false);
// 選中的值
const selectedValues = ref([]);// 配置級聯選擇的字段名
const fieldNames = {text: 'label',value: 'value',children: 'children'
};// 組件參數
const props = defineProps({title: {type: String,default: '選擇時間'},// 起始年份,默認從當前年往前5年startYear: {type: Number,default: new Date().getFullYear() - 5},// 結束年份,默認從當前年往后5年endYear: {type: Number,default: new Date().getFullYear() + 5}
});// 生成級聯選擇的選項
const options = computed(() => {const yearOptions = [];// 生成年份選項for (let year = props.startYear; year <= props.endYear; year++) {const quarterOptions = [];// 生成季度選項for (let quarter = 1; quarter <= 4; quarter++) {const quarterObj = {label: `${year}年第${quarter}季度`,value: `${year}-Q${quarter}`// 移除默認children屬性,避免空選項};// 判斷是否需要生成月份選項// 規則:2025年9月及之前需要月份,之后不需要if (year < 2025) {// 2025年之前,所有季度都需要月份quarterObj.children = getMonthsByQuarter(quarter);} else if (year === 2025) {// 2025年,只有前3季度需要月份if (quarter <= 3) {quarterObj.children = getMonthsByQuarter(quarter);}}// 2025年之后的年份,不生成月份選項quarterOptions.push(quarterObj);}yearOptions.push({label: `${year}年`,value: year.toString(),children: quarterOptions});}return yearOptions;
});// 根據季度獲取對應的月份
function getMonthsByQuarter(quarter) {const months = [];let startMonth, endMonth;switch (quarter) {case 1:startMonth = 1;endMonth = 3;break;case 2:startMonth = 4;endMonth = 6;break;case 3:startMonth = 7;endMonth = 9;break;case 4:startMonth = 10;endMonth = 12;break;default:return [];}for (let month = startMonth; month <= endMonth; month++) {months.push({label: `${month}月`,value: month.toString()});}return months;
}// 處理選擇變化 - 只在選擇完最后一級選項時關閉
const handleChange = ({ selectedValues, selectedOptions }) => {console.log('選擇變化:', selectedValues, selectedOptions);// 如果沒有選擇值,不處理if (!selectedOptions || selectedOptions.length === 0) return;// 獲取當前選中的年份const selectedYear = parseInt(selectedOptions[0].value);// 檢查是否已經選擇到最后一級if (selectedOptions.length === 2) {// 情況1: 如果是2025年之后或2025年第4季度,選擇完季度就關閉const quarter = parseInt(selectedOptions[1].value.split('-Q')[1]);if (selectedYear > 2025 || (selectedYear === 2025 && quarter === 4)) {show.value = false;}// 其他情況:選擇完季度后繼續選擇月份,不關閉} else if (selectedOptions.length === 3) {// 情況2: 選擇完月份后關閉show.value = false;}
};// 格式化選中的結果
const formatSelectedResult = () => {if (selectedValues.value.length === 0) return '';let result = '';// 年份result += `${selectedValues.value[0]}年`;// 季度if (selectedValues.value.length >= 2) {const quarter = selectedValues.value[1].split('-Q')[1];result += `第${quarter}季度`;}// 月份if (selectedValues.value.length === 3) {result += `${selectedValues.value[2]}月`;}return result;
};// 暴露選中的值
const emits = defineEmits(['update:modelValue']);
watch(selectedValues, (newVal) => {emits('update:modelValue', newVal);
});// 生命周期鉤子:設置默認選中最后一項
onMounted(() => {try {if (options.value.length > 0) {const lastYear = options.value[options.value.length - 1];if (lastYear.children && lastYear.children.length > 0) {const lastQuarter = lastYear.children[lastYear.children.length - 1];const selected = [lastYear.value,lastQuarter.value];// 如果有月份選項,也選中最后一個if (lastQuarter.children && lastQuarter.children.length > 0) {selected.push(lastQuarter.children[lastQuarter.children.length - 1].value);}selectedValues.value = selected;}}} catch (error) {console.error('設置默認選中項失敗:', error);}
});
</script><style scoped>
.date-cascader-container {margin: 20px;min-height: 200px; /* 確保容器有足夠高度 */
}
</style>

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

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

相關文章

day1———Qt———應用程序界面設置

1&#xff0c;定義一個Mystring類代替string的功能#include <iostream> #include <string.h>using namespace std; class Mystring {friend ostream &operator<<(ostream &cout,const Mystring &s);friend istream &operator>>(istrea…

apache實現LAMP+apache(URL重定向)

1.apache實現LAMPLAMP是指一組通常一起使用來運行動態網站的自由軟件名稱首字母的縮寫a.L是指Linux操作系統b,.A是指Apache&#xff0c;用來提供Web服務c.M指MySQL&#xff0c;用來提供數據庫服務d.P指PHP&#xff0c;是動態網站的一種開發語言1.1php運行方式說明php是腳本語言…

SAConv可切換空洞卷積

SAConv可切換空洞卷積 帶來的改進機制時可切換的空洞卷積 是一種創新型卷積網絡 專門為增強物體檢測和分割任務&#xff0c;中特征提取去設計 SAC核心時相同的輸入兒子應用到不同空洞率去進行卷積&#xff0c;設計特別開關函數融合這些不同卷積的成果 該方法可讓網絡更靈活的適…

基于Matlab的霧霾天氣和夜間車牌識別系統

在復雜天氣和低光照環境下&#xff0c;車牌識別系統的準確率和穩定性顯著下降&#xff0c;嚴重影響交通管理與智能監控的可靠性。本文針對霧霾天氣和夜間環境下車牌圖像特征模糊、對比度低、噪聲干擾嚴重的問題&#xff0c;提出了一種融合圖像增強與模板匹配的車牌識別方法。系…

華為云/本地化部署K8S-查看容器日志

華為云日志查看 目前工作的大部分情況下&#xff0c;通過華為云LTS云日志服務就可以滿足日常需求。 不過上線時過來支援的開發老哥更習慣于從容器里查看日志&#xff0c;也一并記錄下以備不時之需。 1.登錄服務節點服務器 點擊左側三個橫線&#xff0c;選擇 應用服務-云容器引擎…

【MySQL 死鎖:從 “業務卡頓“ 到 “根因定位“ 的實戰指南】

MySQL 死鎖&#xff1a;從 “業務卡頓” 到 “根因定位” 的實戰指南 后端開發必看&#xff1a;MySQL死鎖排查與預防全攻略線上系統突然報出Deadlock found when trying to get lock; try restarting transaction&#xff0c;用戶操作卡頓甚至超時&#xff0c;排查時卻對著一堆…

從虛擬化基石到云原生架構的降維打擊:用dd/mkfs玩轉namespace隔離,解鎖Docker/K8S資源密碼,看透物理機到云服務器的進化之路

本篇摘要 本文圍繞虛擬化與容器化技術展開&#xff0c;涵蓋架構演進、Docker/K8S優勢與挑戰、namespace隔離實操&#xff08;如主機名/PID隔離&#xff09;、磁盤操作&#xff08;dd/mkfs/df/mount&#xff09;等&#xff0c;對比虛擬機與容器差異&#xff0c;闡明技術原理與架…

自動化測試的概念

文章目錄自動化測試能夠取代人工測試嗎&#xff1f;回歸測試自動化分類自動化測試金字塔為啥單元測試的性價比這么高呢&#xff1f;那為啥UI自動化測試的性價比沒有組件測試的高呢&#xff1f;web自動化測試舉例引入自動化測試的準備工作自動化測試的簡單示例自動化測試能夠取代…

OSPF故障排查實戰:如何通過一條命令精準定位網絡掩碼不匹配問題

掌握display ospf error命令的解讀技巧&#xff0c;快速解決OSPF鄰接關系建立失敗難題。一、問題背景與場景引入 在網絡運維工作中&#xff0c;OSPF&#xff08;開放最短路徑優先&#xff09;協議作為主流的內部網關協議&#xff0c;其穩定運行至關重要。然而&#xff0c;在實際…

Redis----如何引入分布式鎖

一、概述首先引入分布式鎖指的是應用程序引入&#xff0c;不是Redis本身引入&#xff0c;Redis作為中間件可以作為分布式鎖的一個典型實現方案&#xff0c;同時也有一些其他的實現方案。分布式鎖指的是一個/組程序&#xff0c;使用Redis實現的話就是通過添加一個特殊的Key-Valu…

prometheus-2.42.0.linux-amd64.tar.gz 安裝配置展示

一、prometheus 1.1解壓文件 # tar -xzvf prometheus-2.42.0.linux-amd64.tar.gz -C ~/apps/ prometheus-2.42.0.linux-amd64/ prometheus-2.42.0.linux-amd64/NOTICE prometheus-2.42.0.linux-amd64/consoles/ prometheus-2.42.0.linux-amd64/consoles/index.html.example p…

Linux 標準輸入 標準輸出 標準錯誤

目錄一. 簡介二. 常見用法2.1 輸出重定向2.2 錯誤重定向2.3 同時重定向標準輸出 錯誤2.4 輸入重定向2.5 特殊設備三. 這樣設計的好處3.1 區分正常信息和錯誤信息3.2 方便調用方腳本處理3.3 與管道結合時更清晰四. 案例4.1 if判斷4.2 ls查詢一. 簡介 ?在 Linux/Unix 中&#…

零基礎新手小白快速了解掌握服務集群與自動化運維(二)Linux Journalctl命令、Journalctl日志持久化存儲

Linux提供了一個強大的日志系統&#xff0c;它可以跟蹤和記錄系統的各種活動。在這個系統中&#xff0c;journalctl是一個非常重要的工具&#xff0c;用于查詢和操作由systemd進程管理的日志。 本文將深入探討journalctl命令&#xff0c;介紹其基本使用、高級選項及示例等內容…

【學習】【js】棧數據結構

棧 棧是一種遵從后進先出&#xff08;LIFO&#xff09;原則的有序集合。新添加或待刪除的元素都保存在棧的同一端&#xff0c;稱作棧頂&#xff0c;另一端就叫棧底。在棧里&#xff0c;新元素都靠近棧頂&#xff0c;舊元素都接近棧底。 基于數組的棧 時間復雜度O(n),占用較多的…

【Linux】基本指令 · 下

alias 指令起別名為什么 ls -l 指令等價于 ll 指令呢&#xff1f;指令就是可執行程序&#xff0c;和我們自己寫的代碼編譯好的程序&#xff0c;沒有本質區別&#xff01; 指令在系統的某一個位置存在&#xff01; 執行指令前&#xff0c;現在系統中查找對應的指令指令在根目錄下…

計算機視覺(opencv)實戰二十二——指紋圖像中提取特征點,計算兩兩指紋之間的相似度

指紋識別原理與代碼實現詳解指紋識別是一種常見的生物特征識別技術&#xff0c;廣泛應用于門禁系統、手機解鎖、考勤打卡、身份認證等場景。其核心思想是&#xff1a;從指紋圖像中提取特征點&#xff0c;計算兩幅指紋之間的相似度&#xff0c;并根據相似度判斷是否為同一人。本…

Linux基礎之部署mysql數據庫

文章目錄一、環境準備二、源碼解壓與依賴三、CMake 編譯配置四、配置 MySQL權限管理修改配置文件 /etc/my.cnf五、環境變量設置六、數據庫初始化七、服務管理八、賬號密碼管理一、環境準備 yum -y install gcc gcc-c ncurses ncurses-devel bison cmakegcc / gcc-c&#xff1a…

代碼審計-PHP專題原生開發文件上傳刪除包含文件操作監控Zend源碼解密1day分析

快速分析脆弱&#xff1a;1、看文件路徑2、看代碼里面的變量&#xff08;可控&#xff09;3、看變量前后的過濾文件安全挖掘點&#xff1a;1、腳本文件名2、應用功能點3、操作關鍵字文件上傳&#xff0c;文件下載(讀取)&#xff0c;文件包含&#xff0c;文件刪除等emlog-文件上…

零基礎搭建 Hexo 博客:從本地到 GitHub Pages 全流程指南

零基礎搭建 Hexo 博客&#xff1a;從本地到 GitHub Pages 全流程指南 Hexo 是一個快速、簡潔且高效的博客框架&#xff0c;支持使用 Markdown 來編寫文章&#xff0c;并能快速生成靜態網頁&#xff0c;非常適合想要搭建個人博客的同學。本文將帶你從零開始&#xff0c;本地搭建…

Git 簡介

Git 是目前全球最流行的分布式版本控制系統&#xff08;Distributed Version Control System, DVCS&#xff09;&#xff0c;核心作用是追蹤文件修改歷史、支持多人協同開發&#xff0c;并能高效管理代碼&#xff08;或任何文本類文件&#xff09;的版本迭代。它由 Linux 內核創…