feat: update drawer (#2324)
parent
3c292a51e1
commit
3642b09db8
|
@ -0,0 +1,30 @@
|
|||
import { nextTick } from 'vue';
|
||||
const antvRef = {
|
||||
beforeMount: function bind(el, binding, vnode) {
|
||||
nextTick(function() {
|
||||
binding.value(el, vnode.key);
|
||||
});
|
||||
binding.value(el, vnode.key);
|
||||
},
|
||||
updated: function update(el, binding, vnode, oldVnode) {
|
||||
if (oldVnode && oldVnode.directives) {
|
||||
let oldBinding = oldVnode.directives.find(function(directive) {
|
||||
return directive === antvRef;
|
||||
});
|
||||
if (oldBinding && oldBinding.value !== binding.value) {
|
||||
oldBinding && oldBinding.value(null, oldVnode.key);
|
||||
binding.value(el, vnode.key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Should not have this situation
|
||||
if (vnode.el !== oldVnode.el) {
|
||||
binding.value(el, vnode.key);
|
||||
}
|
||||
},
|
||||
unmounted: function unbind(el, binding, vnode) {
|
||||
binding.value(null, vnode.key);
|
||||
},
|
||||
};
|
||||
|
||||
export default antvRef;
|
|
@ -203,12 +203,20 @@ const getKey = ele => {
|
|||
|
||||
export function getEvents(child) {
|
||||
let events = {};
|
||||
if (child.componentOptions && child.componentOptions.listeners) {
|
||||
events = child.componentOptions.listeners;
|
||||
} else if (child.data && child.data.on) {
|
||||
events = child.data.on;
|
||||
for (let key in child) {
|
||||
if (/^on/.test(key)) {
|
||||
key = key.toLowerCase();
|
||||
events[key] = child[key];
|
||||
}
|
||||
}
|
||||
return { ...events };
|
||||
return events;
|
||||
// let events = {};
|
||||
// if (child.componentOptions && child.componentOptions.listeners) {
|
||||
// events = child.componentOptions.listeners;
|
||||
// } else if (child.data && child.data.on) {
|
||||
// events = child.data.on;
|
||||
// }
|
||||
// return { ...events };
|
||||
}
|
||||
|
||||
// 获取 xxx.native 或者 原生标签 事件
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { inject, provide, nextTick } from 'vue';
|
||||
import classnames from 'classnames';
|
||||
import omit from 'omit.js';
|
||||
import VcDrawer from '../vc-drawer/src';
|
||||
|
@ -42,17 +43,28 @@ const Drawer = {
|
|||
_push: false,
|
||||
};
|
||||
},
|
||||
inject: {
|
||||
parentDrawer: {
|
||||
default: () => null,
|
||||
},
|
||||
configProvider: { default: () => ConfigConsumerProps },
|
||||
},
|
||||
provide() {
|
||||
setup() {
|
||||
const configProvider = inject('configProvider', ConfigConsumerProps);
|
||||
return {
|
||||
parentDrawer: this,
|
||||
configProvider,
|
||||
};
|
||||
},
|
||||
// inject: {
|
||||
// parentDrawer: {
|
||||
// default: () => null,
|
||||
// },
|
||||
// configProvider: { default: () => ConfigConsumerProps },
|
||||
// },
|
||||
// provide() {
|
||||
// return {
|
||||
// parentDrawer: this,
|
||||
// };
|
||||
// },
|
||||
beforeCreate() {
|
||||
const parentDrawer = inject('parentDrawer', null);
|
||||
provide('parentDrawer', this);
|
||||
this.parentDrawer = parentDrawer;
|
||||
},
|
||||
mounted() {
|
||||
// fix: delete drawer in child and re-render, no push started.
|
||||
// <Drawer>{show && <Drawer />}</Drawer>
|
||||
|
@ -62,7 +74,7 @@ const Drawer = {
|
|||
}
|
||||
},
|
||||
updated() {
|
||||
this.$nextTick(() => {
|
||||
nextTick(() => {
|
||||
if (this.preVisible !== this.visible && this.parentDrawer) {
|
||||
if (this.visible) {
|
||||
this.parentDrawer.push();
|
||||
|
@ -133,7 +145,9 @@ const Drawer = {
|
|||
},
|
||||
renderHeader(prefixCls) {
|
||||
const { closable, headerStyle } = this.$props;
|
||||
const title = getComponentFromProp(this, 'title');
|
||||
// TODO
|
||||
// const title = getComponentFromProp(this, 'title');
|
||||
const title = null;
|
||||
if (!title && !closable) {
|
||||
return null;
|
||||
}
|
||||
|
@ -181,7 +195,7 @@ const Drawer = {
|
|||
>
|
||||
{this.renderHeader(prefixCls)}
|
||||
<div key="body" class={`${prefixCls}-body`} style={bodyStyle}>
|
||||
{this.$slots.default}
|
||||
{this.$slots.default && this.$slots.default()}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -206,53 +220,59 @@ const Drawer = {
|
|||
} else {
|
||||
offsetStyle.height = typeof height === 'number' ? `${height}px` : height;
|
||||
}
|
||||
const handler = getComponentFromProp(this, 'handle') || false;
|
||||
// TODO
|
||||
// const handler = getComponentFromProp(this, 'handle') || false;
|
||||
const handler = false;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('drawer', customizePrefixCls);
|
||||
|
||||
const vcDrawerProps = {
|
||||
props: {
|
||||
...omit(rest, [
|
||||
'closable',
|
||||
'destroyOnClose',
|
||||
'drawerStyle',
|
||||
'headerStyle',
|
||||
'bodyStyle',
|
||||
'title',
|
||||
'push',
|
||||
'visible',
|
||||
'getPopupContainer',
|
||||
'rootPrefixCls',
|
||||
'getPrefixCls',
|
||||
'renderEmpty',
|
||||
'csp',
|
||||
'pageHeader',
|
||||
'autoInsertSpaceInButton',
|
||||
]),
|
||||
handler,
|
||||
...offsetStyle,
|
||||
prefixCls,
|
||||
open: visible,
|
||||
showMask: mask,
|
||||
placement,
|
||||
className: classnames({
|
||||
[wrapClassName]: !!wrapClassName,
|
||||
[haveMask]: !!haveMask,
|
||||
}),
|
||||
wrapStyle: this.getRcDrawerStyle(),
|
||||
},
|
||||
on: {
|
||||
...getListeners(this),
|
||||
},
|
||||
...omit(rest, [
|
||||
'closable',
|
||||
'destroyOnClose',
|
||||
'drawerStyle',
|
||||
'headerStyle',
|
||||
'bodyStyle',
|
||||
'title',
|
||||
'push',
|
||||
'visible',
|
||||
'getPopupContainer',
|
||||
'rootPrefixCls',
|
||||
'getPrefixCls',
|
||||
'renderEmpty',
|
||||
'csp',
|
||||
'pageHeader',
|
||||
'autoInsertSpaceInButton',
|
||||
]),
|
||||
handler,
|
||||
...offsetStyle,
|
||||
prefixCls,
|
||||
open: visible,
|
||||
showMask: mask,
|
||||
placement,
|
||||
className: classnames({
|
||||
[wrapClassName]: !!wrapClassName,
|
||||
[haveMask]: !!haveMask,
|
||||
}),
|
||||
wrapStyle: this.getRcDrawerStyle(),
|
||||
};
|
||||
return <VcDrawer {...vcDrawerProps}>{this.renderBody(prefixCls)}</VcDrawer>;
|
||||
return (
|
||||
<VcDrawer
|
||||
{...vcDrawerProps}
|
||||
on={{
|
||||
...getListeners(this), //TODO
|
||||
}}
|
||||
>
|
||||
{this.renderBody(prefixCls)}
|
||||
</VcDrawer>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
/* istanbul ignore next */
|
||||
Drawer.install = function(Vue) {
|
||||
Vue.use(Base);
|
||||
Vue.component(Drawer.name, Drawer);
|
||||
Drawer.install = function(app) {
|
||||
app.use(Base);
|
||||
app.component(Drawer.name, Drawer);
|
||||
};
|
||||
|
||||
export default Drawer;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import classnames from 'classnames';
|
||||
import Vue from 'vue';
|
||||
import ref from 'vue-ref';
|
||||
import { cloneVNode, withDirectives, Teleport, nextTick } from 'vue';
|
||||
import antRef from '../../_util/ant-ref';
|
||||
import BaseMixin from '../../_util/BaseMixin';
|
||||
import { initDefaultProps, getEvents, getListeners } from '../../_util/props-util';
|
||||
import { cloneElement } from '../../_util/vnode';
|
||||
import { initDefaultProps, getEvents, getListeners, getSlot } from '../../_util/props-util';
|
||||
// import { cloneElement } from '../../_util/vnode';
|
||||
import getScrollBarSize from '../../_util/getScrollBarSize';
|
||||
import { IDrawerProps } from './IDrawerPropTypes';
|
||||
import KeyCode from '../../_util/KeyCode';
|
||||
|
@ -16,7 +16,7 @@ import {
|
|||
transformArguments,
|
||||
isNumeric,
|
||||
} from './utils';
|
||||
import Portal from '../../_util/Portal';
|
||||
// import Portal from '../../_util/Portal';
|
||||
|
||||
function noop() {}
|
||||
|
||||
|
@ -27,9 +27,10 @@ const windowIsUndefined = !(
|
|||
window.document.createElement
|
||||
);
|
||||
|
||||
Vue.use(ref, { name: 'ant-ref' });
|
||||
// Vue.use(ref, { name: 'ant-ref' });
|
||||
const Drawer = {
|
||||
mixins: [BaseMixin],
|
||||
directives: { 'ant-ref': antRef },
|
||||
props: initDefaultProps(IDrawerProps, {
|
||||
prefixCls: 'drawer',
|
||||
placement: 'left',
|
||||
|
@ -65,7 +66,7 @@ const Drawer = {
|
|||
};
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
nextTick(() => {
|
||||
if (!windowIsUndefined) {
|
||||
let passiveSupported = false;
|
||||
window.addEventListener(
|
||||
|
@ -119,7 +120,7 @@ const Drawer = {
|
|||
},
|
||||
},
|
||||
updated() {
|
||||
this.$nextTick(() => {
|
||||
nextTick(() => {
|
||||
// dom 没渲染时,重走一遍。
|
||||
if (!this.sFirstEnter && this.container) {
|
||||
this.$forceUpdate();
|
||||
|
@ -362,7 +363,9 @@ const Drawer = {
|
|||
}
|
||||
}
|
||||
}
|
||||
const { change } = getListeners(this);
|
||||
// TODO
|
||||
// const { change } = getListeners(this);
|
||||
const change = false;
|
||||
if (change && this.isOpenChange && this.sFirstEnter) {
|
||||
change(open);
|
||||
this.isOpenChange = false;
|
||||
|
@ -382,7 +385,7 @@ const Drawer = {
|
|||
keyboard,
|
||||
maskClosable,
|
||||
} = this.$props;
|
||||
const children = this.$slots.default;
|
||||
const children = getSlot(this);
|
||||
const wrapperClassname = classnames(prefixCls, {
|
||||
[`${prefixCls}-${placement}`]: true,
|
||||
[`${prefixCls}-open`]: open,
|
||||
|
@ -411,73 +414,80 @@ const Drawer = {
|
|||
</div>
|
||||
);
|
||||
const { handler: handlerSlot } = this;
|
||||
const handlerSlotVnode = (handlerSlot && handlerSlot[0]) || handlerDefalut;
|
||||
const { click: handleIconClick } = getEvents(handlerSlotVnode);
|
||||
handlerChildren = cloneElement(handlerSlotVnode, {
|
||||
on: {
|
||||
click: e => {
|
||||
const handlerSlotVnode = handlerSlot || handlerDefalut;
|
||||
const { onclick: handleIconClick } = getEvents(handlerSlotVnode);
|
||||
handlerChildren = withDirectives(
|
||||
cloneVNode(handlerSlotVnode, {
|
||||
onClick: e => {
|
||||
handleIconClick && handleIconClick();
|
||||
this.onIconTouchEnd(e);
|
||||
},
|
||||
},
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
}),
|
||||
[
|
||||
[
|
||||
antRef, //directive
|
||||
c => {
|
||||
this.handlerdom = c;
|
||||
},
|
||||
},
|
||||
}, // value
|
||||
],
|
||||
],
|
||||
});
|
||||
);
|
||||
}
|
||||
const domContProps = {
|
||||
class: wrapperClassname,
|
||||
directives: [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
this.dom = c;
|
||||
},
|
||||
},
|
||||
],
|
||||
on: {
|
||||
transitionend: this.onWrapperTransitionEnd,
|
||||
keydown: open && keyboard ? this.onKeyDown : noop,
|
||||
},
|
||||
// directives: [
|
||||
// {
|
||||
// name: 'ant-ref',
|
||||
// value: c => {
|
||||
// this.dom = c;
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
onTransitionend: this.onWrapperTransitionEnd,
|
||||
onKeydown: open && keyboard ? this.onKeyDown : noop,
|
||||
style: wrapStyle,
|
||||
};
|
||||
const directivesMaskDom = [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
this.maskDom = c;
|
||||
},
|
||||
},
|
||||
];
|
||||
const directivesContentWrapper = [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
this.contentWrapper = c;
|
||||
},
|
||||
},
|
||||
];
|
||||
const directivesContentDom = [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
this.contentDom = c;
|
||||
},
|
||||
},
|
||||
];
|
||||
// const directivesMaskDom = [
|
||||
// {
|
||||
// name: 'ant-ref',
|
||||
// value: c => {
|
||||
// this.maskDom = c;
|
||||
// },
|
||||
// },
|
||||
// ];
|
||||
// const directivesContentWrapper = [
|
||||
// {
|
||||
// name: 'ant-ref',
|
||||
// value: c => {
|
||||
// this.contentWrapper = c;
|
||||
// },
|
||||
// },
|
||||
// ];
|
||||
// const directivesContentDom = [
|
||||
// {
|
||||
// name: 'ant-ref',
|
||||
// value: c => {
|
||||
// this.contentDom = c;
|
||||
// },
|
||||
// },
|
||||
// ];
|
||||
return (
|
||||
<div {...domContProps} tabIndex={-1}>
|
||||
<div
|
||||
v-ant-ref={c => {
|
||||
this.dom = c;
|
||||
}}
|
||||
{...domContProps}
|
||||
tabIndex={-1}
|
||||
>
|
||||
{showMask && (
|
||||
<div
|
||||
class={`${prefixCls}-mask`}
|
||||
onClick={maskClosable ? this.onMaskTouchEnd : noop}
|
||||
style={maskStyle}
|
||||
{...{ directives: directivesMaskDom }}
|
||||
v-ant-ref={c => {
|
||||
this.maskDom = c;
|
||||
}}
|
||||
// {...{ directives: directivesMaskDom }}
|
||||
/>
|
||||
)}
|
||||
<div
|
||||
|
@ -488,11 +498,17 @@ const Drawer = {
|
|||
width: isNumeric(width) ? `${width}px` : width,
|
||||
height: isNumeric(height) ? `${height}px` : height,
|
||||
}}
|
||||
{...{ directives: directivesContentWrapper }}
|
||||
v-ant-ref={c => {
|
||||
this.contentWrapper = c;
|
||||
}}
|
||||
// {...{ directives: directivesContentWrapper }}
|
||||
>
|
||||
<div
|
||||
class={`${prefixCls}-content`}
|
||||
{...{ directives: directivesContentDom }}
|
||||
v-ant-ref={c => {
|
||||
this.contentDom = c;
|
||||
}}
|
||||
// {...{ directives: directivesContentDom }}
|
||||
onTouchstart={open ? this.removeStartHandler : noop} // 跑用例用
|
||||
onTouchmove={open ? this.removeMoveHandler : noop} // 跑用例用
|
||||
>
|
||||
|
@ -604,16 +620,21 @@ const Drawer = {
|
|||
currentDrawer[this.drawerId] = open ? this.container : open;
|
||||
const children = this.getChildToRender(this.sFirstEnter ? open : false);
|
||||
if (!getContainer) {
|
||||
const directives = [
|
||||
{
|
||||
name: 'ant-ref',
|
||||
value: c => {
|
||||
this.container = c;
|
||||
},
|
||||
},
|
||||
];
|
||||
// const directives = [
|
||||
// {
|
||||
// name: 'ant-ref',
|
||||
// value: c => {
|
||||
// this.container = c;
|
||||
// },
|
||||
// },
|
||||
// ];
|
||||
return (
|
||||
<div class={wrapperClassName} {...{ directives }}>
|
||||
<div
|
||||
class={wrapperClassName}
|
||||
v-ant-ref={c => {
|
||||
this.container = c;
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
@ -624,7 +645,7 @@ const Drawer = {
|
|||
// 如果有 handler 为内置强制渲染;
|
||||
const $forceRender = !!handler || forceRender;
|
||||
if ($forceRender || open || this.dom) {
|
||||
portal = <Portal getContainer={this.getSelfContainer} children={children}></Portal>;
|
||||
portal = <Teleport to={this.getSelfContainer()}>{children}</Teleport>;
|
||||
}
|
||||
return portal;
|
||||
},
|
||||
|
|
|
@ -1,47 +1,63 @@
|
|||
<template>
|
||||
<a-config-provider>
|
||||
<a-button-group class="dddd" style="color: red" @click="onClick">
|
||||
<a-button>Cancel</a-button>
|
||||
<a-button type="primary">
|
||||
OK
|
||||
</a-button>
|
||||
</a-button-group>
|
||||
<a-button
|
||||
:class="['test']"
|
||||
class="aaa"
|
||||
style="display: inline"
|
||||
block
|
||||
:type="type"
|
||||
@click="onClick"
|
||||
<div>
|
||||
<a-button type="primary" @click="showDrawer">Open</a-button>
|
||||
<a-drawer
|
||||
title="Multi-level drawer"
|
||||
width="520"
|
||||
:closable="false"
|
||||
:visible="visible"
|
||||
@close="onClose"
|
||||
>
|
||||
Primary
|
||||
</a-button>
|
||||
<a-button block>
|
||||
Default
|
||||
</a-button>
|
||||
<a-button type="dashed" block>
|
||||
Dashed
|
||||
</a-button>
|
||||
<a-button type="danger" block>
|
||||
Danger
|
||||
</a-button>
|
||||
<a-button type="link" block>
|
||||
Link
|
||||
</a-button>
|
||||
</a-config-provider>
|
||||
<a-button type="primary" @click="showChildrenDrawer">Two-level drawer</a-button>
|
||||
<a-drawer
|
||||
title="Two-level Drawer"
|
||||
width="320"
|
||||
:closable="false"
|
||||
:visible="childrenDrawer"
|
||||
@close="onChildrenDrawerClose"
|
||||
>
|
||||
<a-button type="primary" @click="showChildrenDrawer">This is two-level drawer</a-button>
|
||||
</a-drawer>
|
||||
<div
|
||||
:style="{
|
||||
position: 'absolute',
|
||||
bottom: 0,
|
||||
width: '100%',
|
||||
borderTop: '1px solid #e8e8e8',
|
||||
padding: '10px 16px',
|
||||
textAlign: 'right',
|
||||
left: 0,
|
||||
background: '#fff',
|
||||
borderRadius: '0 0 4px 4px',
|
||||
boxSizing: 'border-box',
|
||||
}"
|
||||
>
|
||||
<a-button style="marginRight: 8px" @click="onClose">Cancel</a-button>
|
||||
<a-button type="primary" @click="onClose">Submit</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Demo',
|
||||
data() {
|
||||
return {
|
||||
type: 'primary',
|
||||
visible: false,
|
||||
childrenDrawer: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
console.log(1);
|
||||
showDrawer() {
|
||||
this.visible = true;
|
||||
},
|
||||
onClose() {
|
||||
this.visible = false;
|
||||
},
|
||||
showChildrenDrawer() {
|
||||
this.childrenDrawer = true;
|
||||
},
|
||||
onChildrenDrawerClose() {
|
||||
this.childrenDrawer = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -2,10 +2,13 @@ import '@babel/polyfill';
|
|||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import Button from 'ant-design-vue/button';
|
||||
import Drawer from 'ant-design-vue/drawer';
|
||||
import ConfigProvider from 'ant-design-vue/config-provider';
|
||||
import 'ant-design-vue/button/style/index.less';
|
||||
import 'ant-design-vue/drawer/style/index.less';
|
||||
|
||||
createApp(App)
|
||||
.use(Button)
|
||||
.use(ConfigProvider)
|
||||
.use(Drawer)
|
||||
.mount('#app');
|
||||
|
|
Loading…
Reference in New Issue