组件pages/components/sg-hour-range.vue
<template>
<ul>
<li
v-for="(item, $index) in hours"
:key="$index"
@click="click(item)"
:disabled="disableHours.includes(item)"
:active="active(item)"
:startAndEndOk="startAndEndOk(item, $index)"
>
{{ item }}
</li>
</ul>
</template>
<script>
export default {
model: {
prop: 'hourRange',
event: 'change'
},
props: {
hourRange: {
type: Object,
default: () => {}
},
disableHours: {
type: Array,
default: () => []
},
tip: {
type: String,
default: '请选择正确的时间范围!'
},
hours: {
type: Array,
default: () => []
}
},
data() {
return {};
},
created() {
this.__valid() && this.__resetHourRange();
},
methods: {
active(item) {
if (!this.hourRange) return false;
if (this.hourRange.start == item) return 'start';
if (this.hourRange.start < item && this.hourRange.end > item) return 'mid';
if (this.hourRange.end == item) return 'end';
return false;
},
__resetHourRange() {
(this.hourRange.start = null), (this.hourRange.end = null);
},
__valid() {
var arr = this.disableHours;
for (var i = 0, len = arr.length; i < len; i++) {
var a = arr[i];
if (this.hourRange.start <= a && a <= this.hourRange.end) return true;
}
},
startAndEndOk(item, $index) {
if (this.hourRange.end == this.hourRange.start) return false;
if (parseInt(this.hourRange.end) - parseInt(this.hourRange.start) === 1 || $index % 4 === 0 || $index % 5 === 0) {
if (this.hourRange.end && this.hourRange.start == item) return true;
if (this.hourRange.end == item) return true;
}
},
click(item) {
if (this.hourRange.start && this.hourRange.end) {
this.hourRange.start = item;
this.hourRange.end = null;
} else if (this.hourRange.start) {
if (item < this.hourRange.start) {
this.hourRange.end = this.hourRange.start;
this.hourRange.start = item;
} else if (item == this.hourRange.start) {
this.hourRange.start = null;
this.hourRange.end = null;
} else if (item == this.hourRange.end) {
this.hourRange.start = null;
this.hourRange.end = null;
} else {
this.hourRange.end = item;
}
} else {
this.hourRange.start = item;
}
if (this.hourRange.start && this.hourRange.end && this.__valid()) {
alert(this.tip);
this.__resetHourRange();
}
this.$emit('change', this.hourRange);
}
}
};
</script>
<style lang="scss" scoped>
$size: calc(100vw / 8);
$size2: calc(100vw / 8 + 2px);
$margin: calc(100vw / 8 / 2);
$margin2: calc(100vw / 8 / 3);
$default-color: #3a3a3a;
ul {
display: flex;
flex-wrap: wrap;
padding: 0;
margin: 0;
li {
font-family: 'Arial';
margin: 0 0 $margin2 $margin;
font-size: 16px;
color: $default-color;
width: $size;
height: $size;
border-radius: $size;
line-height: $size;
list-style: none;
text-align: center;
border: 1px solid $default-color;
box-sizing: border-box;
&[disabled] {
color: #9c9c9c;
border-color: #d3d3d3;
background-color: #f4f4f4;
pointer-events: none;
}
&[active='start'],
&[active='end'] {
position: relative;
background-color: #34c3eb;
color: white;
font-weight: bold;
border: none;
box-sizing: initial;
}
&[active='start'][startAndEndOk]::after,
&[active='end'][startAndEndOk]::before,
&[active='mid']::before,
&[active='mid']::after {
content: '';
/*父元素需要position: relative;*/
position: absolute;
margin: auto;
right: -100%;
z-index: -1;
width: $size;
height: $size;
background-color: #e0f5fc;
}
&[active='start'][startAndEndOk]::after {
right: -50%;
}
&[active='end'][startAndEndOk]::before {
right: 50%;
}
&[active='mid'] {
position: relative;
background-color: #e0f5fc;
color: #34c3eb;
font-weight: bold;
border-radius: 0;
border: none;
box-sizing: initial;
line-height: $size2;
}
&[active='mid']::before {
right: 100%;
}
}
}
</style>
pages/index/index.vue引用
<template>
<view class="content">
<center><p>场馆预约の小时范围控件</p></center>
<center><a href="static/sg-hour-range.zip">点击下载此控件(请务必PC下载)</a></center>
<br />
<br />
<sg-hour-range :hours="hours" :disableHours="disableHours" :tip="tip" v-model="hourRange" @change="changeHourRange"></sg-hour-range>
</view>
</template>
<script>
import sgHourRange from '../components/sg-hour-range'; //引入舒工自定义时间范围组件(v1.0-2020.04.07)
export default {
components: {
'sg-hour-range': sgHourRange //自定义组件别名定义
},
data() {
return {
hours: [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], //可预约的时段
disableHours: [7, 10], //屏蔽选择时间
tip:"亲!您选择的预约区间中包含了预约满额的时段!",//提示文字
hourRange: { start: 12, end: 15 } //这个是双向绑定范围值(默认选中13到15)
// hourRange: { start: null, end: null } //这个是双向绑定范围值(没有默认选中范围)
};
},
methods: {
changeHourRange(value) {
console.log('这个是你们想要的时间范围(回调返回值):', value);
console.log('这个是你们想要的时间范围(双向绑定值):', this.hourRange);
}
}
};
</script>