Skip to content

Commit d37db49

Browse files
committed
Select: make better
add props `label` for select fix mutliple selection init add object support for props `value` remove useless code
1 parent 5391a87 commit d37db49

File tree

11 files changed

+683
-381
lines changed

11 files changed

+683
-381
lines changed

document/docs/select.md

+419-232
Large diffs are not rendered by default.

document/docs/tabs.md

+9-8
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919
}
2020
</script>
2121
<style>
22-
.demo-tabs .block {
23-
padding: 30px 24px;
24-
overflow: hidden;
25-
border-bottom: 1px solid #eff2f6;
26-
}
27-
.demo-tabs .block:last-child {
28-
border-bottom: none;
29-
}
22+
.demo-tabs .block {
23+
padding: 30px 24px;
24+
overflow: hidden;
25+
border-bottom: 1px solid #eff2f6;
26+
}
27+
28+
.demo-tabs .block:last-child {
29+
border-bottom: none;
30+
}
3031
</style>
3132
## Tabs 标签页
3233

packages/select/src/main.vue

+67-89
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,49 @@
11
<template>
22
<div class="mv-select" v-clickoutside="handleClose">
3-
<div class="input-field col s12">
4-
<div class="select-wrapper">
5-
<span class="caret">▼</span>
6-
<input type="text"
7-
class="select-dropdown"
8-
readonly="true"
9-
:value="selectedLabel"
10-
@focus="handleFocus"
11-
@click="handleClick"
12-
ref="mvSelect"
13-
>
14-
<transition
15-
name="mv-top"
16-
@before-enter="handleMenuEnter">
17-
<ul id="select-options"
18-
class="dropdown-content select-dropdown"
19-
:class="{'mv-select__multiple': multiple}"
20-
v-show="avisible"
21-
ref="options">
22-
<el-option
23-
:value="placeholder"
24-
created
25-
v-if="placeholder"
26-
disabled>
27-
</el-option>
28-
<slot></slot>
29-
</ul>
30-
</transition>
31-
</div>
32-
<label>Materialize Select</label>
3+
<div class="select-wrapper">
4+
<span class="caret">▼</span>
5+
<input type="text"
6+
class="select-dropdown"
7+
readonly="true"
8+
:value="selectedLabel"
9+
@focus="handleFocus"
10+
@click="handleClick">
11+
<transition
12+
name="mv-top"
13+
@before-enter="handleMenuEnter">
14+
<ul id="select-options"
15+
class="dropdown-content select-dropdown"
16+
:class="{'mv-select__multiple': multiple}"
17+
v-show="visible"
18+
ref="options">
19+
<mv-option
20+
v-if="placeholder"
21+
:value="placeholder"
22+
disabled>
23+
</mv-option>
24+
<slot></slot>
25+
</ul>
26+
</transition>
3327
</div>
28+
<label v-if="label">{{label}}</label>
3429
</div>
3530
</template>
3631

