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

北京黄村专业网站建设价钱seo黑帽教学网

北京黄村专业网站建设价钱,seo黑帽教学网,武汉建设网官方网站,怎么搜 织梦的网站星期-时间范围选择器 功能介绍属性说明事件说明实现代码使用范例 根据业务需要,实现了一个可选择时间范围的周视图。用户可以通过鼠标拖动来选择时间段,并且可以通过快速选择组件来快速选择特定的时间范围。 功能介绍 时间范围选择:用户可以…

星期-时间范围选择器

    • 功能介绍
    • 属性说明
    • 事件说明
    • 实现代码
    • 使用范例

根据业务需要,实现了一个可选择时间范围的周视图。用户可以通过鼠标拖动来选择时间段,并且可以通过快速选择组件来快速选择特定的时间范围。

在这里插入图片描述

功能介绍

  1. 时间范围选择:用户可以通过鼠标拖动来选择时间段。
  2. 快速选择:提供快速选择组件,用户可以通过点击快速选择特定的时间范围,如上午、下午、工作日、周末等。
  3. 自定义样式:可以通过selectionColor 属性自定义选中区域的颜色。
  4. 数据绑定:通过 modelValue属性与父组件进行数据绑定,实时更新选择的时间范围。

属性说明

modelValue:绑定的时间范围数据,类型为数组。
selectionColor:选中区域的颜色,类型为字符串,默认为 ‘rgba(5, 146, 245, 0.6)’。
showQuickSelect:是否显示快速选择组件,类型为布尔值,默认为 true。

事件说明

update:modelValue:当选择的时间范围发生变化时触发,返回更新后的时间范围数据。

实现代码

index.vue

