feat: update transfer

pull/2682/head
tangjinzhou 2020-07-19 22:40:35 +08:00
parent 9cf6fe1c4e
commit a194bbdf43
10 changed files with 102 additions and 138 deletions

@ -1 +1 @@
Subproject commit e142c7f8cb2025c14d973691cfb90603e9790d46 Subproject commit 9df702457ee48468507ed7c6c1bf73758087f227

View File

@ -7,6 +7,7 @@ function noop() {}
export default { export default {
name: 'ListItem', name: 'ListItem',
inheritAttrs: false,
props: { props: {
renderedText: PropTypes.any, renderedText: PropTypes.any,
renderedEl: PropTypes.any, renderedEl: PropTypes.any,
@ -48,14 +49,12 @@ export default {
let children = null; let children = null;
if (lazy) { if (lazy) {
const lazyProps = { const lazyProps = {
props: { height: 32,
height: 32, offset: 500,
offset: 500, throttle: 0,
throttle: 0, debounce: false,
debounce: false, ...lazy,
...lazy, _propsSymbol: Symbol(),
_propsSymbol: Symbol(),
},
}; };
children = <Lazyload {...lazyProps}>{listItem}</Lazyload>; children = <Lazyload {...lazyProps}>{listItem}</Lazyload>;
} else { } else {

View File

@ -1,11 +1,6 @@
import { inject } from 'vue';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { import { hasProp, initDefaultProps, getOptionProps, getComponent } from '../_util/props-util';
hasProp,
initDefaultProps,
getOptionProps,
getComponentFromProp,
getListeners,
} from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import classNames from 'classnames'; import classNames from 'classnames';
import List from './list'; import List from './list';
@ -13,8 +8,6 @@ import Operation from './operation';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
import defaultLocale from '../locale-provider/default'; import defaultLocale from '../locale-provider/default';
import { ConfigConsumerProps } from '../config-provider'; import { ConfigConsumerProps } from '../config-provider';
import warning from '../_util/warning';
import Base from '../base';
export const TransferDirection = 'left' | 'right'; export const TransferDirection = 'left' | 'right';
@ -44,6 +37,7 @@ export const TransferProps = {
rowKey: PropTypes.func, rowKey: PropTypes.func,
lazy: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), lazy: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]),
showSelectAll: PropTypes.bool, showSelectAll: PropTypes.bool,
children: PropTypes.any,
}; };
export const TransferLocale = { export const TransferLocale = {
@ -55,6 +49,7 @@ export const TransferLocale = {
const Transfer = { const Transfer = {
name: 'ATransfer', name: 'ATransfer',
inheritAttrs: false,
mixins: [BaseMixin], mixins: [BaseMixin],
props: initDefaultProps(TransferProps, { props: initDefaultProps(TransferProps, {
dataSource: [], dataSource: [],
@ -62,13 +57,15 @@ const Transfer = {
showSearch: false, showSearch: false,
listStyle: () => {}, listStyle: () => {},
}), }),
inject: { setup() {
configProvider: { default: () => ConfigConsumerProps }, return {
configProvider: inject('configProvider', ConfigConsumerProps),
};
}, },
data() { data() {
// vue slot便notFoundContentsearchPlaceholder // vue slot便notFoundContentsearchPlaceholder
// warning( // warning(
// !(getComponentFromProp(this, 'notFoundContent') || hasProp(this, 'searchPlaceholder')), // !(getComponent(this, 'notFoundContent') || hasProp(this, 'searchPlaceholder')),
// 'Transfer[notFoundContent] and Transfer[searchPlaceholder] will be removed, ' + // 'Transfer[notFoundContent] and Transfer[searchPlaceholder] will be removed, ' +
// 'please use Transfer[locale] instead.', // 'please use Transfer[locale] instead.',
// ) // )
@ -124,7 +121,7 @@ const Transfer = {
const oldLocale = { const oldLocale = {
notFoundContent: renderEmpty('Transfer'), notFoundContent: renderEmpty('Transfer'),
}; };
const notFoundContent = getComponentFromProp(this, 'notFoundContent'); const notFoundContent = getComponent(this, 'notFoundContent');
if (notFoundContent) { if (notFoundContent) {
oldLocale.notFoundContent = notFoundContent; oldLocale.notFoundContent = notFoundContent;
} }
@ -238,14 +235,14 @@ const Transfer = {
handleFilter(direction, e) { handleFilter(direction, e) {
const value = e.target.value; const value = e.target.value;
if (getListeners(this).searchChange) { // if (getListeners(this).searchChange) {
warning( // warning(
false, // false,
'Transfer', // 'Transfer',
'`searchChange` in Transfer is deprecated. Please use `search` instead.', // '`searchChange` in Transfer is deprecated. Please use `search` instead.',
); // );
this.$emit('searchChange', direction, e); // this.$emit('searchChange', direction, e);
} // }
this.$emit('search', direction, value); this.$emit('search', direction, value);
}, },
@ -286,18 +283,18 @@ const Transfer = {
} }
}, },
handleSelect(direction, selectedItem, checked) { // handleSelect(direction, selectedItem, checked) {
warning(false, 'Transfer', '`handleSelect` will be removed, please use `onSelect` instead.'); // warning(false, 'Transfer', '`handleSelect` will be removed, please use `onSelect` instead.');
this.onItemSelect(direction, selectedItem.key, checked); // this.onItemSelect(direction, selectedItem.key, checked);
}, // },
handleLeftSelect(selectedItem, checked) { // handleLeftSelect(selectedItem, checked) {
return this.handleSelect('left', selectedItem, checked); // return this.handleSelect('left', selectedItem, checked);
}, // },
handleRightSelect(selectedItem, checked) { // handleRightSelect(selectedItem, checked) {
return this.handleSelect('right', selectedItem, checked); // return this.handleSelect('right', selectedItem, checked);
}, // },
onLeftItemSelect(selectedKey, checked) { onLeftItemSelect(selectedKey, checked) {
return this.onItemSelect('left', selectedKey, checked); return this.onItemSelect('left', selectedKey, checked);
@ -372,26 +369,27 @@ const Transfer = {
lazy, lazy,
showSelectAll, showSelectAll,
} = props; } = props;
const children = getComponentFromProp(this, 'children', {}, false); const { class: className, style } = this.$attrs;
const children = getComponent(this, 'children', {}, false);
const getPrefixCls = this.configProvider.getPrefixCls; const getPrefixCls = this.configProvider.getPrefixCls;
const prefixCls = getPrefixCls('transfer', customizePrefixCls); const prefixCls = getPrefixCls('transfer', customizePrefixCls);
const renderEmpty = this.configProvider.renderEmpty; const renderEmpty = this.configProvider.renderEmpty;
const locale = this.getLocale(transferLocale, renderEmpty); const locale = this.getLocale(transferLocale, renderEmpty);
const { sourceSelectedKeys, targetSelectedKeys, $scopedSlots } = this; const { sourceSelectedKeys, targetSelectedKeys, $slots } = this;
const { body, footer } = $scopedSlots; const { body, footer } = $slots;
const renderItem = props.render; const renderItem = props.render;
const { leftDataSource, rightDataSource } = this.separateDataSource(); const { leftDataSource, rightDataSource } = this.separateDataSource();
const leftActive = targetSelectedKeys.length > 0; const leftActive = targetSelectedKeys.length > 0;
const rightActive = sourceSelectedKeys.length > 0; const rightActive = sourceSelectedKeys.length > 0;
const cls = classNames(prefixCls, { const cls = classNames(prefixCls, className, {
[`${prefixCls}-disabled`]: disabled, [`${prefixCls}-disabled`]: disabled,
[`${prefixCls}-customize-list`]: !!children, [`${prefixCls}-customize-list`]: !!children,
}); });
const titles = this.getTitles(locale); const titles = this.getTitles(locale);
return ( return (
<div class={cls}> <div class={cls} style={style}>
<List <List
key="leftList" key="leftList"
prefixCls={`${prefixCls}-list`} prefixCls={`${prefixCls}-list`}
@ -402,7 +400,7 @@ const Transfer = {
checkedKeys={sourceSelectedKeys} checkedKeys={sourceSelectedKeys}
handleFilter={this.handleLeftFilter} handleFilter={this.handleLeftFilter}
handleClear={this.handleLeftClear} handleClear={this.handleLeftClear}
handleSelect={this.handleLeftSelect} // handleSelect={this.handleLeftSelect}
handleSelectAll={this.handleLeftSelectAll} handleSelectAll={this.handleLeftSelectAll}
onItemSelect={this.onLeftItemSelect} onItemSelect={this.onLeftItemSelect}
onItemSelectAll={this.onLeftItemSelectAll} onItemSelectAll={this.onLeftItemSelectAll}
@ -443,7 +441,7 @@ const Transfer = {
checkedKeys={targetSelectedKeys} checkedKeys={targetSelectedKeys}
handleFilter={this.handleRightFilter} handleFilter={this.handleRightFilter}
handleClear={this.handleRightClear} handleClear={this.handleRightClear}
handleSelect={this.handleRightSelect} // handleSelect={this.handleRightSelect}
handleSelectAll={this.handleRightSelectAll} handleSelectAll={this.handleRightSelectAll}
onItemSelect={this.onRightItemSelect} onItemSelect={this.onRightItemSelect}
onItemSelectAll={this.onRightItemSelectAll} onItemSelectAll={this.onRightItemSelectAll}
@ -471,16 +469,15 @@ const Transfer = {
<LocaleReceiver <LocaleReceiver
componentName="Transfer" componentName="Transfer"
defaultLocale={defaultLocale.Transfer} defaultLocale={defaultLocale.Transfer}
scopedSlots={{ default: this.renderTransfer }} children={this.renderTransfer}
/> />
); );
}, },
}; };
/* istanbul ignore next */ /* istanbul ignore next */
Transfer.install = function(Vue) { Transfer.install = function(app) {
Vue.use(Base); app.component(Transfer.name, Transfer);
Vue.component(Transfer.name, Transfer);
}; };
export default Transfer; export default Transfer;

View File

@ -1,12 +1,11 @@
import classNames from 'classnames'; import classNames from 'classnames';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { isValidElement, initDefaultProps, getListeners } from '../_util/props-util'; import { isValidElement, initDefaultProps, splitAttrs } from '../_util/props-util';
import BaseMixin from '../_util/BaseMixin'; import BaseMixin from '../_util/BaseMixin';
import Checkbox from '../checkbox'; import Checkbox from '../checkbox';
import Search from './search'; import Search from './search';
import defaultRenderList from './renderListBody'; import defaultRenderList from './renderListBody';
import triggerEvent from '../_util/triggerEvent'; import triggerEvent from '../_util/triggerEvent';
import addEventListener from '../vc-util/Dom/addEventListener';
const defaultRender = () => null; const defaultRender = () => null;
@ -51,11 +50,11 @@ export const TransferListProps = {
showSelectAll: PropTypes.bool, showSelectAll: PropTypes.bool,
}; };
function renderListNode(h, renderList, props) { function renderListNode(renderList, props) {
let bodyContent = renderList ? renderList(props) : null; let bodyContent = renderList ? renderList(props) : null;
const customize = !!bodyContent; const customize = !!bodyContent;
if (!customize) { if (!customize) {
bodyContent = defaultRenderList(h, props); bodyContent = defaultRenderList(props);
} }
return { return {
customize, customize,
@ -66,6 +65,7 @@ function renderListNode(h, renderList, props) {
export default { export default {
name: 'TransferList', name: 'TransferList',
mixins: [BaseMixin], mixins: [BaseMixin],
inheritAttrs: false,
props: initDefaultProps(TransferListProps, { props: initDefaultProps(TransferListProps, {
dataSource: [], dataSource: [],
titleText: '', titleText: '',
@ -79,19 +79,6 @@ export default {
filterValue: '', filterValue: '',
}; };
}, },
// mounted() {
// this.timer = setTimeout(() => {
// this.setState({
// mounted: true,
// });
// }, 0);
// this.$nextTick(() => {
// if (this.$refs.listContentWrapper) {
// const listContentWrapperDom = this.$refs.listContentWrapper.$el;
// this.scrollEvent = addEventListener(listContentWrapperDom, 'scroll', this.handleScroll);
// }
// });
// },
beforeUnmount() { beforeUnmount() {
clearTimeout(this.triggerScrollTimer); clearTimeout(this.triggerScrollTimer);
// if (this.scrollEvent) { // if (this.scrollEvent) {
@ -103,10 +90,6 @@ export default {
if (this.scrollEvent) { if (this.scrollEvent) {
this.scrollEvent.remove(); this.scrollEvent.remove();
} }
if (this.$refs.listContentWrapper) {
const listContentWrapperDom = this.$refs.listContentWrapper.$el;
this.scrollEvent = addEventListener(listContentWrapperDom, 'scroll', this.handleScroll);
}
}); });
}, },
methods: { methods: {
@ -173,10 +156,13 @@ export default {
let listBody = bodyDom; let listBody = bodyDom;
if (!listBody) { if (!listBody) {
let bodyNode; let bodyNode;
const { onEvents } = splitAttrs(this.$attrs);
const { bodyContent, customize } = renderListNode(renderList, { const { bodyContent, customize } = renderListNode(renderList, {
props: { ...this.$props, filteredItems, filteredRenderItems, selectedKeys: checkedKeys }, ...this.$props,
on: getListeners(this), filteredItems,
filteredRenderItems,
selectedKeys: checkedKeys,
...onEvents,
}); });
// We should wrap customize list body in a classNamed div to use flex layout. // We should wrap customize list body in a classNamed div to use flex layout.
@ -334,7 +320,7 @@ export default {
const checkAllCheckbox = this.getCheckBox(filteredItems, showSelectAll, disabled); const checkAllCheckbox = this.getCheckBox(filteredItems, showSelectAll, disabled);
return ( return (
<div class={listCls}> <div class={listCls} style={this.$attrs.style}>
<div class={`${prefixCls}-header`}> <div class={`${prefixCls}-header`}>
{checkAllCheckbox} {checkAllCheckbox}
<span class={`${prefixCls}-header-selected`}> <span class={`${prefixCls}-header-selected`}>

View File

@ -1,56 +1,35 @@
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined'; import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
import RightOutlined from '@ant-design/icons-vue/RightOutlined'; import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import PropTypes from '../_util/vue-types';
import { getOptionProps } from '../_util/props-util';
import Button from '../button'; import Button from '../button';
function noop() {} function noop() {}
export const TransferOperationProps = { const Operation = (_, { attrs }) => {
className: PropTypes.string, const {
leftArrowText: PropTypes.string, disabled,
rightArrowText: PropTypes.string, moveToLeft = noop,
moveToLeft: PropTypes.any, moveToRight = noop,
moveToRight: PropTypes.any, leftArrowText = '',
leftActive: PropTypes.bool, rightArrowText = '',
rightActive: PropTypes.bool, leftActive,
disabled: PropTypes.bool, rightActive,
}; class: className,
style,
} = attrs;
export default { return (
name: 'Operation', <div class={className} style={style}>
props: { ...TransferOperationProps }, <Button type="primary" size="small" disabled={disabled || !rightActive} onClick={moveToRight}>
render() { <RightOutlined slot="icon" />
const { {rightArrowText}
disabled, </Button>
moveToLeft = noop, <Button type="primary" size="small" disabled={disabled || !leftActive} onClick={moveToLeft}>
moveToRight = noop, <LeftOutlined slot="icon" />
leftArrowText = '', {leftArrowText}
rightArrowText = '', </Button>
leftActive, </div>
rightActive, );
} = getOptionProps(this);
return (
<div>
<Button
type="primary"
size="small"
disabled={disabled || !rightActive}
onClick={moveToRight}
>
<RightOutlined slot="icon" />
{rightArrowText}
</Button>
<Button
type="primary"
size="small"
disabled={disabled || !leftActive}
onClick={moveToLeft}
>
<LeftOutlined slot="icon" />
{leftArrowText}
</Button>
</div>
);
},
}; };
Operation.inheritAttrs = false;
export default Operation;

View File

@ -1,3 +1,4 @@
import { TransitionGroup } from 'vue';
import raf from '../_util/raf'; import raf from '../_util/raf';
import ListItem from './ListItem'; import ListItem from './ListItem';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
@ -91,18 +92,16 @@ const ListBody = {
mounted ? `${prefixCls}-content-item-highlight` : '', mounted ? `${prefixCls}-content-item-highlight` : '',
{ {
tag: 'ul', tag: 'ul',
nativeOn: { onScroll: this.onScroll,
scroll: this.onScroll, onLeave: noop,
},
leave: noop,
}, },
); );
return ( return (
<transition-group class={`${prefixCls}-content`} {...transitionProps}> <TransitionGroup class={`${prefixCls}-content`} {...transitionProps}>
{items} {items}
</transition-group> </TransitionGroup>
); );
}, },
}; };
export default (h, props) => <ListBody {...props} />; export default props => <ListBody {...props} />;

View File

@ -14,6 +14,7 @@ export const TransferSearchProps = {
export default { export default {
name: 'Search', name: 'Search',
inheritAttrs: false,
props: initDefaultProps(TransferSearchProps, { props: initDefaultProps(TransferSearchProps, {
placeholder: '', placeholder: '',
}), }),

View File

@ -482,6 +482,7 @@ const Tree = {
}); });
} }
this.$emit('update:checkedKeys', checkedObj); this.$emit('update:checkedKeys', checkedObj);
this.__emit('check', checkedObj, eventObj); this.__emit('check', checkedObj, eventObj);
}, },
onNodeLoad(treeNode) { onNodeLoad(treeNode) {

View File

@ -29,6 +29,7 @@ import {
Avatar, Avatar,
Tree, Tree,
TreeSelect, TreeSelect,
Transfer,
notification, notification,
message, message,
} from 'ant-design-vue'; } from 'ant-design-vue';
@ -46,11 +47,11 @@ const app = createApp(App);
app.config.globalProperties.$notification = notification; app.config.globalProperties.$notification = notification;
app.config.globalProperties.$message = message; app.config.globalProperties.$message = message;
app app
// .component('demo-sort', { ...basic }) .component('demo-sort', { ...basic })
// .component('md', { ...basic }) .component('md', { ...basic })
// .component('api', { ...basic }) .component('api', { ...basic })
// .component('CN', { ...basic }) .component('CN', { ...basic })
// .component('US', { ...basic }) .component('US', { ...basic })
.use(Pagination) .use(Pagination)
.use(Select) .use(Select)
.use(Spin) .use(Spin)
@ -78,4 +79,5 @@ app
.use(Card) .use(Card)
.use(Tree) .use(Tree)
.use(TreeSelect) .use(TreeSelect)
.use(Transfer)
.mount('#app'); .mount('#app');

View File

@ -76,7 +76,7 @@
"@commitlint/config-conventional": "^8.0.0", "@commitlint/config-conventional": "^8.0.0",
"@octokit/rest": "^16.0.0", "@octokit/rest": "^16.0.0",
"@vue/cli-plugin-eslint": "^4.0.0", "@vue/cli-plugin-eslint": "^4.0.0",
"@vue/compiler-sfc": "^3.0.0-beta.21", "@vue/compiler-sfc": "^3.0.0-rc.1",
"@vue/server-test-utils": "1.0.0-beta.16", "@vue/server-test-utils": "1.0.0-beta.16",
"@vue/test-utils": "^2.0.0-alpha.6", "@vue/test-utils": "^2.0.0-alpha.6",
"acorn": "^7.0.0", "acorn": "^7.0.0",
@ -152,7 +152,7 @@
"terser-webpack-plugin": "^3.0.3", "terser-webpack-plugin": "^3.0.3",
"through2": "^3.0.0", "through2": "^3.0.0",
"url-loader": "^3.0.0", "url-loader": "^3.0.0",
"vue": "^3.0.0-beta.21", "vue": "^3.0.0-rc.1",
"vue-antd-md-loader": "^1.1.0", "vue-antd-md-loader": "^1.1.0",
"vue-clipboard2": "0.3.1", "vue-clipboard2": "0.3.1",
"vue-draggable-resizable": "^2.1.0", "vue-draggable-resizable": "^2.1.0",