⼩程序之⾃定义select下拉选项框组件
知识点:组件,animation,获取当前点击元素的索引与内容
⼩程序中没有select下拉选项框,所以只有⾃定义。⾃定义的话,可以选择模板的⽅式,也可以选择组件的⽅式来创建。
这次我选择了组件,这样只需引⼊组件和添加数据,其它的不⽤管,就能实现多个地⽅重复使⽤了。
第⼀步:创建组件所需的⽂件
我喜欢把共⽤的内容都放在和pages⽂件同级的地⽅,所以有了下⾯的⽬录结构
(1)先创建⼀个⾃定义名字的⽂件夹,例如我上⾯的Componet
(2)再创建⼀个select⽂件夹,然后:右键这个⽂件夹,新建下⾯的这个Component。然后输⼊需要创建的名称,我这⾥为了⽅便就取了select的名字。然后就会⾃动创建4个⽂件,js、json、wxml、wxss。
第⼆步:开始配置组件
注意:如果通过第⼀步创建的可直接跳过第⼆步。
(1)通过第⼀步创建的组件的⽂件夹中,已经⾃动配置好了。只需在引⼊组件的时候,在引⼊组件的页⾯的json⽂件中配置组件的名称和组件的位置。
(2)如果⾃⼰⼿动创建组件的js、json、wxml、wxss这个⽂件,那么需要在json⽂件中填⼊"component": true表⽰⾃定义组件声明。js⽂件中也需要写成这种格式:
Component({
properties: {
// 这⾥定义了innerText属性,属性值可以在组件使⽤时指定
innerText: {
type: String,
value: 'default value',
}
},
data: {
// 这⾥是⼀些组件内部数据
someData: {}
},
methods: {
// 这⾥是⼀个⾃定义⽅法
customMethod: function(){}
}
})
第三步:⾃定义组件样式及js。
注意:这⾥可以在 app.json 的 pages 中把组件所在的页⾯放到第⼀位,这样就能在组件的页⾯编写代码了,⽐如我上⾯的⽬录结构:就需要写成"Componet/select/select", 后⾯再是其它的页⾯。这样⽅便得多。
1. 组件的wxml
<view class='com-selectBox'>
<view class='com-sContent' bindtap='selectToggle'>
<view class='com-sTxt'>{{nowText}}</view>
<image src='../../public/img/local/down.png'  class='com-sImg'  animation="{{animationData}}"></image>
</view>
<view class='com-sList' wx:if="{{selectShow}}">
<view wx:for="{{propArray}}" data-index="{{index}}" wx:key='' class='com-sItem' bindtap='setText'>{{}}</view>
</view>
</view>
(1)animation="{{animationData}}"这个是下箭头的动画效果
(2)data-index="{{index}}"这个是当前元素被点击时的索引
(3) selectToggle是模仿下拉选项框隐藏和显⽰的事件。
(4) setText是模仿下拉选项框选择⼦项之后,设置内容的事件。
(5) selectShow是表⽰option选项显⽰与否
2. 组件的wxss
-selectBox{
width: 200px;
}
-sContent{
border: 1px solid #e2e2e2;
background: white;
font-size: 16px;
position: relative;
height: 30px;
line-height: 30px;
}
-sImg{
position: absolute;
right: 10px;
top: 11px;
width: 16px;
height: 9px;
transition: all .3s ease;
}
.
com-sTxt{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding:0 20px 0 6px;
font-size: 14px;
}
-sList{
background: white;
width: inherit;
position: absolute;
border: 1px solid #e2e2e2;
border-top: none;
box-sizing: border-box;
z-index: 3;
max-height: 120px;
overflow: auto;
}
-sItem{
height: 30px;
line-height: 30px;
border-top: 1px solid #e2e2e2;
padding: 0 6px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 14px;
}
-sItem:first-child{
border-top: none;
}
3. 组件的 js
/
/ Componet/Componet.js
Component({
/**
* 组件的属性列表
*/
properties: {
propArray:{
type:Array,
}
},
/**
* 组件的初始数据
*/
data: {
selectShow:false,//初始option不显⽰
nowText:"请选择",//初始内容
animationData:{}//右边箭头的动画
},
/**
* 组件的⽅法列表
*/
methods: {
   //option的显⽰与否
selectToggle:function(){
var nowShow=this.data.selectShow;//获取当前option显⽰的状态
//创建动画
var animation = wx.createAnimation({
timingFunction:"ease"
})
this.animation=animation;
if(nowShow){
this.setData({
animationData: port()
})
}else{
this.setData({
animationData: port()
})
}
this.setData({
selectShow: !nowShow
})
},
//设置内容
setText:function(e){
var nowData = this.properties.propArray;//当前option的数据是引⼊组件的页⾯传过来的,所以这⾥获取数据只有通过this.properties
var nowIdx = e.target.dataset.index;//当前点击的索引
var nowText = nowData[nowIdx].text;//当前点击的内容
//再次执⾏动画,注意这⾥⼀定,⼀定,⼀定是this.animation来使⽤动画
ate(0).step();
this.setData({
selectShow: false,
nowText:nowText,
animationData: port()
})
}
}
})
(1)组件的 properties 属性是对外属性,我理解的是可以当做 data 数据来使⽤,它是⼀个含有三个属性的对象,分别是 type 表⽰属性类型、 value 表⽰属性初始值、 observer 表⽰属性值被更改时的响应函数。type 是必填的,其它的可选。如果只有 type,可以写成:属性名:type类型。
(2)组件的 data 和普通页⾯的data⼀样,是组件的内部数据,和 properties ⼀同⽤于组件的模版渲染。html animation属性
(3)组件的 method 是专门⽤于事件响应函数和任意的⾃定义⽅法。在这⾥⾯获取数据有两种⽅法:⼀种是获取data⾥的数据:this.data.属性名;⼀种是获取 properties 中的属性值: this.properties.属性名
(4)创建animation动画,作⽤在通过 true 和 false 切换显⽰状态的内容上没有过渡、没有过渡、没有过渡。
第四步:引⼊组件,传⼊组件所需数据
1. 引⼊前,需要在引⼊组件的页⾯的json⽂件中配置,⽐如我要在 index.wxml 中引⼊,那么在 index.json 中我就需要配置:"usingComponents": {
"Select": "/Componet/select/select"
}
(1)Select是你定义的组件的名称,后⾯的是组件所在的位置。 /  单斜杠表⽰根⽬录,是绝对路径。
(2)如果出现下⾯这种说没到路径的,⼀定是⾃⼰填写的路径不对,认真查。
2. 配置好后,就可以引⼊组件。
<Select prop-array='{{selectArray}}'></Select>
(1) prop-array 是我⾃定义的属性名,这个是和组件所在的 js 中properties中的属性是对应的。在properties定义的属性中,属性名采⽤驼峰写法(例如:propArray);在引⼊组件的wxml中,指定属性值时则对应使⽤连字符写法(例如:prop-array="...")。
3. 最后就是传⼊数据了。在引⼊组件的js的data中,添加:
selectArray: [{
"id": "10",
"text": "会计类"
}, {
"id": "21",
"text": "⼯程类"
}]
最终结果:
如果引⼊两个相同的组件,传⼊的数据也相同:
<Select prop-array='{{selectArray}}'></Select>
<Select prop-array='{{selectArray}}'></Select>
这样的⽅式组件并不会相互影响,都是独⽴的。
对了,组件样式的规则可以查看
第五步:获取点击的内容,即组件间的通信
效果有了,最关键的是获取选中的内容。这个怎么实现呢,这时候需要了。
1. 对组件的事件进⾏监听:
<Select prop-array='{{selectArray}}' bind:myget='getDate'></Select>
(1)这⾥myget是⾃定义的⼦组件需要触发的事件名,getDate是引⼊组件的页⾯需要获取传过来的数据的⾃定义的事件名。
2. ⼦组件触发事件
因为这⾥的select组件是点击下拉列表的内容才进⾏内容的更新,所以这⾥只需要在下拉列表⾥添加⼀个点击事件,⽽原来已经设置了setText事件。所以只需要在setText函数⾥⾯写触发事件就⾏了。
在setText函数的内容⾥加上:
var nowDate={
id:nowIdx,
text:nowText
}
(1)这⾥的 myget 和 bind:myget ,名称⼀定要对应。
(2) nowDate是需要传回的数据,不⼀定要弄成对象,想传什么传什么,我这⾥只是演⽰⽽已。我试了⼀下也可以传函数。。。
3. 引⼊组件的页⾯的js
添加引⼊组件时,⾃定义的函数:
getDate:function(e){
console.log(e.detail)
}
e的内容为:
传过来的值就在detail⾥⾯。
到此,⼀个完整的select组件就完成了。
更新:
如果要select组件默认显⽰传⼊的第⼀个数据,做法是:
(1)在select组件的wxml页⾯,在class为com-sTxt的view标签中,原来的 {{ nowText }} 改为 {{ nowText==' ' ? propArray[0].text : nowText }}。
(2)然后在 select 组件 js⽂件中原来nowText的值修改为 ‘ ’ 空。
(3)这样的话就表⽰如果最初nowText为空,就显⽰传⼊数据的第⼀个值,否则就是选中的值

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。