UNPKG

vue-ant-patterns

Version:

vue-ant-patterns

320 lines (297 loc) 10 kB
import _mergeJSXProps from 'babel-helper-vue-jsx-merge-props'; import _defineProperty from 'babel-runtime/helpers/defineProperty'; import _extends from 'babel-runtime/helpers/extends'; import _typeof from 'babel-runtime/helpers/typeof'; import PropTypes from 'ant-design-vue/es/_util/vue-types'; import { filterEmpty } from 'ant-design-vue/es/_util/props-util'; import LocaleReceiver from 'ant-design-vue/es/locale-provider/LocaleReceiver'; import { AutoComplete } from 'ant-design-vue'; import Icon from '../d-icon'; import IconButton from '../d-icon-button'; import Container from '../d-container'; import debounce from 'debounce'; import zhCN from '../d-language/global/zh_CN'; var Option = AutoComplete.Option, AutoCompleteProps = AutoComplete.props; var Horizontal = Container.Horizontal; var DataSourceItemObject = PropTypes.shape({ value: String, text: String }).loose; var DataSourceItemType = PropTypes.oneOfType([PropTypes.string, DataSourceItemObject]).isRequired; var noop = function noop() {}; var DAutoComplete = { name: 'DAutoComplete', props: { prefixCls: PropTypes.string.def('depot-auto-complete'), locale: PropTypes.object, dataSource: PropTypes.arrayOf(DataSourceItemType), dropdownMatchSelectWidth: PropTypes.bool, dropdownStyle: PropTypes.object, inputWidth: PropTypes.string.def('300px'), optionLabelProp: PropTypes.string.def('title'), autoFocus: PropTypes.bool.def(true), tagItemList: PropTypes.array.def([]), dropdownClassName: PropTypes.string.def(''), showFilter: PropTypes.bool.def(true) // renderKeys: PropTypes.shape({ // text: 'name', // value: 'name', // key: 'id', // }), }, watch: { tagItemList: function tagItemList(newVal, oldVal) { this.localTagItemList = newVal; } }, created: function created() { // const { $listeners } = this; this.debounceChange = debounce(this.handlerChange, 300); this.debounceSearch = debounce(this.handlerSearch, 400); }, data: function data() { var tagItemList = this.$props.tagItemList; return { showInput: false, show: true, events: {}, currentEvent: '', localTagItemList: tagItemList, // 标签 searchVal: '' // 双向绑定的变化 }; }, methods: { renderOptions: function renderOptions() { var h = this.$createElement; var $slots = this.$slots, dataSource = this.dataSource; var childArray = filterEmpty($slots['default']); var options = void 0; if (childArray.length) { options = childArray; } else { options = dataSource ? dataSource.map(function (item) { switch (typeof item === 'undefined' ? 'undefined' : _typeof(item)) { case 'string': return h( Option, { key: item }, [item] ); case 'object': return h( Option, { key: item.value }, [item.text] ); default: throw new Error('AutoComplete[dataSource] only supports type `string[] | Object[]`.'); } }) : []; } return options; }, getDefaultLocale: function getDefaultLocale() { var result = _extends({}, zhCN, this.locale); result.lang = _extends({}, result.lang, (this.locale || {}).lang); return result; }, open: function open() { this.showInput = !this.showInput; }, close: function close() { this.showInput = false; }, handlerChange: function handlerChange(val) { if (val === undefined) { this.$emit('clear'); return; } this.$emit('change', val); }, handlerSearch: function handlerSearch(val) { this.$emit('search', val); }, // 移除标签 handleTagRemoveClick: function handleTagRemoveClick(obj) { this.$emit('removeTag', obj); this.$refs.autoref.focus(); // 手动触发焦点,否则失去焦点,搜索框不显示了 }, // 清空输入框的值 clearVal: function clearVal() { this.searchVal = ''; this.$emit('change', ''); }, renderComponent: function renderComponent(contextLocale, locale) { var _props, _this = this; var h = this.$createElement; var $slots = this.$slots, $listeners = this.$listeners, showInput = this.showInput, show = this.show, localTagItemList = this.localTagItemList, searchVal = this.searchVal, showFilter = this.showFilter; var _$props = this.$props, prefixCls = _$props.prefixCls, dataSource = _$props.dataSource, inputWidth = _$props.inputWidth, optionLabelProp = _$props.optionLabelProp, autoFocus = _$props.autoFocus; var buttonStr = showInput ? 'close' : 'search'; var title = showInput ? contextLocale['close'] || '关闭' : contextLocale['search'] || '搜索'; var props = { 'class': prefixCls }; // const transitionCls = var inputProps = { ref: 'autoref', 'class': prefixCls + '-input', props: (_props = { placeholder: contextLocale.searchPlaceholder, optionLabelProp: optionLabelProp, allowClear: true, dropdownClassName: prefixCls + '-overlay', dropdownMatchSelectWidth: this.$props.dropdownMatchSelectWidth, dropdownStyle: this.$props.dropdownStyle }, _defineProperty(_props, 'dropdownClassName', this.$props.dropdownClassName ? this.$props.dropdownClassName + ' ' + prefixCls + '-overlay' : prefixCls + '-overlay'), _defineProperty(_props, 'autoFocus', autoFocus), _defineProperty(_props, 'value', searchVal), _props), on: { change: function change(val) { /* ant vue 在触发 select 事件后也会触发 change 事件 正常应该是如果事件为 select, 就不在处理 change 了 */ if (_this.currentEvent === 'select') { _this.currentEvent = ''; return; } _this.debounceChange(val); }, select: function select(value, option) { _this.currentEvent = 'select'; _this.searchVal = ''; /* ant vue 组件问题, 偶尔会出现选中节点后光标位置不准缺的问题 临时解决方法: 丢失焦点 */ setTimeout(function () { if (_this.$refs && _this.$refs.autoref) { _this.$refs.autoref.blur(); } _this.showInput = false; }, 200); _this.$emit('select', value, option); }, search: function search(val) { _this.debounceSearch(val); _this.searchVal = val; }, blur: function blur() { _this.showInput = false; _this.$emit('blur'); } }, style: { width: inputWidth } }; var iconProps = { key: 'header-search', attrs: { title: title }, on: { click: function click() { _this.open(); } } }; var filterIconProps = { 'class': 'filter-search-icon', on: { click: function click(e) { e.stopPropagation(); var searchVal = _this.searchVal, localTagItemList = _this.localTagItemList; _this.$emit('filter', searchVal, localTagItemList); } } }; return h( Horizontal, _mergeJSXProps([{ attrs: { align: 'center', justify: 'start' } }, props]), [h( 'transition', { attrs: { name: 'headrSearchMove' } }, [showInput ? h( AutoComplete, inputProps, [h( 'template', { slot: 'dataSource' }, [this.renderOptions()] ), h('a-input', [h( 'template', { slot: 'addonBefore' }, [h( 'ul', { 'class': 'item-tag-wrapper-ul' }, [localTagItemList.map(function (item) { return h( 'li', { 'class': 'item-li', key: '' + item.labelId }, [h( 'span', { 'class': 'item-name', attrs: { title: item.showValue } }, [item.showValue] ), h( 'span', { 'class': 'remove-item-icon', on: { 'click': function click(e) { e.stopPropagation(); _this.handleTagRemoveClick(item); } } }, [h('a-icon', { attrs: { type: 'close' } })] )] ); })] )] ), showFilter ? h('a-icon', _mergeJSXProps([{ slot: 'suffix', attrs: { type: 'filter' } }, filterIconProps])) : null])] ) : null] ), h( IconButton, iconProps, [h(Icon, { attrs: { type: buttonStr } })] )] ); } }, render: function render() { var h = arguments[0]; return h(LocaleReceiver, { attrs: { componentName: 'Global', defaultLocale: this.getDefaultLocale }, scopedSlots: { 'default': this.renderComponent } }); } }; DAutoComplete.install = function (Vue) { Vue.component(DAutoComplete.name, DAutoComplete); }; export default DAutoComplete;