feat: upadate transfer
parent
44d55b329d
commit
86bbeff161
|
@ -19,8 +19,10 @@ The most basic usage of `Transfer` involves providing the source data and target
|
|||
@selectChange="handleSelectChange"
|
||||
@scroll="handleScroll"
|
||||
:render="item=>item.title"
|
||||
:disabled="disabled"
|
||||
>
|
||||
</a-transfer>
|
||||
<a-switch unCheckedChildren="disabled" checkedChildren="disabled" :checked="disabled" @change="handleDisable" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
|
@ -35,20 +37,21 @@ export default {
|
|||
});
|
||||
}
|
||||
|
||||
const targetKeys = mockData
|
||||
const oriTargetKeys = mockData
|
||||
.filter(item => +item.key % 3 > 1)
|
||||
.map(item => item.key);
|
||||
return {
|
||||
mockData,
|
||||
targetKeys,
|
||||
targetKeys: oriTargetKeys,
|
||||
selectedKeys: ['1', '4'],
|
||||
disabled: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleChange(nextTargetKeys, direction, moveKeys) {
|
||||
this.targetKeys = nextTargetKeys
|
||||
|
||||
console.log('targetKeys: ', this.targetKeys);
|
||||
console.log('targetKeys: ', nextTargetKeys);
|
||||
console.log('direction: ', direction);
|
||||
console.log('moveKeys: ', moveKeys);
|
||||
},
|
||||
|
@ -62,6 +65,9 @@ export default {
|
|||
console.log('direction:', direction);
|
||||
console.log('target:', e.target);
|
||||
},
|
||||
handleDisable(disabled) {
|
||||
this.disabled = disabled
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
| Property | Description | Type | Default |
|
||||
| -------- | ----------- | ---- | ------- |
|
||||
| dataSource | Used for setting the source data. The elements that are part of this array will be present the left column. Except the elements whose keys are included in `targetKeys` prop. | \[{key: string.isRequired,title: string.isRequired,description: string,disabled: bool}\] | \[] |
|
||||
| disabled | Whether disabled transfer | boolean | false |
|
||||
| filterOption | A function to determine whether an item should show in search result list | (inputValue, option): boolean | |
|
||||
| footer | customize the progress dot by setting a scoped slot | slot="footer" slot-scope="props" | |
|
||||
| lazy | property of vc-lazy-load for lazy rendering items. Turn off it by set to `false`. | object\|boolean | `{ height: 32, offset: 32 }` |
|
||||
| listStyle | A custom CSS style used for rendering the transfer columns. | object | |
|
||||
| notFoundContent | Text to display when a column is empty. | string\|slot | 'The list is empty' |
|
||||
| locale | i18n text including filter, empty text, item unit, etc | object | `{ itemUnit: 'item', itemsUnit: 'items', notFoundContent: 'The list is empty', searchPlaceholder: 'Search here' }` |
|
||||
| operations | A set of operations that are sorted from bottom to top. | string\[] | ['>', '<'] |
|
||||
| render | The function to generate the item shown on a column. Based on an record (element of the dataSource array), this function should return a element which is generated from that record. Also, it can return a plain object with `value` and `label`, `label` is a element and `value` is for title | Function(record) | |
|
||||
| searchPlaceholder | The hint text of the search box. | string | 'Search here' |
|
||||
| selectedKeys | A set of keys of selected items. | string\[] | \[] |
|
||||
| showSearch | If included, a search box is shown on each column. | boolean | false |
|
||||
| targetKeys | A set of keys of elements that are listed on the right column. | string\[] | \[] |
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
import PropTypes from '../_util/vue-types'
|
||||
import { initDefaultProps, getOptionProps, getComponentFromProp } from '../_util/props-util'
|
||||
import { hasProp, initDefaultProps, getOptionProps, getComponentFromProp } from '../_util/props-util'
|
||||
import BaseMixin from '../_util/BaseMixin'
|
||||
import classNames from 'classnames'
|
||||
import List from './list'
|
||||
import Operation from './operation'
|
||||
// import Search from './search'
|
||||
import warning from '../_util/warning'
|
||||
import LocaleReceiver from '../locale-provider/LocaleReceiver'
|
||||
import defaultLocale from '../locale-provider/default'
|
||||
|
||||
|
@ -23,6 +24,7 @@ export const TransferItem = {
|
|||
export const TransferProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
dataSource: PropTypes.arrayOf(PropTypes.shape(TransferItem).loose),
|
||||
disabled: PropTypes.boolean,
|
||||
targetKeys: PropTypes.arrayOf(PropTypes.string),
|
||||
selectedKeys: PropTypes.arrayOf(PropTypes.string),
|
||||
render: PropTypes.func,
|
||||
|
@ -34,6 +36,7 @@ export const TransferProps = {
|
|||
filterOption: PropTypes.func,
|
||||
searchPlaceholder: PropTypes.string,
|
||||
notFoundContent: PropTypes.any,
|
||||
locale: PropTypes.object,
|
||||
rowKey: PropTypes.func,
|
||||
lazy: PropTypes.oneOfType([
|
||||
PropTypes.object,
|
||||
|
@ -44,7 +47,6 @@ export const TransferProps = {
|
|||
export const TransferLocale = {
|
||||
titles: PropTypes.arrayOf(PropTypes.string),
|
||||
notFoundContent: PropTypes.string,
|
||||
searchPlaceholder: PropTypes.string,
|
||||
itemUnit: PropTypes.string,
|
||||
itemsUnit: PropTypes.string,
|
||||
}
|
||||
|
@ -54,9 +56,16 @@ const Transfer = {
|
|||
mixins: [BaseMixin],
|
||||
props: initDefaultProps(TransferProps, {
|
||||
dataSource: [],
|
||||
locale: {},
|
||||
showSearch: false,
|
||||
}),
|
||||
data () {
|
||||
warning(
|
||||
!(getComponentFromProp(this, 'notFoundContent') || hasProp(this, 'searchPlaceholder')),
|
||||
'Transfer[notFoundContent] and Transfer[searchPlaceholder] will be removed, ' +
|
||||
'please use Transfer[locale] instead.',
|
||||
)
|
||||
|
||||
this.separatedDataSource = {
|
||||
leftDataSource: [],
|
||||
rightDataSource: [],
|
||||
|
@ -296,19 +305,33 @@ const Transfer = {
|
|||
return direction === 'left' ? 'sourceSelectedKeys' : 'targetSelectedKeys'
|
||||
},
|
||||
|
||||
renderTransfer (locale) {
|
||||
getLocale (transferLocale) {
|
||||
// Keep old locale props still working.
|
||||
const oldLocale = {}
|
||||
const notFoundContent = getComponentFromProp(this, 'notFoundContent')
|
||||
if (notFoundContent) {
|
||||
oldLocale.notFoundContent = notFoundContent
|
||||
}
|
||||
if (hasProp(this, 'searchPlaceholder')) {
|
||||
oldLocale.searchPlaceholder = this.$props.searchPlaceholder
|
||||
}
|
||||
|
||||
return ({ ...transferLocale, ...oldLocale, ...this.$props.locale })
|
||||
},
|
||||
|
||||
renderTransfer (transferLocale) {
|
||||
const props = getOptionProps(this)
|
||||
const {
|
||||
prefixCls = 'ant-transfer',
|
||||
disabled,
|
||||
operations = [],
|
||||
showSearch,
|
||||
searchPlaceholder,
|
||||
listStyle,
|
||||
operationStyle,
|
||||
filterOption,
|
||||
lazy,
|
||||
} = props
|
||||
const notFoundContent = getComponentFromProp(this, 'notFoundContent')
|
||||
const locale = this.getLocale(transferLocale)
|
||||
const { leftFilter, rightFilter, sourceSelectedKeys, targetSelectedKeys, $scopedSlots } = this
|
||||
const { body, footer } = $scopedSlots
|
||||
const renderItem = props.render
|
||||
|
@ -316,7 +339,7 @@ const Transfer = {
|
|||
const leftActive = targetSelectedKeys.length > 0
|
||||
const rightActive = sourceSelectedKeys.length > 0
|
||||
|
||||
const cls = classNames(prefixCls)
|
||||
const cls = classNames(prefixCls, disabled && `${prefixCls}-disabled`)
|
||||
|
||||
const titles = this.getTitles(locale)
|
||||
return (
|
||||
|
@ -335,14 +358,15 @@ const Transfer = {
|
|||
handleSelectAll={this.handleLeftSelectAll}
|
||||
renderItem={renderItem}
|
||||
showSearch={showSearch}
|
||||
searchPlaceholder={searchPlaceholder || locale.searchPlaceholder}
|
||||
notFoundContent={notFoundContent || locale.notFoundContent}
|
||||
itemUnit={locale.itemUnit}
|
||||
itemsUnit={locale.itemsUnit}
|
||||
body={body}
|
||||
footer={footer}
|
||||
lazy={lazy}
|
||||
onScroll={this.handleLeftScroll}
|
||||
disabled={disabled}
|
||||
itemUnit={locale.itemUnit}
|
||||
itemsUnit={locale.itemsUnit}
|
||||
notFoundContent={locale.notFoundContent}
|
||||
searchPlaceholder={locale.searchPlaceholder}
|
||||
/>
|
||||
<Operation
|
||||
class={`${prefixCls}-operation`}
|
||||
|
@ -353,6 +377,7 @@ const Transfer = {
|
|||
leftArrowText={operations[1]}
|
||||
moveToLeft={this.moveToLeft}
|
||||
style={operationStyle}
|
||||
disabled={disabled}
|
||||
/>
|
||||
<List
|
||||
prefixCls={`${prefixCls}-list`}
|
||||
|
@ -368,14 +393,15 @@ const Transfer = {
|
|||
handleSelectAll={this.handleRightSelectAll}
|
||||
renderItem={renderItem}
|
||||
showSearch={showSearch}
|
||||
searchPlaceholder={searchPlaceholder || locale.searchPlaceholder}
|
||||
notFoundContent={notFoundContent || locale.notFoundContent}
|
||||
itemUnit={locale.itemUnit}
|
||||
itemsUnit={locale.itemsUnit}
|
||||
body={body}
|
||||
footer={footer}
|
||||
lazy={lazy}
|
||||
onScroll={this.handleRightScroll}
|
||||
disabled={disabled}
|
||||
itemUnit={locale.itemUnit}
|
||||
itemsUnit={locale.itemsUnit}
|
||||
notFoundContent={locale.notFoundContent}
|
||||
searchPlaceholder={locale.searchPlaceholder}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| dataSource | 数据源,其中的数据将会被渲染到左边一栏中,`targetKeys` 中指定的除外。 | \[{key: string.isRequired,title: string.isRequired,description: string,disabled: bool}\]\[] | \[] |
|
||||
| disabled | 是否禁用 | boolean | false |
|
||||
| filterOption | 接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | (inputValue, option): boolean | |
|
||||
| footer | 可以设置为一个 作用域插槽 | slot="footer" slot-scope="props" | |
|
||||
| lazy | Transfer 使用了 [vc-lazy-load]优化性能,这里可以设置相关参数。设为 `false` 可以关闭懒加载。 | object\|boolean | `{ height: 32, offset: 32 }` |
|
||||
| listStyle | 两个穿梭框的自定义样式 | object | |
|
||||
| notFoundContent | 当列表为空时显示的内容 | string\|slot | '列表为空' |
|
||||
| locale | 各种语言 | object | `{ itemUnit: '项', itemsUnit: '项', notFoundContent: '列表为空', searchPlaceholder: '请输入搜索内容' }` |
|
||||
| operations | 操作文案集合,顺序从下至上 | string\[] | ['>', '<'] |
|
||||
| render | 每行数据渲染函数,该函数的入参为 `dataSource` 中的项,返回值为 element。或者返回一个普通对象,其中 `label` 字段为 element,`value` 字段为 title | Function(record) | |
|
||||
| searchPlaceholder | 搜索框的默认值 | string | '请输入搜索内容' |
|
||||
| selectedKeys | 设置哪些项应该被选中 | string\[] | \[] |
|
||||
| showSearch | 是否显示搜索框 | boolean | false |
|
||||
| targetKeys | 显示在右侧框数据的key集合 | string\[] | \[] |
|
||||
|
|
|
@ -17,25 +17,34 @@ export default {
|
|||
]),
|
||||
checked: PropTypes.bool,
|
||||
prefixCls: PropTypes.string,
|
||||
disabled: PropTypes.bool,
|
||||
},
|
||||
name: 'Item',
|
||||
render () {
|
||||
const { renderedText, renderedEl, item, lazy, checked, prefixCls } = this.$props
|
||||
const {
|
||||
renderedText, renderedEl, item, lazy,
|
||||
checked, disabled, prefixCls,
|
||||
} = this.$props
|
||||
|
||||
const className = classNames({
|
||||
[`${prefixCls}-content-item`]: true,
|
||||
[`${prefixCls}-content-item-disabled`]: item.disabled,
|
||||
[`${prefixCls}-content-item-disabled`]: disabled || item.disabled,
|
||||
})
|
||||
|
||||
let title
|
||||
if (typeof renderedText === 'string' || typeof renderedText === 'number') {
|
||||
title = String(renderedText)
|
||||
}
|
||||
|
||||
const listItem = (
|
||||
<li
|
||||
class={className}
|
||||
title={renderedText}
|
||||
onClick={item.disabled ? noop : () => {
|
||||
title={title}
|
||||
onClick={(disabled || item.disabled) ? noop : () => {
|
||||
this.$emit('click', item)
|
||||
}}
|
||||
>
|
||||
<Checkbox checked={checked} disabled={item.disabled} />
|
||||
<Checkbox checked={checked} disabled={disabled || item.disabled} />
|
||||
<span>{renderedEl}</span>
|
||||
</li>
|
||||
)
|
||||
|
|
|
@ -51,6 +51,7 @@ export const TransferListProps = {
|
|||
PropTypes.bool,
|
||||
PropTypes.object,
|
||||
]),
|
||||
disabled: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -179,14 +180,14 @@ export default {
|
|||
|
||||
render () {
|
||||
const {
|
||||
prefixCls, dataSource, titleText, checkedKeys, lazy,
|
||||
body = noop, footer = noop, showSearch, filter,
|
||||
prefixCls, dataSource, titleText, checkedKeys, lazy, disabled,
|
||||
body, footer, showSearch, filter,
|
||||
searchPlaceholder, notFoundContent, itemUnit, itemsUnit,
|
||||
} = this.$props
|
||||
|
||||
// Custom Layout
|
||||
const footerDom = footer({ ...this.$props })
|
||||
const bodyDom = body({ ...this.$props })
|
||||
const footerDom = footer && footer({ ...this.$props })
|
||||
const bodyDom = body && body({ ...this.$props })
|
||||
|
||||
const listCls = classNames(prefixCls, {
|
||||
[`${prefixCls}-with-footer`]: !!footerDom,
|
||||
|
@ -211,6 +212,7 @@ export default {
|
|||
const checked = checkedKeys.indexOf(item.key) >= 0
|
||||
return (
|
||||
<Item
|
||||
disabled={disabled}
|
||||
key={item.key}
|
||||
item={item}
|
||||
lazy={lazy}
|
||||
|
@ -242,7 +244,7 @@ export default {
|
|||
})
|
||||
const listBody = bodyDom || (
|
||||
<div
|
||||
class={showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`}
|
||||
class={classNames(showSearch ? `${prefixCls}-body ${prefixCls}-body-with-search` : `${prefixCls}-body`)}
|
||||
>
|
||||
{search}
|
||||
<transition-group
|
||||
|
@ -270,6 +272,7 @@ export default {
|
|||
const checkAllCheckbox = (
|
||||
<Checkbox
|
||||
ref='checkbox'
|
||||
disabled={disabled}
|
||||
checked={checkedAll}
|
||||
indeterminate={checkStatus === 'part'}
|
||||
onChange={() => {
|
||||
|
|
|
@ -13,6 +13,7 @@ export const TransferOperationProps = {
|
|||
moveToRight: PropTypes.any,
|
||||
leftActive: PropTypes.bool,
|
||||
rightActive: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
}
|
||||
|
||||
export default {
|
||||
|
@ -20,6 +21,7 @@ export default {
|
|||
props: { ...TransferOperationProps },
|
||||
render () {
|
||||
const {
|
||||
disabled,
|
||||
moveToLeft = noop,
|
||||
moveToRight = noop,
|
||||
leftArrowText = '',
|
||||
|
@ -32,7 +34,7 @@ export default {
|
|||
<Button
|
||||
type='primary'
|
||||
size='small'
|
||||
disabled={!rightActive}
|
||||
disabled={disabled || !rightActive}
|
||||
onClick={moveToRight}
|
||||
icon='right'
|
||||
>
|
||||
|
@ -41,7 +43,7 @@ export default {
|
|||
<Button
|
||||
type='primary'
|
||||
size='small'
|
||||
disabled={!leftActive}
|
||||
disabled={disabled || !leftActive}
|
||||
onClick={moveToLeft}
|
||||
icon='left'
|
||||
>
|
||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
|||
const { placeholder, value, prefixCls } = getOptionProps(this)
|
||||
const icon = (value && value.length > 0) ? (
|
||||
<a href='#' class={`${prefixCls}-action`} onClick={this.handleClear2}>
|
||||
<Icon type='cross-circle' />
|
||||
<Icon type='close-circle' />
|
||||
</a>
|
||||
) : (
|
||||
<span class={`${prefixCls}-action`}><Icon type='search' /></span>
|
||||
|
|
Loading…
Reference in New Issue