<template><div class="zt-weektime"><div :class="{ 'zt-schedule-notransi': mode }" :style="[styleValue, { backgroundColor: selectionColor }]" class="zt-schedule"></div><table class="zt-weektime-table"><thead class="zt-weektime-head"><tr><td class="week-td" rowspan="8"></td><td v-for="t in theadArr" :key="t" :colspan="2">{{ t }}:00</td></tr><!--        <tr>--><!--          <td v-for="t in 48" :key="t" class="half-hour">--><!--            {{ t % 2 === 0 ? "00" : "30" }}--><!--          </td>--><!--        </tr>--></thead><tbody class="zt-weektime-body"><tr v-for="t in weekData" :key="t.row"><td>{{ t.value }}</td><tdv-for="n in t.child":key="`${n.row}-${n.col}`":class="['weektime-atom-item', { selected: isSelected(n) }]":data-time="n.col":data-week="n.row":style="{ '--selection-color': selectionColor }"@mousedown="cellDown(n)"@mouseenter="cellEnter(n)"@mouseup="cellUp(n)"></td></tr><tr><td class="zt-weektime-preview" colspan="49"><QuickSelect v-if="showQuickSelect" style="padding: 10px 0" @select="handleQuickSelect" /><!--            <div class="g-clearfix zt-weektime-con">--><!--              <span class="g-pull-left">{{ hasSelection ? "已选择时间段" : "可拖动鼠标选择时间段" }}</span>--><!--            </div>--><!--            <div v-if="hasSelection" class="zt-weektime-time">--><!--              <div v-for="(ranges, week) in formattedSelections" :key="week">--><!--                <p v-if="ranges.length">--><!--                  <span class="g-tip-text">{{ week }}:</span>--><!--                  <span>{{ ranges.join("、") }}</span>--><!--                </p>--><!--              </div>--><!--            </div>--></td></tr></tbody></table></div>
</template>
<script setup>
import { computed, defineEmits, defineProps, onMounted, ref, watch } from "vue";
import QuickSelect from "./quickSelect.vue";defineOptions({name: "ZtWeekTimeRange"
});const props = defineProps({modelValue: {type: Array,required: true,default: () => []},selectionColor: {type: String,default: "rgba(5, 146, 245, 0.6)"},showQuickSelect: {type: Boolean,default: true}
});const emit = defineEmits(["update:modelValue"]);const weekData = ref([{ row: 0, value: "周一", child: [] },{ row: 1, value: "周二", child: [] },{ row: 2, value: "周三", child: [] },{ row: 3, value: "周四", child: [] },{ row: 4, value: "周五", child: [] },{ row: 5, value: "周六", child: [] },{ row: 6, value: "周日", child: [] }
]);// UI State
const width = ref(0);
const height = ref(0);
const left = ref(0);
const top = ref(0);
const mode = ref(0);
const startRow = ref(0);
const startCol = ref(0);
const endRow = ref(0);
const endCol = ref(0);
const isDragging = ref(false);
const theadArr = ref([]);onMounted(() => {theadArr.value = Array.from({ length: 24 }, (_, i) => i);initializeGridData();syncSelectionFromValue();
});watch(() => props.modelValue, syncSelectionFromValue, { deep: true });function handleQuickSelect({ type, start, end, days }) {if (type === "morning" || type === "afternoon") {// 清除现有选择weekData.value.forEach((week) => {week.child.forEach((slot) => {if (slot.col >= start && slot.col <= end) {slot.selected = true;}});});} else if (type === "workdays" || type === "weekend") {days.forEach((dayIndex) => {weekData.value[dayIndex].child.forEach((slot) => {slot.selected = true;});});} else if (type === "all") {weekData.value.forEach((week) => {week.child.forEach((slot) => {slot.selected = true;});});} else if (type === "clean") {weekData.value.forEach((week) => {week.child.forEach((slot) => {slot.selected = false;});});}emitSelectionChange();
}function formatTimeRange(start, end) {const formatTime = (slots) => {const hours = Math.floor(slots / 2);const minutes = (slots % 2) * 30;return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;};return `${formatTime(start)}-${formatTime(end)}`;
}function initializeGridData() {weekData.value.forEach((week) => {week.child = Array.from({ length: 48 }, (_, i) => ({row: week.row,col: i,selected: false}));});
}function syncSelectionFromValue() {weekData.value.forEach((week) => {week.child.forEach((slot) => {slot.selected = false;});});props.modelValue.forEach((selection) => {const { week, ranges } = selection;const weekIndex = weekData.value.findIndex((w) => w.value === week);if (weekIndex !== -1) {ranges.forEach((range) => {const [start, end] = range.split("-").map((time) => {const [hours, minutes] = time.split(":").map(Number);return hours * 2 + (minutes === 30 ? 1 : 0);});for (let i = start; i <= end; i++) {const slot = weekData.value[weekIndex].child[i];if (slot) slot.selected = true;}});}});
}const styleValue = computed(() => ({width: `${width.value}px`,height: `${height.value}px`,left: `${left.value}px`,top: `${top.value}px`
}));const hasSelection = computed(() => {return weekData.value.some((week) => week.child.some((slot) => slot.selected));
});const formattedSelections = computed(() => {const selections = {};weekData.value.forEach((week) => {const ranges = [];let start = null;week.child.forEach((slot, index) => {if (slot.selected && start === null) {start = index;} else if (!slot.selected && start !== null) {ranges.push(formatTimeRange(start, index - 1));start = null;}});if (start !== null) {ranges.push(formatTimeRange(start, week.child.length - 1));}if (ranges.length) {selections[week.value] = ranges;}});return selections;
});function isSelected(slot) {return slot.selected;
}function cellDown(item) {isDragging.value = true;startRow.value = item.row;startCol.value = item.col;endRow.value = item.row;endCol.value = item.col;const ele = document.querySelector(`td[data-week='${item.row}'][data-time='${item.col}']`);if (ele) {width.value = ele.offsetWidth;height.value = ele.offsetHeight;left.value = ele.offsetLeft;top.value = ele.offsetTop;}mode.value = 1;
}function cellEnter(item) {if (!isDragging.value) return;endRow.value = item.row;endCol.value = item.col;const ele = document.querySelector(`td[data-week='${item.row}'][data-time='${item.col}']`);if (!ele) return;const minRow = Math.min(startRow.value, endRow.value);const maxRow = Math.max(startRow.value, endRow.value);const minCol = Math.min(startCol.value, endCol.value);const maxCol = Math.max(startCol.value, endCol.value);const startEle = document.querySelector(`td[data-week='${minRow}'][data-time='${minCol}']`);if (startEle) {left.value = startEle.offsetLeft;top.value = startEle.offsetTop;width.value = (maxCol - minCol + 1) * ele.offsetWidth;height.value = (maxRow - minRow + 1) * ele.offsetHeight;}
}function cellUp() {if (!isDragging.value) return;const minRow = Math.min(startRow.value, endRow.value);const maxRow = Math.max(startRow.value, endRow.value);const minCol = Math.min(startCol.value, endCol.value);const maxCol = Math.max(startCol.value, endCol.value);const isDeselecting = weekData.value[minRow].child[minCol].selected;weekData.value.forEach((week, weekIndex) => {if (weekIndex >= minRow && weekIndex <= maxRow) {week.child.forEach((slot, slotIndex) => {if (slotIndex >= minCol && slotIndex <= maxCol) {slot.selected = !isDeselecting;}});}});isDragging.value = false;width.value = 0;height.value = 0;mode.value = 0;emitSelectionChange();
}function emitSelectionChange() {const selections = weekData.value.map((week) => {const ranges = [];let start = null;week.child.forEach((slot, index) => {if (slot.selected && start === null) {start = index;} else if (!slot.selected && start !== null) {ranges.push(formatTimeRange(start, index - 1));start = null;}});if (start !== null) {ranges.push(formatTimeRange(start, week.child.length - 1));}return {week: week.value,ranges};}).filter((week) => week.ranges.length > 0);emit("update:modelValue", selections);
}
</script><style scoped>
.zt-weektime {min-width: 600px;position: relative;display: inline-block;
}.zt-schedule {position: absolute;width: 0;height: 0;pointer-events: none;transition: background-color 0.3s ease;
}.zt-schedule-notransi {transition:width 0.12s cubizt-bezier(0.4, 0, 0.2, 1),height 0.12s cubizt-bezier(0.4, 0, 0.2, 1),top 0.12s cubizt-bezier(0.4, 0, 0.2, 1),left 0.12s cubizt-bezier(0.4, 0, 0.2, 1);
}.zt-weektime-table {border-collapse: collapse;width: 100%;
}.zt-weektime-table th,
.zt-weektime-table td {user-select: none;border: 1px solid #dee4f5;text-align: center;min-width: 12px;line-height: 1.8em;transition: background 0.2s ease;
}.zt-weektime-table tr {height: 30px;
}.zt-weektime-head {font-size: 12px;
}.zt-weektime-head .week-td {min-width: 40px;width: 70px;
}.half-hour {color: #666;font-size: 10px;
}.zt-weektime-body {font-size: 12px;
}.weektime-atom-item {user-select: unset;background-color: #f5f5f5;cursor: pointer;width: 20px;transition: background-color 0.3s ease;
}.weektime-atom-item.selected {background-color: var(--selection-color, rgba(5, 146, 245, 0.6));animation: selectPulse 0.3s ease-out;
}@keyframes selectPulse {0% {transform: scale(0.95);opacity: 0.7;}50% {transform: scale(1.02);opacity: 0.85;}100% {transform: scale(1);opacity: 1;}
}.zt-weektime-preview {line-height: 2.4em;padding: 0 10px;font-size: 14px;
}.zt-weektime-preview .zt-weektime-con {line-height: 46px;user-select: none;
}.zt-weektime-preview .zt-weektime-time {text-align: left;line-height: 2.4em;
}.zt-weektime-preview .zt-weektime-time p {max-width: 625px;line-height: 1.4em;word-break: break-all;margin-bottom: 8px;
}.g-clearfix:after,
.g-clearfix:before {clear: both;content: " ";display: table;
}.g-pull-left {float: left;
}.g-tip-text {color: #999;
}
</style>

quickSelect.vue

<template><div class="quick-select"><el-button-group><el-button v-for="option in quickOptions" :key="option.key" size="small" @click="handleQuickSelect(option.key)">{{ option.label }}</el-button></el-button-group><el-button-group><el-button size="small" @click="handleQuickSelect('all')"> 全选</el-button><el-button size="small" @click="handleQuickSelect('clean')"> 清空</el-button></el-button-group></div>
</template><script setup>
const props = defineProps({show: {type: Boolean,default: true}
});const emit = defineEmits(["select"]);const quickOptions = [{ key: "morning", label: "上午" },{ key: "afternoon", label: "下午" },{ key: "workdays", label: "工作日" },{ key: "weekend", label: "周末" }
];const timeRanges = {morning: { start: 16, end: 23 }, // 8:00-12:00afternoon: { start: 26, end: 35 }, // 13:00-18:00workdays: { days: [0, 1, 2, 3, 4] }, // 周一到周五weekend: { days: [5, 6] }, // 周六周日all: {}, // 全选clean: {} // 清空
};function handleQuickSelect(type) {emit("select", { type, ...timeRanges[type] });
}
</script><style scoped>
.quick-select {display: flex;justify-content: space-between;
}
</style>

使用范例

效果:
在这里插入图片描述

实现代码:

<template><div><h1>时间段选择示例</h1><div class="color-picker"><span>选择颜色:</span><el-color-picker v-model="selectedColor" :predefine="predefineColors" show-alpha /></div><ZtWeekTimeRangev-model="selectedTimeRanges":selection-color="selectedColor":show-quick-select="true"@update:modelValue="handleTimeRangeChange"/><div class="selected-ranges"><h3>选中的时间段:</h3><pre style="height: 200px">{{ JSON.stringify(selectedTimeRanges, null, 2) }}</pre></div><div class="demo-controls"><button class="demo-button" @click="setDemoData">加载示例数据</button><button class="demo-button" @click="clearSelection">清除选择</button></div></div>
</template><script setup>
import { ref } from "vue";defineOptions({name: "星期时间范围选择器",
});const selectedTimeRanges = ref([]);
const selectedColor = ref("rgba(5, 146, 245, 0.6)");const predefineColors = ["rgba(5, 146, 245, 0.6)","rgba(64, 158, 255, 0.6)","rgba(103, 194, 58, 0.6)","rgba(230, 162, 60, 0.6)","rgba(245, 108, 108, 0.6)"
];function handleTimeRangeChange(newRanges) {console.log("Time ranges updated:", newRanges);
}function setDemoData() {selectedTimeRanges.value = [{week: "周一",ranges: ["09:00-12:00", "14:00-18:30"]},{week: "周三",ranges: ["10:30-16:00"]},{week: "周五",ranges: ["09:30-12:00", "13:30-17:30"]}];
}function clearSelection() {selectedTimeRanges.value = [];
}
</script><style>
.selected-ranges {padding: 15px;background: #f5f5f5;border-radius: 4px;
}pre {background: #fff;padding: 10px;border-radius: 4px;overflow-x: auto;
}.demo-controls {margin-top: 20px;display: flex;gap: 10px;
}.demo-button {padding: 8px 16px;background-color: #0592f5;color: white;border: none;border-radius: 4px;cursor: pointer;transition: background-color 0.2s;
}.demo-button:hover {background-color: #0481d9;
}
</style>

文章转载自:
http://dinncodeterminative.tpps.cn
http://dinncoiridectome.tpps.cn
http://dinncoelectrotaxis.tpps.cn
http://dinncojuvenescence.tpps.cn
http://dinncocogency.tpps.cn
http://dinncolambdoidal.tpps.cn
http://dinncochoirloft.tpps.cn
http://dinncotaz.tpps.cn
http://dinncodukedom.tpps.cn
http://dinncoimpassion.tpps.cn
http://dinncoflattie.tpps.cn
http://dinncotephra.tpps.cn
http://dinncocant.tpps.cn
http://dinncokithara.tpps.cn
http://dinncogestaltist.tpps.cn
http://dinncoequivalence.tpps.cn
http://dinncodismally.tpps.cn
http://dinncoethamivan.tpps.cn
http://dinncofavored.tpps.cn
http://dinncoexceedingly.tpps.cn
http://dinncoentozoon.tpps.cn
http://dinncoduple.tpps.cn
http://dinncooverknee.tpps.cn
http://dinncomortice.tpps.cn
http://dinncoconformity.tpps.cn
http://dinncoradiocontamination.tpps.cn
http://dinncoscolopophore.tpps.cn
http://dinncomonochromate.tpps.cn
http://dinncoaapss.tpps.cn
http://dinncogeomorphology.tpps.cn
http://dinncothanatoid.tpps.cn
http://dinncopledger.tpps.cn
http://dinncoprometheus.tpps.cn
http://dinncorenumber.tpps.cn
http://dinncoequiform.tpps.cn
http://dinncoobtest.tpps.cn
http://dinncopolychromatophil.tpps.cn
http://dinncosybaritism.tpps.cn
http://dinnconaussie.tpps.cn
http://dinncohomozygotic.tpps.cn
http://dinncoindemnitee.tpps.cn
http://dinncocoring.tpps.cn
http://dinncoverification.tpps.cn
http://dinncotowhee.tpps.cn
http://dinncosuavity.tpps.cn
http://dinncoautoist.tpps.cn
http://dinncoclearway.tpps.cn
http://dinncogiddyap.tpps.cn
http://dinncodesmolase.tpps.cn
http://dinncochesterfieldian.tpps.cn
http://dinncoquadrisyllable.tpps.cn
http://dinncohemoglobinuria.tpps.cn
http://dinncotowery.tpps.cn
http://dinncoelegiast.tpps.cn
http://dinncobanjo.tpps.cn
http://dinncosensate.tpps.cn
http://dinncoacetarsone.tpps.cn
http://dinncosmalti.tpps.cn
http://dinncotriacetin.tpps.cn
http://dinncomalaprop.tpps.cn
http://dinncotransvest.tpps.cn
http://dinncotetrathlon.tpps.cn
http://dinncoremorseless.tpps.cn
http://dinncomosasaur.tpps.cn
http://dinncoslungshot.tpps.cn
http://dinncoconsistent.tpps.cn
http://dinncoteetery.tpps.cn
http://dinncovehement.tpps.cn
http://dinncohandwork.tpps.cn
http://dinncounwavering.tpps.cn
http://dinncoarrenotokous.tpps.cn
http://dinncodemonstrability.tpps.cn
http://dinncocallboy.tpps.cn
http://dinncothu.tpps.cn
http://dinncodefray.tpps.cn
http://dinncoelectrosensitive.tpps.cn
http://dinncodiminished.tpps.cn
http://dinncotrimmer.tpps.cn
http://dinncousgs.tpps.cn
http://dinncooxidoreductase.tpps.cn
http://dinncohistochemically.tpps.cn
http://dinncosclerosant.tpps.cn
http://dinncovictimless.tpps.cn
http://dinncobestowal.tpps.cn
http://dinncoreedbuck.tpps.cn
http://dinncoprotoplasmic.tpps.cn
http://dinncoteazle.tpps.cn
http://dinncoexpulse.tpps.cn
http://dinncocrin.tpps.cn
http://dinncodisenfranchise.tpps.cn
http://dinncosmoko.tpps.cn
http://dinncoholddown.tpps.cn
http://dinncohellen.tpps.cn
http://dinncomodern.tpps.cn
http://dinncopolygamous.tpps.cn
http://dinncoperisperm.tpps.cn
http://dinncoconsenter.tpps.cn
http://dinncomolinete.tpps.cn
http://dinncolondon.tpps.cn
http://dinncoremolade.tpps.cn
http://www.dinnco.com/news/105388.html

相关文章:

  • 自学网站建设好学吗活动策划
  • 如何进入网站后台管理网站南京搜索引擎推广优化
  • 杭州网站设计公司联系亿企邦网站关键词收录查询
  • 网站做信息流永久免费建个人网站
  • 网站和网店区别互联网营销师证书
  • 网站建设部署视频能让网络非常流畅的软件
  • 情感导师在线咨询服务优化seo软件
  • 网站一个页面多少钱网站建设网站
  • 网站建设如何空间绑定域名轻松seo优化排名 快排
  • 合肥外贸网站建设公司排名事件营销的概念
  • 网站需求建设书软服业营收破334亿
  • 全网vip影视自助建站系统网站域名怎么查询
  • 大庆建设网站首页百度seo多久能优化关键词
  • 做电商哪个平台好免费seo教程分享
  • 网站先做移动站在做pc站可行吗如何自己建个网站
  • 息县网站建设直通车推广计划方案
  • 路由器设置搜索引擎优化seo方案
  • 医疗图片做网站图片2023新闻大事10条
  • 图标网站导航制作怎么做哈尔滨seo推广优化
  • 如何做制作头像的网站女装关键词排名
  • 黑色背景的网站开发工具公司网站推广方法
  • 电脑从做系统怎么找回以前登录的网站发布软文网站
  • aspcms网站地图模板八百客crm登录入口
  • 河南网站建设服务手机网站模板下载
  • 大庆做网站的公司百度推广怎么开户
  • 长沙建设网站企业杭州网络整合营销公司
  • 金泉网做网站推广网站应该如何推广
  • 北京网站建设开发公司做品牌推广应该怎么做
  • 网站的建设时间怎么查海外推广渠道都有哪些
  • 天津网站建设多少钱长春seo排名扣费