vdesign-ui 0.1.24 → 0.2.0-beta

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.
Files changed (71) hide show
  1. package/dist/components/activityviews/index.vue +14 -12
  2. package/dist/components/button/index.vue +1 -1
  3. package/dist/components/checkbox/checkbox-group/index.vue +2 -1
  4. package/dist/components/checkbox/index.vue +19 -20
  5. package/dist/components/dialog/index.vue +15 -11
  6. package/dist/components/dropdown/index.vue +43 -31
  7. package/dist/components/empty/404-dark.png +0 -0
  8. package/dist/components/empty/404.png +0 -0
  9. package/dist/components/empty/index.vue +30 -2
  10. package/dist/components/empty/network-dark.png +0 -0
  11. package/dist/components/empty/network.png +0 -0
  12. package/dist/components/empty/nocoupons-dark.png +0 -0
  13. package/dist/components/empty/nocoupons.png +0 -0
  14. package/dist/components/empty/nodata-dark.png +0 -0
  15. package/dist/components/empty/nodata.png +0 -0
  16. package/dist/components/empty/nomargin-dark.png +0 -0
  17. package/dist/components/empty/nomargin.png +0 -0
  18. package/dist/components/empty/nonotice-dark.png +0 -0
  19. package/dist/components/empty/nonotice.png +0 -0
  20. package/dist/components/empty/noocomments-dark.png +0 -0
  21. package/dist/components/empty/noocomments.png +0 -0
  22. package/dist/components/empty/noorders-dark.png +0 -0
  23. package/dist/components/empty/noorders.png +0 -0
  24. package/dist/components/empty/noposition-dark.png +0 -0
  25. package/dist/components/empty/noposition.png +0 -0
  26. package/dist/components/empty/nosearch-dark.png +0 -0
  27. package/dist/components/empty/nosearch.png +0 -0
  28. package/dist/components/footer/index.vue +5 -1
  29. package/dist/components/footnav/footnav-item/index.vue +11 -42
  30. package/dist/components/footnav/index.vue +13 -27
  31. package/dist/components/headnav/index.vue +52 -35
  32. package/dist/components/icon/font/iconfont.css +62 -952
  33. package/dist/components/icon/font/iconfont.js +1 -1
  34. package/dist/components/icon/index.vue +26 -18
  35. package/dist/components/input/index.vue +107 -109
  36. package/dist/components/input/search/index.vue +18 -22
  37. package/dist/components/input/stepper/index.vue +32 -26
  38. package/dist/components/input/style.less +20 -33
  39. package/dist/components/list/index.vue +57 -69
  40. package/dist/components/list/style.less +20 -92
  41. package/dist/components/loading/img_status_loading_white_ani.svg +155 -0
  42. package/dist/components/loading/img_status_refresh_ani.svg +158 -0
  43. package/dist/components/loading/index.vue +21 -11
  44. package/dist/components/loading/style.less +1 -1
  45. package/dist/components/mixins/clickoutside.js +81 -81
  46. package/dist/components/pagebreak/index.vue +21 -14
  47. package/dist/components/radio/index.vue +164 -135
  48. package/dist/components/radio/radio-group/index.vue +40 -52
  49. package/dist/components/result/index.vue +1 -2
  50. package/dist/components/selector/index.vue +49 -31
  51. package/dist/components/selector/style.less +14 -0
  52. package/dist/components/step-item/index.vue +2 -2
  53. package/dist/components/tabs/index.vue +55 -32
  54. package/dist/components/tabs/tab/index.vue +13 -16
  55. package/dist/components/tag/index.vue +18 -4
  56. package/dist/components/tag/style.less +2 -2
  57. package/dist/components/title/index.vue +11 -8
  58. package/dist/components/title/style.less +6 -0
  59. package/dist/img/img_status_loading_white_ani.b56fcfae.svg +155 -0
  60. package/dist/img/img_status_refresh_ani.d0e59f12.svg +158 -0
  61. package/dist/token.css +8 -0
  62. package/dist/vdesign-ui.common.js +1362 -1170
  63. package/dist/vdesign-ui.css +1 -1
  64. package/dist/vdesign-ui.umd.js +1362 -1170
  65. package/dist/vdesign-ui.umd.min.js +3 -3
  66. package/package.json +1 -1
  67. package/dist/components/loading/loading.png +0 -0
  68. package/dist/components/loading/refresh.png +0 -0
  69. package/dist/img/404-dark.775df5bb.png +0 -0
  70. package/dist/img/network-dark.11a147bb.png +0 -0
  71. package/dist/img/nodata-dark.b0ea0e39.png +0 -0
