Skip to content

Commit 3459512

Browse files
committed
update(uni-ui): 新增组合框组件
1 parent c798e9b commit 3459512

File tree

5 files changed

+362
-4
lines changed

5 files changed

+362
-4
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
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>

components/uni-section/uni-section.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<view class="uni-section">
2+
<view class="uni-section" nvue>
33
<view v-if="type" class="uni-section__head">
44
<view :class="type" class="uni-section__head-tag" />
55
</view>

pages.json

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -873,15 +873,27 @@
873873
},
874874
{
875875
"path": "transition/transition",
876-
"style": {}
876+
"style": {
877+
"navigationBarTitleText": "Transition 过渡动画"
878+
}
877879
},
878880
{
879881
"path": "title/title",
880-
"style": {}
882+
"style": {
883+
"navigationBarTitleText": "Title 章节标题"
884+
}
881885
},
882886
{
883887
"path": "link/link",
884-
"style": {}
888+
"style": {
889+
"navigationBarTitleText": "Link 链接"
890+
}
891+
},
892+
{
893+
"path": "combox/combox",
894+
"style": {
895+
"navigationBarTitleText": "Combox 组合框"
896+
}
885897
}
886898
]
887899
},

pages/extUI/combox/combox.vue

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
<template>
2+
<view class="page">
3+
<text class="example-info">组合框一般用于可以选择也可以输入的表单项</text>
4+
<uni-section title="基本用法" type="line"></uni-section>
5+
<view class="example-body">
6+
<uni-combox label="所在城市" :candidates="candidates" placeholder="请选择所在城市" v-model="city"></uni-combox>
7+
<view class="result-box">
8+
<text>所选城市为:{{city}}</text>
9+
</view>
10+
</view>
11+
<uni-section title="设置label宽度" type="line"></uni-section>
12+
<view class="example-body">
13+
<uni-combox label="所在城市" labelWidth="150px" :candidates="candidates" placeholder="请选择所在城市"></uni-combox>
14+
</view>
15+
<uni-section title="设置无匹配项时的提示语" type="line"></uni-section>
16+
<view class="example-body">
17+
<uni-combox label="所在城市" emptyTips="这里啥都没有" placeholder="请选择所在城市"></uni-combox>
18+
</view>
19+
</view>
20+
</template>
21+
22+
<script>
23+
import uniCombox from '@/components/uni-combox/uni-combox.vue'
24+
import uniSection from '@/components/uni-section/uni-section.vue'
25+
export default {
26+
components: {
27+
uniCombox,
28+
uniSection
29+
},
30+
data() {
31+
return {
32+
candidates: ['北京', '南京', '东京', '武汉', '天津', '上海', '海口'],
33+
city: ''
34+
}
35+
},
36+
methods: {
37+
38+
}
39+
}
40+
</script>
41+
42+
<style>
43+
/* 头条小程序组件内不能引入字体 */
44+
/* #ifdef MP-TOUTIAO */
45+
@font-face {
46+
font-family: uniicons;
47+
font-weight: normal;
48+
font-style: normal;
49+
src: url('~@/static/uni.ttf') format('truetype');
50+
}
51+
52+
/* #endif */
53+
54+
/* #ifndef APP-NVUE */
55+
page {
56+
display: flex;
57+
flex-direction: column;
58+
box-sizing: border-box;
59+
background-color: #efeff4;
60+
min-height: 100%;
61+
height: auto;
62+
}
63+
64+
view {
65+
font-size: 14px;
66+
line-height: inherit;
67+
}
68+
69+
.example {
70+
padding: 0 15px 15px;
71+
}
72+
73+
.example-info {
74+
padding: 15px;
75+
color: #3b4144;
76+
background: #ffffff;
77+
}
78+
79+
.example-body {
80+
flex-direction: row;
81+
flex-wrap: wrap;
82+
justify-content: center;
83+
padding: 0;
84+
font-size: 14px;
85+
background-color: #ffffff;
86+
}
87+
88+
/* #endif */
89+
.example {
90+
padding: 0 15px;
91+
}
92+
93+
.example-info {
94+
/* #ifndef APP-NVUE */
95+
display: block;
96+
/* #endif */
97+
padding: 15px;
98+
color: #3b4144;
99+
background-color: #ffffff;
100+
font-size: 14px;
101+
line-height: 20px;
102+
}
103+
104+
.example-info-text {
105+
font-size: 14px;
106+
line-height: 20px;
107+
color: #3b4144;
108+
}
109+
110+
111+
.example-body {
112+
flex-direction: column;
113+
padding: 15px;
114+
background-color: #ffffff;
115+
}
116+
117+
.word-btn-white {
118+
font-size: 18px;
119+
color: #FFFFFF;
120+
}
121+
122+
.word-btn {
123+
/* #ifndef APP-NVUE */
124+
display: flex;
125+
/* #endif */
126+
flex-direction: row;
127+
align-items: center;
128+
justify-content: center;
129+
border-radius: 6px;
130+
height: 48px;
131+
margin: 15px;
132+
background-color: #007AFF;
133+
}
134+
135+
.word-btn--hover {
136+
background-color: #4ca2ff;
137+
}
138+
139+
140+
.example-body {
141+
padding: 0px 12px;
142+
background-color: #FFFFFF;
143+
}
144+
145+
.result-box {
146+
text-align: center;
147+
padding: 20px 0px;
148+
font-size: 16px;
149+
}
150+
</style>

pages/tabBar/extUI/extUI.nvue

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@
4040
name: "Collapse 折叠面板",
4141
url: "collapse"
4242
},
43+
{
44+
name: "Combox 组合框",
45+
url: "combox"
46+
},
4347
{
4448
name: "Countdown 倒计时",
4549
url: "countdown"

0 commit comments

Comments
 (0)