Skip to content

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;
}

分析记录

Released under the MIT License.