vant
Version:
Mobile UI Components built on Vue
210 lines (192 loc) • 5.18 kB
JavaScript
// Utils
import { createNamespace } from '../utils';
import { on, off } from '../utils/dom/event'; // Mixins
import { PortalMixin } from '../mixins/portal';
import { ChildrenMixin } from '../mixins/relation'; // Components
import Cell from '../cell';
import Icon from '../icon';
import Popup from '../popup';
var _createNamespace = createNamespace('dropdown-item'),
createComponent = _createNamespace[0],
bem = _createNamespace[1];
export default createComponent({
mixins: [PortalMixin({
ref: 'wrapper'
}), ChildrenMixin('vanDropdownMenu')],
props: {
value: null,
title: String,
disabled: Boolean,
titleClass: String,
options: {
type: Array,
default: function _default() {
return [];
}
},
lazyRender: {
type: Boolean,
default: true
}
},
data: function data() {
return {
transition: true,
showPopup: false,
showWrapper: false
};
},
computed: {
displayTitle: function displayTitle() {
var _this = this;
if (this.title) {
return this.title;
}
var match = this.options.filter(function (option) {
return option.value === _this.value;
});
return match.length ? match[0].text : '';
}
},
watch: {
showPopup: function showPopup(val) {
this.bindScroll(val);
}
},
beforeCreate: function beforeCreate() {
var _this2 = this;
var createEmitter = function createEmitter(eventName) {
return function () {
return _this2.$emit(eventName);
};
};
this.onOpen = createEmitter('open');
this.onClose = createEmitter('close');
this.onOpened = createEmitter('opened');
},
methods: {
// @exposed-api
toggle: function toggle(show, options) {
if (show === void 0) {
show = !this.showPopup;
}
if (options === void 0) {
options = {};
}
if (show === this.showPopup) {
return;
}
this.transition = !options.immediate;
this.showPopup = show;
if (show) {
this.parent.updateOffset();
this.showWrapper = true;
}
},
bindScroll: function bindScroll(bind) {
var scroller = this.parent.scroller;
var action = bind ? on : off;
action(scroller, 'scroll', this.onScroll, true);
},
onScroll: function onScroll() {
this.parent.updateOffset();
},
onClickWrapper: function onClickWrapper(event) {
// prevent being identified as clicking outside and closed when use get-contaienr
if (this.getContainer) {
event.stopPropagation();
}
}
},
render: function render() {
var _this3 = this;
var h = arguments[0];
var _this$parent = this.parent,
zIndex = _this$parent.zIndex,
offset = _this$parent.offset,
overlay = _this$parent.overlay,
duration = _this$parent.duration,
direction = _this$parent.direction,
activeColor = _this$parent.activeColor,
closeOnClickOverlay = _this$parent.closeOnClickOverlay;
var Options = this.options.map(function (option) {
var active = option.value === _this3.value;
return h(Cell, {
"attrs": {
"clickable": true,
"icon": option.icon,
"title": option.text
},
"key": option.value,
"class": bem('option', {
active: active
}),
"style": {
color: active ? activeColor : ''
},
"on": {
"click": function click() {
_this3.showPopup = false;
if (option.value !== _this3.value) {
_this3.$emit('input', option.value);
_this3.$emit('change', option.value);
}
}
}
}, [active && h(Icon, {
"class": bem('icon'),
"attrs": {
"color": activeColor,
"name": "success"
}
})]);
});
var style = {
zIndex: zIndex
};
if (direction === 'down') {
style.top = offset + "px";
} else {
style.bottom = offset + "px";
}
return h("div", [h("div", {
"directives": [{
name: "show",
value: this.showWrapper
}],
"ref": "wrapper",
"style": style,
"class": bem([direction]),
"on": {
"click": this.onClickWrapper
}
}, [h(Popup, {
"attrs": {
"overlay": overlay,
"position": direction === 'down' ? 'top' : 'bottom',
"duration": this.transition ? duration : 0,
"lazyRender": this.lazyRender,
"overlayStyle": {
position: 'absolute'
},
"closeOnClickOverlay": closeOnClickOverlay
},
"class": bem('content'),
"on": {
"open": this.onOpen,
"close": this.onClose,
"opened": this.onOpened,
"closed": function closed() {
_this3.showWrapper = false;
_this3.$emit('closed');
}
},
"model": {
value: _this3.showPopup,
callback: function callback($$v) {
_this3.showPopup = $$v;
}
}
}, [Options, this.slots('default')])])]);
}
});