1+ <template >
2+ <view class =" uni-combox" nvue >
3+ <view v-if =" label" class =" uni-combox__label" :style =" labelStyle" >
4+ <text >{{label}}</text >
5+ </view >
6+ <view class =" uni-combox__input-box" >
7+ <input class =" uni-combox__input" type =" text" :placeholder =" placeholder" v-model =" inputVal" @input =" onInput" @focus =" onFocus" @blur =" onBlur" />
8+ <uni-icons class =" uni-combox__input-arrow" type =" arrowdown" size =" 14" @click =" toggleSelector" ></uni-icons >
9+ <view class =" uni-combox__selector" v-if =" showSelector" >
10+ <view class =" uni-combox__selector-empty" v-if =" filterCandidatesLength === 0" >
11+ <text >{{emptyTips}}</text >
12+ </view >
13+ <view class =" uni-combox__selector-item" v-for =" (item,index) in filterCandidates" :key =" index" @click =" onSelectorClick(index)" >
14+ <text >{{item}}</text >
15+ </view >
16+ </view >
17+ </view >
18+ </view >
19+ </template >
20+
21+ <script >
22+ import uniIcons from ' ../uni-icons/uni-icons.vue'
23+ export default {
24+ name: ' uniCombox' ,
25+ components: {
26+ uniIcons
27+ },
28+ props: {
29+ label: {
30+ type: String ,
31+ default: ' '
32+ },
33+ labelWidth: {
34+ type: String ,
35+ default: ' auto'
36+ },
37+ placeholder: {
38+ type: String ,
39+ default: ' '
40+ },
41+ candidates: {
42+ type: Array ,
43+ default () {
44+ return []
45+ }
46+ },
47+ emptyTips: {
48+ type: String ,
49+ default: ' 无匹配项'
50+ },
51+ value: {
52+ type: String ,
53+ default: ' '
54+ }
55+ },
56+ data () {
57+ return {
58+ showSelector: false ,
59+ inputVal: ' '
60+ }
61+ },
62+ computed: {
63+ labelStyle () {
64+ if (this .labelWidth === ' auto' ) {
65+ return {}
66+ }
67+ return {
68+ width: this .labelWidth
69+ }
70+ },
71+ filterCandidates () {
72+ return this .candidates .filter ((item ) => {
73+ return item .indexOf (this .inputVal ) > - 1
74+ })
75+ },
76+ filterCandidatesLength () {
77+ return this .filterCandidates .length
78+ }
79+ },
80+ watch: {
81+ value: {
82+ handler (newVal ) {
83+ this .inputVal = newVal
84+ },
85+ immediate: true
86+ }
87+ },
88+ methods: {
89+ toggleSelector () {
90+ this .showSelector = ! this .showSelector
91+ },
92+ onFocus () {
93+ setTimeout (() => {
94+ this .showSelector = true
95+ })
96+ },
97+ onBlur () {
98+ setTimeout (() => {
99+ this .showSelector = false
100+ })
101+ },
102+ onSelectorClick (index ) {
103+ this .inputVal = this .filterCandidates [index]
104+ this .showSelector = false
105+ this .$emit (' input' , this .inputVal )
106+ },
107+ onInput () {
108+ setTimeout (() => {
109+ this .$emit (' input' , this .inputVal )
110+ })
111+ }
112+ }
113+ }
114+ </script >
115+
116+ <style scoped>
117+ .uni-combox {
118+ /* #ifndef APP-NVUE */
119+ display : flex ;
120+ /* #endif */
121+ height : 40px ;
122+ flex-direction : row ;
123+ align-items : center ;
124+ /* border-bottom: solid 1px #DDDDDD;
125+ */
126+ }
127+
128+ .uni-combox__label {
129+ font-size : 16px ;
130+ padding-right : 10px ;
131+ color : #999999 ;
132+ }
133+
134+ .uni-combox__input-box {
135+ flex : 1 ;
136+ flex-direction : row ;
137+ align-items : center ;
138+ }
139+
140+ .uni-combox__input {
141+ flex : 1 ;
142+ font-size : 16px ;
143+ }
144+
145+ .uni-combox__input-arrow {
146+ padding : 10px ;
147+ }
148+
149+ .uni-combox__selector {
150+ flex-direction : column ;
151+ position : absolute ;
152+ top : 42px ;
153+ left : 0 ;
154+ width : 100% ;
155+ max-height : 200px ;
156+ overflow-y : auto ;
157+ padding : 10px ;
158+ background-color : #FFFFFF ;
159+ border-radius : 6px ;
160+ box-shadow : #DDDDDD 4px 4px 8px , #DDDDDD -4px -4px 8px ;
161+ z-index : 2 ;
162+ }
163+
164+ .uni-combox__selector ::before {
165+ content : ' ' ;
166+ position : absolute ;
167+ width : 0 ;
168+ height : 0 ;
169+ border-bottom : solid 6px #FFFFFF ;
170+ border-right : solid 6px transparent ;
171+ border-left : solid 6px transparent ;
172+ left : 50% ;
173+ top : -6px ;
174+ margin-left : -6px ;
175+ }
176+
177+ .uni-combox__selector-empty ,
178+ .uni-combox__selector-item {
179+ /* #ifdef APP-NVUE */
180+ display : flex ;
181+ /* #endif */
182+ line-height : 36px ;
183+ font-size : 14px ;
184+ text-align : center ;
185+ border-bottom : solid 1px #DDDDDD ;
186+ }
187+
188+ .uni-combox__selector-empty :last-child ,
189+ .uni-combox__selector-item :last-child {
190+ border-bottom : none ;
191+ }
192+ </style >
0 commit comments