123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- import { VantComponent } from '../common/component';
- import { addUnit } from '../common/utils';
- let ARRAY = [];
- VantComponent({
- field: true,
- relation: {
- name: 'dropdown-item',
- type: 'descendant',
- linked(target) {
- this.children = this.children || [];
- // 透传 props 给 dropdown-item
- const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.data;
- this.updateChildData(target, {
- overlay,
- duration,
- activeColor,
- closeOnClickOverlay,
- direction,
- childIndex: this.children.length
- });
- this.children.push(target);
- // 收集 dorpdown-item 的 data 挂在 data 上
- target &&
- this.setData({
- itemListData: this.data.itemListData.concat([target.data])
- });
- },
- unlinked(target) {
- this.children = this.children.filter((child) => child !== target);
- }
- },
- props: {
- activeColor: String,
- overlay: {
- type: Boolean,
- value: true
- },
- zIndex: {
- type: Number,
- value: 10
- },
- duration: {
- type: Number,
- value: 200
- },
- direction: {
- type: String,
- value: 'down'
- },
- closeOnClickOverlay: {
- type: Boolean,
- value: true
- },
- closeOnClickOutside: {
- type: Boolean,
- value: true
- }
- },
- data: {
- itemListData: []
- },
- created() {
- ARRAY.push(this);
- },
- destroyed() {
- ARRAY = ARRAY.filter(item => item !== this);
- },
- methods: {
- updateChildData(childItem, newData, needRefreshList = false) {
- childItem.setData(newData);
- if (needRefreshList) {
- // dropdown-item data 更新,涉及到 title 的展示,触发模板更新
- this.setData({ itemListData: this.data.itemListData });
- }
- },
- toggleItem(active) {
- this.children.forEach((item, index) => {
- const { showPopup } = item.data;
- if (index === active) {
- this.toggleChildItem(item);
- }
- else if (showPopup) {
- this.toggleChildItem(item, false, { immediate: true });
- }
- });
- },
- toggleChildItem(childItem, show, options = {}) {
- const { showPopup, duration } = childItem.data;
- if (show === undefined)
- show = !showPopup;
- if (show === showPopup) {
- return;
- }
- const newChildData = { transition: !options.immediate, showPopup: show };
- if (!show) {
- const time = options.immediate ? 0 : duration;
- this.updateChildData(childItem, Object.assign({}, newChildData), true);
- setTimeout(() => {
- this.updateChildData(childItem, { showWrapper: false }, true);
- }, time);
- return;
- }
- this.getChildWrapperStyle().then((wrapperStyle = '') => {
- this.updateChildData(childItem, Object.assign(Object.assign({}, newChildData), { wrapperStyle, showWrapper: true }), true);
- });
- },
- close() {
- this.children.forEach((item) => {
- this.toggleChildItem(item, false, { immediate: true });
- });
- },
- getChildWrapperStyle() {
- const { windowHeight } = wx.getSystemInfoSync();
- const { zIndex, direction } = this.data;
- let offset = 0;
- return this.getRect('.van-dropdown-menu').then(rect => {
- const { top = 0, bottom = 0 } = rect;
- if (direction === 'down') {
- offset = bottom;
- }
- else {
- offset = windowHeight - top;
- }
- let wrapperStyle = `z-index: ${zIndex};`;
- if (direction === 'down') {
- wrapperStyle += `top: ${addUnit(offset)};`;
- }
- else {
- wrapperStyle += `bottom: ${addUnit(offset)};`;
- }
- return Promise.resolve(wrapperStyle);
- });
- },
- onTitleTap(event) {
- // item ---> dropdown-item
- const { item, index } = event.currentTarget.dataset;
- if (!item.disabled) {
- // menuItem ---> dropdown-menu
- ARRAY.forEach(menuItem => {
- if (menuItem && menuItem.data.closeOnClickOutside && menuItem !== this) {
- menuItem.close();
- }
- });
- this.toggleItem(index);
- }
- }
- }
- });
|