@@ -13,7 +13,7 @@
13
13
  <vd-icon v-if="closeIcon" class="vd-activityviews__close" :name="currentCloseIcon" svg
14
14
  @click="onCancel"></vd-icon>
15
15
  <vd-button v-if="closeBtn" class="vd-activityviews__done" type="primary_text" size="large"
16
- @click="onCancel">{{ closeBtn }}</vd-button>
16
+ @click="onCancel">{{ closeBtn }}</vd-button>
17
17
  </slot>
18
18
  </div>
19
19
  <p v-if="description" class="vd-activityviews__description">{{ description }}</p>
@@ -23,8 +23,9 @@
23
23
  <div v-if="actionSheet" class="vd-activityviews__action">
24
24
  <p v-if="title" class="vd-activityviews__action-title vd-hairline--bottom">{{ title }}</p>
25
25
  <div class="vd-activityviews__actions">
26
- <vd-button v-for="(item, index) in actions" block size="large" :type="item.type" :key="index" :class="{ 'vd-hairline--bottom': index !== actions.length - 1 }"
27
- :disabled="item.disabled" @click.stop="onSelect(item)" >{{ item.name }}</vd-button>
26
+ <vd-button v-for="(item, index) in actions" block size="large" :type="item.type"
27
+ :key="index" :class="{ 'vd-hairline--bottom': index !== actions.length - 1 }"
28
+ :disabled="item.disabled" @click.stop="onSelect(item)">{{ item.name }}</vd-button>
28
29
  </div>
29
30
  <div v-if="cancelText" class="vd-activityviews__gap"></div>
30
31
  <div v-if="cancelText" class="vd-activityviews__cancel" @click="onCancel">
