/
Select.vue
99 lines (92 loc) · 2.54 KB
/
Select.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<template>
<div
class="control"
:class="{ 'is-expanded': expanded, 'has-icons-left': icon }">
<span class="select" :class="spanClasses">
<select
v-model="computedValue"
ref="select"
:multiple="multiple"
:size="nativeSize"
v-bind="$attrs"
@blur="$emit('blur', $event) && checkHtml5Validity()"
@focus="$emit('focus', $event)">
<template v-if="placeholder">
<option
v-if="computedValue == null"
:value="null"
disabled
hidden>
{{ placeholder }}
</option>
</template>
<slot/>
</select>
</span>
<b-icon
v-if="icon"
class="is-left"
:icon="icon"
:pack="iconPack"
:size="iconSize"/>
</div>
</template>
<script>
import Icon from '../icon/Icon.vue'
import FormElementMixin from '../../utils/FormElementMixin'
export default {
name: 'BSelect',
components: {
[Icon.name]: Icon
},
mixins: [FormElementMixin],
inheritAttrs: false,
props: {
value: {
type: [String, Number, Boolean, Object, Array, Function, Date],
default: null
},
placeholder: String,
multiple: Boolean,
nativeSize: [String, Number]
},
data() {
return {
selected: this.value,
_elementRef: 'select'
}
},
computed: {
computedValue: {
get() {
return this.selected
},
set(value) {
this.selected = value
this.$emit('input', value)
!this.isValid && this.checkHtml5Validity()
}
},
spanClasses() {
return [this.size, this.statusType, {
'is-fullwidth': this.expanded,
'is-loading': this.loading,
'is-multiple': this.multiple,
'is-rounded': this.rounded,
'is-empty': this.selected === null
}]
}
},
watch: {
/**
* When v-model is changed:
* 1. Set the selected option.
* 2. If it's invalid, validate again.
*/
value(value) {
this.selected = value
!this.isValid && this.checkHtml5Validity()
}
}
}
</script>