3732
<script>
38-
import ElOption from './option.vue'
39-
import Clickoutside from 'mvui/src/utils/clickoutside'
33+
import MvOption from './option.vue'
34+
import Clickoutside from 'main/utils/clickoutside'
35+
import {getValueByPath} from 'main/utils/util'
4036
4137
export default {
4238
name: 'MvSelect',
4339
4440
componentName: 'MvSelect',
4541
46-
directives: { Clickoutside },
42+
directives: {Clickoutside},
43+
44+
components: {
45+
MvOption
46+
},
4747
4848
props: {
4949
value: {
@@ -54,32 +54,32 @@
5454
default: 'value'
5555
},
5656
placeholder: {
57-
type: [String, Object, Number],
57+
type: [String, Number, Object],
5858
default: ''
5959
},
6060
multiple: {
6161
type: Boolean
62-
}
62+
},
63+
label: String
6364
},
65+
6466
data () {
6567
return {
6668
options: [],
6769
cachedOptions: [],
68-
avisible: false,
70+
visible: false,
6971
isSelect: true,
70-
selectedLabel: '',
71-
createdLabel: '',
72-
filterable: '',
73-
createdSelected: '',
74-
checkbox: false
72+
selectedLabel: ''
7573
}
7674
},
77-
components: {
78-
ElOption
79-
},
80-
created () {
81-
this.$on('handleOptionClick', this.handleOptionSelect)
75+
76+
watch: {
77+
value (val) {
78+
this.setSelected()
79+
this.$emit('change', val)
80+
}
8281
},
82+
8383
methods: {
8484
handleOptionSelect (option) {
8585
if (this.multiple) {
@@ -93,58 +93,56 @@
9393
this.$emit('input', value)
9494
} else {
9595
this.$emit('input', option.value)
96-
this.avisible = false
96+
this.visible = false
9797
}
9898
},
9999
getValueIndex (arr = [], value) {
100100
const isObject = Object.prototype.toString.call(value).toLowerCase() === '[object object]'
101101
if (!isObject) {
102102
return arr.indexOf(value)
103+
} else {
104+
const valueKey = this.valueKey
105+
let index = -1
106+
arr.some((item, i) => {
107+
if (getValueByPath(item, valueKey) === getValueByPath(value, valueKey)) {
108+
index = i
109+
return true
110+
}
111+
return false
112+
})
113+
return index
103114
}
104115
},
105116
handleFocus () {
106-
this.avisible = true
107-
},
108-
handleBlur () {
109-
setTimeout(() => {
110-
this.avisible = false
111-
}, 200)
117+
this.visible = true
112118
},
113119
handleClose () {
114-
this.avisible = false
120+
this.visible = false
115121
},
116122
setSelected () {
117123
if (!this.multiple) {
118124
let option = this.getOption(this.value)
119-
if (option.created) {
120-
this.createdLabel = option.currentLabel
121-
this.createdSelected = true
122-
} else {
123-
this.createdSelected = false
124-
}
125125
this.selectedLabel = option.currentLabel
126126
if (!option.currentLabel && this.placeholder) {
127127
this.selectedLabel = this.placeholder
128128
}
129-
this.selected = option
130-
if (this.filterable) this.query = this.selectedLabel
131129
return
132130
}
133131
let result = []
134132
if (Array.isArray(this.value)) {
135133
this.value.forEach(value => {
136-
result.push(this.getOption(value).label)
134+
result.push(this.getOption(value).currentLabel)
137135
})
138136
}
139137
this.selectedLabel = result
140138
},
141139
getOption (value) {
142140
let option
143141
const isObject = Object.prototype.toString.call(value).toLowerCase() === '[object object]'
144-
for (let i = this.cachedOptions.length - 1; i >= 0; i--) {
142+
for (let i = 0; i <= this.cachedOptions.length - 1; i++) {
145143
const cachedOption = this.cachedOptions[i]
146144
const isEqual = isObject
147-
? this.getValueByPath(cachedOption.value, this.valueKey) === this.getValueByPath(value, this.valueKey)
145+
? getValueByPath(cachedOption.value, this.valueKey) === getValueByPath(value, this.valueKey)
148146
: cachedOption.value === value
149147
if (isEqual) {
150148
option = cachedOption
@@ -164,38 +162,18 @@
164162
return newOption
165163
},
166164
handleClick () {
167-
this.avisible !== this.avisible
165+
this.visible !== this.visible
168166
},
169167
handleMenuEnter (el) {
170168
el.style.top = 0
171-
},
172-
getValueByPath (object, prop) {
173-
prop = prop || ''
174-
const paths = prop.split('.')
175-
let current = object
176-
let result = null
177-
for (let i = 0, j = paths.length; i < j; i++) {
178-
const path = paths[i]
179-
if (!current) break
180-
181-
if (i === j - 1) {
182-
result = current[path]
183-
break
184-
}
185-
current = current[path]
186-
}
187-
return result
188169
}
189170
},
190-
computed: {},
191171
mounted () {
192172
this.setSelected()
193173
},
194-
watch: {
195-
'value' (val) {
196-
this.setSelected()
197-
this.$emit('change', val)
198-
}
174+
175+
created () {
176+
this.$on('handleOptionClick', this.handleOptionSelect)
199177
}
200178
}
201179
</script>

packages/select/src/option-group.vue

+4-7
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,15 @@
88
</template>
99

1010
<script>
11-
import Emitter from 'mvui/src/mixins/emitter'
1211
export default {
13-
mixins: [Emitter],
1412
name: 'MvOptionGroup',
13+
14+
componentName: 'MvOptionGroup',
15+
1516
props: {
1617
label: String,
17-
disabled: {
18-
type: Boolean,
19-
default: false
20-
}
18+
disabled: Boolean
2119
}
2220
}
23-
2421
</script>
2522

0 commit comments

Comments
 (0)