@@ -47,7 +48,7 @@ export default {
47
48
  props: {
48
49
  value: Boolean,
49
50
  title: String,
50
- backDefault:Boolean,
51
+ backDefault: Boolean,
51
52
  closeIcon: Boolean,
52
53
  closeBtn: String,
53
54
  description: String,
@@ -69,7 +70,7 @@ export default {
69
70
  default: true
70
71
  },
71
72
  disabled: Boolean,
72
- closeOnOverlay:{
73
+ closeOnOverlay: {
73
74
  type: Boolean,
74
75
  default: true
75
76
  },
@@ -79,11 +80,11 @@ export default {
79
80
  }
80
81
  },
81
82
  computed: {
82
- visible(){
83
+ visible() {
83
84
  return this.value
84
85
  },
85
86
  currentCloseIcon() {
86
- return this.isDarkTheme ? 'icon_btn_dialogclose_dark' : 'icon_btn_dialogclose';
87
+ return this.isDarkTheme ? 'icon_btn_dialogclose_dark_svg' : 'icon_btn_dialogclose_svg';
87
88
  },
88
89
  isDarkTheme() {
89
90
  return this.theme === 'dark';
@@ -121,20 +122,21 @@ export default {
121
122
 
122
123
  .vd-activityviews-fade-enter-active,
123
124
  .vd-activityviews-fade-leave-active {
124
- transition: opacity 0.3s;
125
+ transition: opacity 0.3s;
125
126
  }
127
+
126
128
  .vd-activityviews-fade-enter,
127
129
  .vd-activityviews-fade-leave-to {
128
- opacity: 0;
130
+ opacity: 0;
129
131
  }
130
132
 
131
133
  .vd-activityviews-slide-up-enter-active,
132
134
  .vd-activityviews-slide-up-leave-active {
133
- transition: transform 0.3s;
135
+ transition: transform 0.3s;
134
136
  }
137
+
135
138
  .vd-activityviews-slide-up-enter,
136
139
  .vd-activityviews-slide-up-leave-to {
137
- transform: translateY(100%);
140
+ transform: translateY(100%);
138
141
  }
139
-
140
142
  </style>
@@ -33,7 +33,7 @@ export default {
33
33
  },
34
34
  loadingIcon: {
35
35
  type: String,
36
- default: 'icon_show_statisticsprice'
36
+ default: 'icon_show_list_loading'
37
37
  },
38
38
  block: {
39
39
  type: Boolean,
@@ -18,7 +18,8 @@ export default {
18
18
  return [];
19
19
  }
20
20
  },
21
- type: String,
21
+ type: String, // 类型card
22
+
22
23
  },
23
24
  data() {
24
25
  return {
@@ -1,12 +1,15 @@
1
1
  <template>
2
2
  <label :class="wrapClasses" v-if="!checkboxButton">
3
3
  <span :class="checkboxClasses">
4
+ <!-- 处理分组和单个情况的输入元素 -->
4
5
  <span :class="innerClasses"></span>
6
+ <!-- 处理分组和单个情况的输入元素 -->
5
7
  <input v-if="group" type="checkbox" :class="inputClasses" :disabled="disabled" :value="name" v-model="model"
6
8
  @change="change" />
7
9
  <input v-else type="checkbox" :class="inputClasses" :disabled="disabled" :checked="currentValue"
8
10
  @change="change" />
9
11
  </span>
12
+ <!-- 标签和可选的描述 -->
10
13
  <div class="vd-checkbox__label" v-if="$slots.default">
11
14
  <p class="vd-checkbox__text">
12
15
  <slot></slot>
@@ -15,6 +18,7 @@
15
18
  </div>
16
19
  </label>
17
20
 
21
+ <!-- 复选框按钮变体 -->
18
22
  <label class="vd-checkbox vd-checkbox-button" :class="checkboxButtonClasses" v-else>
19
23
  <input type="checkbox" :class="inputClasses" :disabled="disabled" :checked="currentValue" @change="change" />
20
24
  <template v-if="type === 'small'">
@@ -46,32 +50,29 @@ const prefixCls = "vd-checkbox";
46
50
  export default {
47
51
  name: "vd-checkbox",
48
52
  props: {
49
- checkboxButton: Boolean,
50
- disabled: Boolean,
51
- extra: [String, Number, Boolean],
52
- descriptionText: [String, Number, Boolean],
53
- iconDescriptionText: [String, Number, Boolean],
54
- value: [String, Number, Boolean],
53
+ value: [String, Number, Boolean], // 复选框的当前值
54
+ checkboxButton: Boolean, // 是否为复选框按钮
55
+ disabled: Boolean, // 是否禁用
56
+ extra: [String, Number, Boolean], // 额外的描述文本
55
57
  trueValue: {
56
58
  type: [String, Number, Boolean],
57
- default: true,
59
+ default: true, // 复选框被选中时的值
58
60
  },
59
61
  falseValue: {
60
62
  type: [String, Number, Boolean],
61
- default: false,
63
+ default: false, // 复选框未被选中时的值
62
64
  },
63
- name: null,
64
- indeterminate: Boolean,
65
- icon: String,
66
- iconText: [String, Number, Boolean],
67
- type: String,
65
+ name: null, //复选框的 name 属性
66
+ indeterminate: Boolean, // 复选框的不确定状态
67
+ icon: String, // 使用复选框按钮时显示的图标
68
+ type: String, // 复选框按钮的尺寸类型('small','medium','large')
68
69
  },
69
70
  data() {
70
71
  return {
71
- model: [],
72
- currentValue: this.value,
73
- group: false,
74
- parent: findComponentUpward(this, "vd-checkbox-group"),
72
+ model: [], // 复选框组的模型值
73
+ currentValue: this.value, // 复选框的当前值
74
+ group: false, // 是否为复选框组
75
+ parent: null, // 对父级复选框组组件的引用
75
76
  };
76
77
  },
77
78
  computed: {
@@ -111,9 +112,7 @@ export default {
111
112
  mounted() {
112
113
  this.parent = findComponentUpward(this, "vd-checkbox-group");
113
114
  if (this.parent) {
114
- this.group = true;
115
- }
116
- if (this.group) {
115
+ this.isGroup = true;
117
116
  this.parent.updateModel(true);
118
117
  } else {
119
118
  this.updateModel();
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <div class="vd-dialog-wrap">
3
3
  <div class="vd-overlay" v-if="visible && isOverlayVisible && overlay" :style="{ zIndex: overlayZIndex }"
4
- @click="handleOverlayClick()"></div>
4
+ @click="handleOverlayClick"></div>
5
5
  <transition name="vd-dialog-fade">
6
- <div class="vd-dialog" v-if="visible" :class="className ? `vd-dialog--${className}` : ''" :style="{width : width, zIndex: overlayZIndex + 1}">
6
+ <div class="vd-dialog" v-if="visible" :class="computedClassName" :style="{width : width, zIndex: overlayZIndex + 1}">
7
7
  <header class="vd-dialog__header" :class="{ 'vd-dialog__header--img': $slots.imgs }">
8
8
  <div class="vd-dialog__header--img-content" v-if="$slots.imgs">
9
9
  <slot name="imgs"></slot>
@@ -13,9 +13,7 @@
13
13
  <div class="vd-dialog__content">
14
14
  <div class="vd-dialog__message" :class="{ 'vd-dialog__message--head': !title }"
15
15
  v-if="message || $slots.content">
16
- <slot name="content">{{
17
- message
18
- }}</slot>
16
+ <slot name="content">{{message}}</slot>
19
17
  </div>
20
18
  </div>
21
19
  <footer class="vd-dialog__footer">
@@ -89,18 +87,24 @@ export default {
89
87
  }
90
88
  },
91
89
  watch: {
92
- visible(val) {
93
- if (val) {
90
+ visible: {
91
+ immediate: true,
92
+ handler(val) {
93
+ if (val) {
94
94
  this.showOverlayLayer();
95
- } else {
95
+ } else {
96
96
  this.hideOverlayLayer();
97
- }
98
- }
97
+ }
98
+ },
99
+ },
99
100
  },
100
101
  computed: {
101
102
  visible() {
102
103
  return this.value
103
- }
104
+ },
105
+ computedClassName() {
106
+ return this.className ? `vd-dialog--${this.className}` : '';
107
+ },
104
108
  },
105
109
  methods: {
106
110
  showOverlayLayer() {
@@ -4,9 +4,9 @@
4
4
  <div class="vd-menu-mask" @click.stop="clickMenuMask"></div>
5
5
  </transition> -->
6
6
  <transition :name="isAnimation ? 'vd-dropdown-slide-down' : ''">
7
- <div v-clickoutside="clickMenuMask" class="vd-dropdown-menu" v-show="value">
7
+ <div v-clickoutside="clickMenuMask" class="vd-dropdown-menu" v-show="isMask">
8
8
  <template v-if="!isMultiple && !$slots.custom">
9
- <div class="vd-dropdown-item" :class="itemClass(item)" v-for="(item, index) of datalist" :key="item.name"
9
+ <div class="vd-dropdown-item" :class="itemClass(item)" v-for="(item, index) in datalist" :key="item.name"
10
10
  @click.stop="selectedItem(item, index)">
11
11
  <span class="vd-dropdown-left">
12
12
  <vd-icon v-if="item.icon" :name="item.icon" svg class="vd-dropdown-icon"></vd-icon>
@@ -26,7 +26,7 @@
26
26
  </template>
27
27
 
28
28
  <template v-if="isMultiple">
29
- <div class="vd-dropdown-item" :class="itemClass(item)" v-for="item of datalist" :key="item.name">
29
+ <div class="vd-dropdown-item" :class="itemClass(item)" v-for="item in datalist" :key="item.name">
30
30
  <vd-checkbox v-model="item.selected" :disabled="!item.selected && max <= selectedCount">
31
31
  {{ item.text }}
32
32
  </vd-checkbox>
@@ -99,36 +99,33 @@ export default {
99
99
  type: Array,
100
100
  default: () => []
101
101
  },
102
- state: {
103
- type: String,
104
- default: 'close',
105
- validator: value => ['open', 'preopen', 'close', 'fusing', 'pre', 'last'].includes(value)
106
- },
107
- stateText: {
108
- type: String,
109
- default: ''
110
- },
111
- subText: {
102
+ for: {
112
103
  type: String,
113
104
  default: ''
114
105
  },
115
- subIcon: {
116
- type: String,
117
- default: ''
118
- }
119
106
  },
120
107
  data() {
121
108
  return {
122
- datalist: [],
123
- isMask: this.value
109
+ datalist: []
124
110
  };
125
111
  },
126
112
  watch: {
127
- value(val) {
128
- this.isMask = val;
113
+ list: {
114
+ immediate: true,
115
+ handler(val) {
116
+ this.datalist = [...val];
117
+ }
118
+ },
119
+ value(val){
120
+ if(!val){
121
+ this.$emit('close')
122
+ }
129
123
  }
130
124
  },
131
125
  computed: {
126
+ isMask() {
127
+ return this.value;
128
+ },
132
129
  wrapClasses() {
133
130
  return {
134
131
  [`${prefixCls}-${this.types}`]: this.types,
@@ -146,9 +143,6 @@ export default {
146
143
  return this.datalist.filter(item => item.selected).length;
147
144
  }
148
145
  },
149
- mounted() {
150
- this.datalist = [...this.list];
151
- },
152
146
  methods: {
153
147
  itemClass(item) {
154
148
  return {
@@ -156,26 +150,44 @@ export default {
156
150
  [`${prefixCls}--active`]: item.selected
157
151
  };
158
152
  },
159
- clickMenuMask() {
160
- this.isMask = false;
161
- this.$emit('close');
153
+ findParentWithNameAttr(element, nameValue) {
154
+ // 如果当前元素具有 name 属性且与传入的值匹配,返回该元素
155
+ if (element.getAttribute && element.getAttribute('alias-name') === nameValue) {
156
+ return element;
157
+ }
158
+ // 如果已经到达根元素 (document 或 null),停止查找
159
+ if (element.parentElement) {
160
+ return this.findParentWithNameAttr(element.parentElement, nameValue); // 递归查找父元素
161
+ }
162
+ return null; // 没有找到带 name 属性的匹配元素
163
+ },
164
+ clickMenuMask(e) {
165
+ if (this.value) {
166
+ if(this.for){
167
+ const nameElement = this.findParentWithNameAttr(e, this.for)
168
+ // 如果没找到就说明点外面了
169
+ if (!nameElement) {
170
+ this.$emit('input', false);
171
+ }
172
+ }
173
+ }
162
174
  },
163
175
  selectedItem(item, index) {
164
- this.$emit('change', item, index);
176
+ this.$emit('change', item, index); // 通知父组件选中项改变
165
177
  },
166
178
  resetMenu() {
167
179
  this.datalist.forEach(item => (item.selected = false));
168
180
  this.$emit('reset', this.datalist);
169
181
  },
170
182
  sureMenu() {
171
- this.isMask = false;
172
- this.$emit('close');
173
- this.$emit('ok', this.datalist);
183
+ this.$emit('close'); // 关闭菜单
184
+ this.$emit('ok', this.datalist); // 确认并返回数据
174
185
  }
175
186
  }
176
187
  };
177
188
  </script>
178
189
 
190
+
179
191
  <style lang="less">
180
192
  @import './style.less';
181
193
 
Binary file
Binary file
@@ -25,7 +25,7 @@ export default {
25
25
  default: 'nodata', // 默认类型
26
26
  validator(value) {
27
27
  // 只接受以下类型值
28
- return ['nodata', 'network', 'not-found'].includes(value);
28
+ return ['nodata', 'network', 'not-found','noposition','nomargin','nocoupons','nosearch','nonotice','noorders','noocomments'].includes(value);
29
29
  }
30
30
  },
31
31
  },
@@ -43,7 +43,35 @@ export default {
43
43
  'not-found': {
44
44
  light: require('./404.png'),
45
45
  dark: require('./404-dark.png')
46
- }
46
+ },
47
+ noposition: {
48
+ light: require('./noposition.png'),
49
+ dark: require('./noposition-dark.png')
50
+ },
51
+ nomargin: {
52
+ light: require('./nomargin.png'),
53
+ dark: require('./nomargin-dark.png')
54
+ },
55
+ nocoupons: {
56
+ light: require('./nocoupons.png'),
57
+ dark: require('./nocoupons-dark.png')
58
+ },
59
+ nosearch: {
60
+ light: require('./nosearch.png'),
61
+ dark: require('./nosearch-dark.png')
62
+ },
63
+ nonotice: {
64
+ light: require('./nonotice.png'),
65
+ dark: require('./nonotice-dark.png')
66
+ },
67
+ noorders: {
68
+ light: require('./noorders.png'),
69
+ dark: require('./noorders-dark.png')
70
+ },
71
+ noocomments: {
72
+ light: require('./noocomments.png'),
73
+ dark: require('./noocomments-dark.png')
74
+ },
47
75
  }
48
76
  }
49
77
  },
Binary file
Binary file
@@ -4,7 +4,11 @@
4
4
  <slot>
5
5
  </slot>
6
6
  </div>
7
- <p class="vd-footer__text" v-html="text"></p>
7
+ <div class="vd-footer__text" v-if="text || $slots.text">
8
+ <slot name="text">
9
+ {{ text }}
10
+ </slot>
11
+ </div>
8
12
  </div>
9
13
  </template>
10
14
 
@@ -1,8 +1,7 @@
1
1
  <template>
2
- <div class="vd-foot-nav-item" :class="{ 'vd-foot-nav-item--active': active }" @click="onClick">
3
- <vd-icon v-if="icon" :name="icon" :svg="isSvg"></vd-icon>
4
- <vd-badge v-if="dot || badge" :is-dot="dot" :value="badge" :max="99">
5
- <vd-icon :name="iconName" size="large" :svg="isSvg"></vd-icon>
2
+ <div class="vd-foot-nav-item" :class="{ 'vd-foot-nav-item--active': isActive }" @click="onClick">
3
+ <vd-badge v-if="iconName|| $slots.icon" :is-dot="dot" :value="badge" :max="99">
4
+ <slot name="icon"><vd-icon :name="iconName" size="large"></vd-icon></slot>
6
5
  </vd-badge>
7
6
  <slot></slot>
8
7
  </div>
@@ -16,53 +15,23 @@ export default {
16
15
  name: 'vd-foot-nav-item',
17
16
  mixins: [RouterLink],
18
17
  props: {
19
- iconName: {
20
- type: String,
21
- },
22
- icon: {
23
- type: String,
24
- },
25
- name: {
26
- type: String,
27
- },
28
- text: {
29
- type: String,
30
- },
31
- dot: {
32
- type: Boolean,
33
- },
34
- badge: {
35
- type: [Number, String],
36
- },
37
- isSvg: {
38
- type: Boolean,
39
- },
18
+ iconName: String,
19
+ dot: Boolean,
20
+ badge: [Number, String],
40
21
  },
41
22
  computed: {
42
- // isActive() {
43
- // return this.$parent.active === this.$parent.$children.indexOf(this);
44
- // // return this.activeIndex === this.index;
45
-
46
- // },
23
+ isActive() {
24
+ return this.$parent.value === this.$parent.$slots.default.indexOf(this.$vnode);
25
+ },
47
26
  },
48
27
  data() {
49
28
  return {
50
- active: false
51
29
  };
52
30
  },
53
-
54
- beforeCreate() {
55
- this.$parent.items.push(this);
56
- },
57
-
58
- destroyed() {
59
- this.$parent.items.splice(this.$parent.items.indexOf(this), 1);
60
- },
61
31
  methods: {
62
32
  onClick(event) {
63
- // this.$parent.updateActive(this.$parent.$children.indexOf(this));
64
- // this.$emit('click', event);
65
- this.$parent.onChange(this.$parent.items.indexOf(this));
33
+ const index = this.$parent.$slots.default.indexOf(this.$vnode);
34
+ this.$parent.onChange(index);
66
35
  this.$emit('click', event);
67
36
  this.routerLink();
68
37
  },
@@ -27,14 +27,14 @@ export default {
27
27
  default: null,
28
28
  },
29
29
  placeholder: Boolean,
30
+ beforeChange: {
31
+ type: Function,
32
+ default: null,
33
+ },
30
34
  },
31
35
  computed: {
32
36
  fit() {
33
- if (this.safeAreaInsetBottom !== null) {
34
- return this.safeAreaInsetBottom;
35
- }
36
- // enable safe-area-inset-bottom by default when fixed
37
- return this.fixed;
37
+ return this.safeAreaInsetBottom !== null ? this.safeAreaInsetBottom : this.fixed;
38
38
  },
39
39
  style() {
40
40
  return {
@@ -44,39 +44,24 @@ export default {
44
44
  },
45
45
  data() {
46
46
  return {
47
- // active: 0,
48
- items: [],
49
47
  height: null,
50
48
  }
51
49
  },
52
50
  watch: {
53
- items() {
54
- this.setActiveItem();
55
- },
56
-
57
- value() {
58
- this.setActiveItem();
59
- }
60
51
  },
61
52
  methods: {
62
- setActiveItem() {
63
- this.items.forEach((item, index) => {
64
- item.active = index === this.value;
65
- });
66
- },
53
+ async onChange(active) {
54
+ // 处理 before-change 回调,允许用户决定是否切换
55
+ if (this.beforeChange) {
56
+ const canChange = await this.beforeChange(active);
57
+ if (!canChange) return;
58
+ }
67
59
 
68
- onChange(active) {
69
60
  if (active !== this.value) {
70
61
  this.$emit('input', active);
71
62
  this.$emit('change', active);
72
63
  }
73
64
  },
74
- // updateActive(index) {
75
- // this.active = index;
76
- // },
77
- // handleClick() {
78
- // this.$emit('click',this.active)
79
- // }
80
65
  },
81
66
  mounted() {
82
67
  if (this.placeholder && this.fixed) {
@@ -85,7 +70,8 @@ export default {
85
70
  };
86
71
 
87
72
  setHeight();
88
- setTimeout(setHeight, 100);
73
+ window.addEventListener('resize', setHeight);
74
+ this.$once('hook:beforeDestroy', () => window.removeEventListener('resize', setHeight));
89
75
  }
90
76
  }
91
77