Dropdown组件完整代码
wxml
html
<!-- 负责展示所有menu的title,控制menu的开合,通知子组件调用开合方法 -->
<view class="fty_dropdown_menu custom_class">
<view class="menu_body">
<view class="titles">
<!-- 左插槽 -->
<slot name="menu-left"></slot>
<!-- 菜单项 -->
<view
class='title'
style="{{ item.showDropdown ? 'color:' + activeColor : '' }}"
wx:for="{{dataList}}" wx:key="index"
data-index="{{index}}" bind:tap="onTitleTap"
>
{{item.triggerText}}
<view wx:if="{{item.showDropdown}}" class="arrow_up"></view>
<view wx:else class="arrow_down"></view>
</view>
<!-- 右插槽 -->
<slot name="menu-right"></slot>
</view>
<slot></slot>
</view>
</view>
js
js
const relationPath = '../fty-dropdownitem/fty-dropdownitem';
Component({
relations: {
[relationPath]: {
type: 'child', // 关联的目标节点应为子节点
linked: function (target) {
// 每次有custom-li被插入时执行,target是该节点实例对象,触发在该节点attached生命周期之后
},
linkChanged: function (target) {
// 每次有custom-li被移动后执行,target是该节点实例对象,触发在该节点moved生命周期之后
},
unlinked: function (target) {
// 每次有custom-li被移除时执行,target是该节点实例对象,触发在该节点detached生命周期之后
}
}
},
options: {
multipleSlots: true // 在组件定义时的选项中启用多slot支持
},
/**
* 组件:<custom-component class="my-class"></custom-component>
* 页面:<custom-component my-class="red-text" />
*/
externalClasses: ['custom_class'],
properties: {
activeColor: {
type: String,
value: '#5F00C9'
},
overlay: {
type: Boolean,
value: true
}
},
lifetimes: {
ready() {
// 获取父组件实例
Object.defineProperty(this, 'children', {
get: () => this.getRelationNodes(relationPath) || [],
});
// this.updateItemListData(); //子组件在更新展示项text后,会自动触发
},
},
data: {
dataList: [],
isOpen: false,
},
methods: {
/**
* 点击触发“展开”、“关闭”
* @param {*} e
*/
onTitleTap(e) {
const {
index
} = e.currentTarget.dataset;
this.children.map((item, idx) => {
if (idx != index) {
// 关闭其他所有子组件
item.close()
} else {
// 点击的子组件,连续切换
item.toggleDropdown((showDropdown) => {
this.setData({
isOpen: showDropdown
})
})
}
})
// 如果是展开的项,会高亮处理
this.updateItemListData();
},
/**
* 获取子组件的数据
*/
updateItemListData() {
var datas = this.children.map(item => item.data)
this.setData({
dataList: datas
})
}
}
})
wxss
css
.fty_dropdown_menu {
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
position: relative;
}
.menu_body {
background-color: #fff;
}
.titles {
display: flex;
justify-content: space-between;
align-items: flex-start;
padding: 20rpx 30rpx;
}
.title {
min-width: 100rpx;
max-width: 200rpx;
overflow: hidden;
font-size: 28rpx;
text-overflow: ellipsis;
white-space: nowrap;
}
.arrow_up {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-bottom: 14rpx solid #ddd;
display: inline-block;
}
.arrow_down {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 14rpx solid #ddd;
display: inline-block;
}