gunter-kgd 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,227 @@
1
+ <template>
2
+ <div class="dropdown-wrapper" :class="{ 'dropdown-disabled': disabled }">
3
+ <div
4
+ class="dropdown-trigger"
5
+ @click="toggleDropdown"
6
+ :class="{ 'dropdown-active': isOpen }"
7
+ :disabled="disabled"
8
+ >
9
+ <span class="dropdown-value">{{ selectedLabel || placeholder }}</span>
10
+ <span class="dropdown-arrow"></span>
11
+ </div>
12
+ <ul
13
+ class="dropdown-menu"
14
+ v-if="isOpen"
15
+ @click.stop="handleMenuClick"
16
+ >
17
+ <li
18
+ v-for="(option, index) in options"
19
+ :key="index"
20
+ class="dropdown-item"
21
+ :class="{ 'dropdown-item-selected': option.value === selectedValue }"
22
+ @click="selectOption(option)"
23
+ >
24
+ {{ option.label }}
25
+ </li>
26
+ </ul>
27
+ </div>
28
+ </template>
29
+
30
+ <script>
31
+ export default {
32
+ name: 'Dropdown',
33
+ props: {
34
+ // 下拉选项数组,格式: [{ label: '选项1', value: 'value1' }]
35
+ options: {
36
+ type: Array,
37
+ required: true
38
+ },
39
+ // 默认选中值
40
+ value: {
41
+ type: [String, Number],
42
+ default: ''
43
+ },
44
+ // 占位符文本
45
+ placeholder: {
46
+ type: String,
47
+ default: '请选择'
48
+ },
49
+ // 是否禁用
50
+ disabled: {
51
+ type: Boolean,
52
+ default: false
53
+ }
54
+ },
55
+ data() {
56
+ return {
57
+ isOpen: false,
58
+ selectedValue: this.value,
59
+ }
60
+ },
61
+ watch: {
62
+ // 监听外部value变化
63
+ value(newVal) {
64
+ this.selectedValue = newVal;
65
+ },
66
+ // 监听选项变化,确保选中值有效
67
+ options() {
68
+ this.validateSelectedValue();
69
+ }
70
+ },
71
+ mounted() {
72
+ // 点击外部关闭下拉框
73
+ document.addEventListener('click', this.closeDropdown);
74
+ },
75
+ beforeDestroy() {
76
+ // 移除事件监听
77
+ document.removeEventListener('click', this.closeDropdown);
78
+ },
79
+ computed: {
80
+ selectedLabel() {
81
+ const selectedOption = this.options.find(option => option.value === this.selectedValue);
82
+ return selectedOption ? selectedOption.label : this.placeholder;
83
+ }
84
+ },
85
+ methods: {
86
+ // 切换下拉框显示状态
87
+ toggleDropdown() {
88
+ if (!this.disabled) {
89
+ this.isOpen = !this.isOpen;
90
+ }
91
+ },
92
+ // 关闭下拉框
93
+ closeDropdown(e) {
94
+ if (!this.$el.contains(e.target)) {
95
+ this.isOpen = false;
96
+ }
97
+ },
98
+ // 阻止事件冒泡
99
+ handleMenuClick(e) {
100
+ e.stopPropagation();
101
+ },
102
+ // 选择选项
103
+ selectOption(option) {
104
+ this.selectedValue = option.value;
105
+ this.isOpen = false;
106
+ // 触发change事件,传递选中的选项和值
107
+ this.$emit('change', option, option.value);
108
+ this.$emit('input', option.value);
109
+ },
110
+ // 验证选中值是否在选项中存在
111
+ validateSelectedValue() {
112
+ const optionValues = this.options.map(option => option.value);
113
+ if (!optionValues.includes(this.selectedValue)) {
114
+ this.selectedValue = '';
115
+ }
116
+ }
117
+ }
118
+ }
119
+ </script>
120
+
121
+ <style lang="less" scoped>
122
+ .dropdown-wrapper {
123
+ position: relative;
124
+ display: inline-block;
125
+ font-size: 14px;
126
+ max-width: 200px;
127
+ }
128
+
129
+ .dropdown-trigger {
130
+ display: flex;
131
+ align-items: center;
132
+ justify-content: space-between;
133
+ width: 100%;
134
+ padding: 6px 10px;
135
+ border: 1px solid #dcdfe6;
136
+ border-radius: 4px;
137
+ background-color: #fff;
138
+ cursor: pointer;
139
+ transition: border-color 0.3s;
140
+ box-sizing: border-box;
141
+ user-select: none;
142
+
143
+ &:hover {
144
+ border-color: #00a578;
145
+ }
146
+
147
+ &:focus {
148
+ outline: none;
149
+ border-color: #00a578;
150
+ box-shadow: 0 0 0 2px rgba(0, 165, 120, 0.2);
151
+ }
152
+
153
+ &.dropdown-active {
154
+ border-color: #00a578;
155
+ border-radius: 4px 4px 0 0;
156
+ }
157
+ }
158
+
159
+ .dropdown-value {
160
+ overflow: hidden;
161
+ text-overflow: ellipsis;
162
+ white-space: nowrap;
163
+ }
164
+
165
+ .dropdown-arrow {
166
+ width: 0;
167
+ height: 0;
168
+ border-left: 4px solid transparent;
169
+ border-right: 4px solid transparent;
170
+ border-top: 4px solid #606266;
171
+ margin-left: 8px;
172
+ transition: transform 0.3s;
173
+
174
+ .dropdown-active & {
175
+ transform: rotate(180deg);
176
+ }
177
+ }
178
+
179
+ .dropdown-menu {
180
+ position: absolute;
181
+ top: 100%;
182
+ left: 0;
183
+ width: 100%;
184
+ margin: 0;
185
+ padding: 0;
186
+ list-style: none;
187
+ background-color: #fff;
188
+ border: 1px solid #dcdfe6;
189
+ border-radius: 0 0 4px 4px;
190
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
191
+ z-index: 10;
192
+ max-height: 200px;
193
+ overflow-y: auto;
194
+ }
195
+
196
+ .dropdown-item {
197
+ padding: 8px 12px;
198
+ cursor: pointer;
199
+ transition: background-color 0.3s;
200
+ user-select: none;
201
+
202
+ &:hover {
203
+ background-color: #f5f7fa;
204
+ }
205
+
206
+ &.dropdown-item-selected {
207
+ color: #00a578;
208
+ background-color: #00A57833;
209
+ }
210
+ }
211
+
212
+ .dropdown-disabled {
213
+ .dropdown-trigger {
214
+ cursor: not-allowed;
215
+ background-color: #f5f7fa;
216
+ color: #c0c4cc;
217
+
218
+ &:hover {
219
+ border-color: #dcdfe6;
220
+ }
221
+ }
222
+
223
+ .dropdown-arrow {
224
+ border-top-color: #c0c4cc;
225
+ }
226
+ }
227
+ </style>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <div :style="{color:color}" class="loadBox">
3
+ <div v-show="showLoading" class="gj-loading"></div>
4
+ <div style="color: #ccc" v-show="!showLoading">
5
+ <slot></slot>
6
+ </div>
7
+
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ name: "loading",
14
+ props:{
15
+ color:{
16
+ default:'#3396fb',
17
+ type:String
18
+ },
19
+ showLoading:{
20
+ default:true,
21
+ type:Boolean
22
+ }
23
+ }
24
+ }
25
+ </script>
26
+
27
+ <style scoped>
28
+ .loadBox{
29
+ height: 50px;
30
+ line-height: 50px;
31
+ text-align: center;
32
+ }
33
+ .gj-loading {
34
+ display: inline-block;
35
+ width: 15px;
36
+ height: 15px;
37
+ color: inherit;
38
+ vertical-align: middle;
39
+ pointer-events: none;
40
+ border: 2px solid currentcolor;
41
+ border-bottom-color: transparent;
42
+ border-radius: 50%;
43
+ -webkit-animation: 1s gj-loading linear infinite;
44
+ animation: 1s gj-loading linear infinite;
45
+ position: relative;
46
+ }
47
+ @-webkit-keyframes gj-loading {
48
+ 0% {
49
+ -webkit-transform: rotate(0deg);
50
+ transform: rotate(0deg);
51
+ }
52
+ 100% {
53
+ -webkit-transform: rotate(360deg);
54
+ transform: rotate(360deg);
55
+ }
56
+ }
57
+ @keyframes gj-loading {
58
+ 0% {
59
+ -webkit-transform: rotate(0deg);
60
+ transform: rotate(0deg);
61
+ }
62
+ 100% {
63
+ -webkit-transform: rotate(360deg);
64
+ transform: rotate(360deg);
65
+ }
66
+ }
67
+ </style>
@@ -0,0 +1,32 @@
1
+ export default {
2
+ data(){
3
+ return{
4
+ scrollFn: null
5
+ }
6
+ },
7
+ methods:{
8
+ autoScroll(e,scrollEl){
9
+ if(!scrollEl) return;
10
+ let scaleX = 0,sacleY = 0;
11
+ if(e.clientX >= window.innerWidth - 40 || e.clientX >= scrollEl.getBoundingClientRect().right - 40){
12
+ scaleX = 1
13
+ }
14
+ if(e.clientX <= scrollEl.getBoundingClientRect().left + 40){
15
+ scaleX = -1
16
+ }
17
+ if(e.clientY >= window.innerHeight - 40 || e.clientY >= scrollEl.getBoundingClientRect().bottom - 40){
18
+ sacleY = 1
19
+ }
20
+ if(e.clientY <= scrollEl.getBoundingClientRect().top + 40){
21
+ sacleY = -1
22
+ }
23
+ if(this.scrollFn){
24
+ clearInterval(this.scrollFn);
25
+ }
26
+ this.scrollFn = setInterval(()=>{
27
+ scrollEl.scrollLeft += scaleX*20;
28
+ scrollEl.scrollTop += sacleY*20;
29
+ },30)
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,257 @@
1
+ <template>
2
+ <div @click.stop v-show="showCalendar" v-outclick="show_calendar" :style="{left:left+'px',top:top+'px'}" class="calendar-box">
3
+ <div class="change-time">
4
+ <span @click.stop="changeIndex(-1,'year')" class="last"><<</span>
5
+ <span @click.stop="changeIndex(-1,'month')" style="margin-left: 10px" class="last"><</span>
6
+ <span>{{disp_date | day_filter}}</span>
7
+ <span @click.stop="changeIndex(1,'year')" style="margin-left: 10px" class="next">>></span>
8
+ <span @click.stop="changeIndex(1,'month')" class="next">></span>
9
+ </div>
10
+ <ul class="calendar-head">
11
+ <li>一</li><li>二</li><li>三</li><li>四</li><li>五</li><li>六</li><li>日</li>
12
+ </ul>
13
+ <div v-for="(month,index) in monthList" :key="index" class="month swiper-item">
14
+ <!--<ul v-for="(week,weekindex) in month" :key="weekindex">-->
15
+ <li v-for="(day,dayindex) in month" @click="chooseDay(day.year,day.month,day.day,day.othermonth)">
16
+ <div class="week-day" :class="{ischecked:checkedDay==day.date,othermonth:day.othermonth,istoday:day.istoday}">
17
+ {{day.day}}
18
+ </div>
19
+ </li>
20
+ <!--</ul>-->
21
+ </div>
22
+ <div class="calendar-bottom">
23
+ <div @click="to_today" class="today-button">今天</div>
24
+ </div>
25
+ </div>
26
+ </template>
27
+ <script>
28
+ import outclick from '../../../utils/click-outside'
29
+ export default{
30
+ data(){
31
+ return{
32
+ disp_date:new Date(),
33
+ today:new Date(),
34
+ current_day:new Date(),
35
+ monthList:[],
36
+ showCalendar:false,
37
+ checkedDay:'0000-00-00',
38
+ }
39
+ },
40
+ directives:{
41
+ outclick
42
+ },
43
+ props:{
44
+ left:Number,
45
+ top:Number,
46
+ value:Boolean,
47
+ choose_date:{
48
+ default:new Date()
49
+ }
50
+ },
51
+ methods:{
52
+ show_calendar(){
53
+ this.showCalendar = false
54
+ },
55
+ to_today(){
56
+ this.current_day = new Date()
57
+ this.checkedDay = this.format(new Date().getFullYear(),new Date().getMonth(),new Date().getDate())
58
+ this.showCalendar = false
59
+ this.$emit('change',this.current_day)
60
+ },
61
+ chooseDay(year,month,day){
62
+ this.current_day = new Date(year,month,day)
63
+ this.checkedDay = this.format(year,month,day)
64
+ this.showCalendar = false
65
+ this.$emit('change',this.current_day)
66
+ },
67
+ format(year,month,day){
68
+ month++
69
+ month<10&&(month='0'+month)
70
+ day<10&&(day='0'+day)
71
+ return year + '-' + month + '-' + day;
72
+ },
73
+ getMonth(year,month){ //创建单月历
74
+ var monthArr = []
75
+ var dt_first = new Date(year,month,1) //每个月第一天
76
+ var dt_last = new Date(year,month+1,0) //每个月最后一天
77
+ var monthLength = dt_last.getDate()-dt_first.getDate()+1
78
+ var daylist =[];
79
+ var space = (dt_first.getDay() - 1 + 7) % 7 //月历前面空格
80
+ //console.log(year,month)
81
+ for(var i = -space;i<36;i+=7){
82
+ var week = []
83
+ for(var j=0;j<7;j++){
84
+ var day = i+j+1
85
+ if(day>0 && day<=monthLength){
86
+ week.push({
87
+ mode:'month',
88
+ day:day,
89
+ year:year,
90
+ month:month,
91
+ date:this.format(year,month,day),
92
+ istoday:(this.today.getFullYear()==year && this.today.getMonth()==month && this.today.getDate() == day)?true:false,
93
+ ischecked:false
94
+ })
95
+ }else{
96
+ //其它月份
97
+ //week.push({})
98
+ var newdt = new Date(year,month,day)
99
+ var _year = newdt.getFullYear()
100
+ var _month = newdt.getMonth()
101
+ var _day = newdt.getDate()
102
+ week.push({
103
+ mode:'month',
104
+ day:_day,
105
+ year:_year,
106
+ month:_month,
107
+ date:this.format(_year,_month,_day),
108
+ ischecked:false,
109
+ othermonth:day<=0?-1:1,
110
+ })
111
+ }
112
+ }
113
+ monthArr.push(week)
114
+ }
115
+ return monthArr
116
+ },
117
+ getOneMonth(){
118
+ var year = this.disp_date.getFullYear()
119
+ var month = this.disp_date.getMonth()
120
+ this.monthList=this.getMonth(year,month)
121
+ },
122
+ changeIndex(index,mode){
123
+ if(index){
124
+ if(mode == 'month'){
125
+ var _tmpdt = new Date(this.disp_date.getFullYear(),this.disp_date.getMonth()+index,0)
126
+ var maxday = _tmpdt.getDate()
127
+ var _day = maxday<this.disp_date.getDate()?maxday:this.disp_date.getDate()
128
+ this.disp_date = new Date(this.disp_date.getFullYear(),this.disp_date.getMonth()+index,_day)
129
+ }else if(mode == 'year'){
130
+ var _tmpdt = new Date(this.disp_date.getFullYear()+index,this.disp_date.getMonth(),0)
131
+ var maxday = _tmpdt.getDate()
132
+ var _day = maxday<this.disp_date.getDate()?maxday:this.disp_date.getDate()
133
+ this.disp_date = new Date(this.disp_date.getFullYear()+index,this.disp_date.getMonth(),_day)
134
+ }
135
+ this.getOneMonth()
136
+ }
137
+ }
138
+ },
139
+ watch:{
140
+ value(val){
141
+ this.showCalendar=val
142
+ },
143
+ choose_date(val){
144
+ if(val){
145
+ this.disp_date = this.choose_date
146
+ this.getOneMonth()
147
+ this.checkedDay = this.format(this.disp_date.getFullYear(),this.disp_date.getMonth(),this.disp_date.getDate())
148
+ }
149
+ },
150
+ showCalendar(val){
151
+ this.$emit('input',val)
152
+ }
153
+ },
154
+ filters:{
155
+ day_filter(value){
156
+ if(value){
157
+ var year = value.getFullYear()
158
+ var month = value.getMonth()+1
159
+ return year+'年'+month+'月'
160
+ }
161
+ }
162
+ },
163
+ destroyed(){
164
+ document.removeEventListener('click',this.show_calendar,false)
165
+ }
166
+ }
167
+ </script>
168
+ <style scoped>
169
+ .calendar-box{
170
+ position: fixed;
171
+ width:250px;
172
+ z-index:1000;
173
+ font-size: 13px;
174
+ border: 1px solid #ebeef5 ;
175
+ box-sizing: border-box;
176
+ background: #fff;
177
+ box-shadow: 1px 1px 8px #333;
178
+ }
179
+ .change-time{
180
+ padding: 5px 10px;
181
+ text-align: center;
182
+ background: #ffffff;
183
+ color: rgba(0, 0, 0, 0.85);
184
+ font-weight: 500;
185
+ border-bottom: 1px solid #ebeef5;
186
+ }
187
+ .last{
188
+ float: left;
189
+ cursor: pointer;
190
+ color: rgb(0 0 0 / 45%);
191
+ }
192
+ .next{
193
+ float: right;
194
+ cursor: pointer;
195
+ color: rgb(0 0 0 / 45%);
196
+ }
197
+ .last:hover,.next:hover{
198
+ background: #cfe6dc;
199
+ }
200
+ .calendar-head{
201
+ padding: 0;
202
+ display: flex;
203
+ justify-content: space-evenly;
204
+ height:30px;
205
+ line-height: 30px;
206
+ }
207
+ .calendar-head li{
208
+ width: 27px !important;
209
+ text-align: center;
210
+ }
211
+ .swiper-item{
212
+ display: flex;
213
+ justify-content: space-evenly;
214
+ }
215
+ .month li{
216
+ width: 27px !important;
217
+ overflow: hidden;
218
+ transition: background .2s ease;
219
+ cursor: pointer;
220
+ }
221
+ .month li:hover{
222
+ background: #efefef;
223
+ }
224
+ .week-day{
225
+ font-size:12px;
226
+ text-align: center;
227
+ overflow: hidden;
228
+ z-index: 1;
229
+ transition: all .1s ease;
230
+ height: 27px;
231
+ width: 27px;
232
+ line-height: 27px;
233
+ border-radius: 3px;
234
+ }
235
+ .calendar-bottom{
236
+ border-top: 1px solid #ccc;
237
+ }
238
+ .today-button{
239
+ width: 46px;
240
+ height: 22px;
241
+ line-height: 22px;
242
+ color: #00A578;
243
+ text-align: center;
244
+ border-radius: 2px;
245
+ margin: 5px auto;
246
+ cursor: pointer;
247
+ }
248
+ .othermonth{
249
+ color: #dcafaf;
250
+ }
251
+ .istoday{
252
+ border: 1px solid #00A578 !important;
253
+ }
254
+ .ischecked{
255
+ background: #8bd9ba !important;
256
+ }
257
+ </style>
@@ -0,0 +1,2 @@
1
+ import Vue from 'vue'
2
+ export default new Vue()