mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
[bugfix] Popup should remove event handler when destroyed (#477)
This commit is contained in:
parent
719d1f9b0a
commit
2d2a368e2c
@ -31,8 +31,8 @@
|
|||||||
<demo-block :title="$t('uneditable')">
|
<demo-block :title="$t('uneditable')">
|
||||||
<van-contact-card
|
<van-contact-card
|
||||||
type="edit"
|
type="edit"
|
||||||
:name="list[0].name"
|
:name="mockContact.name"
|
||||||
:tel="list[0].tel"
|
:tel="mockContact.tel"
|
||||||
:editable="false"
|
:editable="false"
|
||||||
/>
|
/>
|
||||||
</demo-block>
|
</demo-block>
|
||||||
@ -62,14 +62,18 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.list.push({
|
this.list.push(this.mockContact);
|
||||||
name: this.$t('name'),
|
|
||||||
tel: '13000000000',
|
|
||||||
id: 0
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
mockContact() {
|
||||||
|
return {
|
||||||
|
name: this.$t('name'),
|
||||||
|
tel: '13000000000',
|
||||||
|
id: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
cardType() {
|
cardType() {
|
||||||
return this.chosenContactId !== null ? 'edit' : 'add';
|
return this.chosenContactId !== null ? 'edit' : 'add';
|
||||||
},
|
},
|
||||||
@ -102,7 +106,7 @@ export default {
|
|||||||
this.showList = false;
|
this.showList = false;
|
||||||
|
|
||||||
if (this.isEdit) {
|
if (this.isEdit) {
|
||||||
this.list = this.list.map(item => item.id === info.id ? info : item);
|
this.list = this.list.map(item => (item.id === info.id ? info : item));
|
||||||
} else {
|
} else {
|
||||||
this.list.push(info);
|
this.list.push(info);
|
||||||
}
|
}
|
||||||
|
@ -96,12 +96,12 @@
|
|||||||
"uppercamelcase": "^3.0.0",
|
"uppercamelcase": "^3.0.0",
|
||||||
"url-loader": "^0.6.2",
|
"url-loader": "^0.6.2",
|
||||||
"vant-doc": "0.3.19",
|
"vant-doc": "0.3.19",
|
||||||
"vue": "^2.5.11",
|
"vue": "^2.5.13",
|
||||||
"vue-loader": "^13.6.0",
|
"vue-loader": "^13.6.1",
|
||||||
"vue-router": "^3.0.1",
|
"vue-router": "^3.0.1",
|
||||||
"vue-sfc-compiler": "^0.0.6",
|
"vue-sfc-compiler": "^0.0.6",
|
||||||
"vue-style-loader": "^3.0.0",
|
"vue-style-loader": "^3.0.0",
|
||||||
"vue-template-compiler": "^2.5.11",
|
"vue-template-compiler": "^2.5.13",
|
||||||
"vue-template-es2015-compiler": "^1.6.0",
|
"vue-template-es2015-compiler": "^1.6.0",
|
||||||
"webpack": "^3.10.0",
|
"webpack": "^3.10.0",
|
||||||
"webpack-bundle-analyzer": "^2.9.1",
|
"webpack-bundle-analyzer": "^2.9.1",
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
const PopupContext = {
|
const PopupContext = {
|
||||||
idSeed: 1,
|
idSeed: 1,
|
||||||
zIndex: 2000,
|
zIndex: 2000,
|
||||||
instances: {},
|
|
||||||
stack: [],
|
stack: [],
|
||||||
|
|
||||||
plusKeyByOne(key) {
|
plusKey(key) {
|
||||||
return this[key]++;
|
return this[key]++;
|
||||||
},
|
},
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
import manager from './popup-manager';
|
import manager from './manager';
|
||||||
import context from './popup-context';
|
import context from './context';
|
||||||
import scrollUtils from '../../utils/scroll';
|
import scrollUtils from '../../utils/scroll';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -32,8 +32,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this._popupId = 'popup-' + context.plusKeyByOne('idSeed');
|
this._popupId = 'popup-' + context.plusKey('idSeed');
|
||||||
context.instances[this._popupId] = this;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@ -55,14 +54,12 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
watchTouchMove(e) {
|
watchTouchMove(e) {
|
||||||
const pos = this.pos;
|
const { pos } = this;
|
||||||
const dx = e.touches[0].clientX - pos.x;
|
const dx = e.touches[0].clientX - pos.x;
|
||||||
const dy = e.touches[0].clientY - pos.y;
|
const dy = e.touches[0].clientY - pos.y;
|
||||||
const direction = dy > 0 ? '10' : '01';
|
const direction = dy > 0 ? '10' : '01';
|
||||||
const el = scrollUtils.getScrollEventTarget(e.target, this.$el);
|
const el = scrollUtils.getScrollEventTarget(e.target, this.$el);
|
||||||
const scrollTop = el.scrollTop;
|
const { scrollHeight, offsetHeight, scrollTop } = el;
|
||||||
const scrollHeight = el.scrollHeight;
|
|
||||||
const offsetHeight = el.offsetHeight;
|
|
||||||
const isVertical = Math.abs(dx) < Math.abs(dy);
|
const isVertical = Math.abs(dx) < Math.abs(dy);
|
||||||
|
|
||||||
let status = '11';
|
let status = '11';
|
||||||
@ -92,10 +89,10 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.overlay) {
|
if (this.overlay) {
|
||||||
manager.openModal({
|
manager.openModal(this, {
|
||||||
id: this._popupId,
|
id: this._popupId,
|
||||||
zIndex: context.plusKeyByOne('zIndex'),
|
|
||||||
dom: this.$el,
|
dom: this.$el,
|
||||||
|
zIndex: context.plusKey('zIndex'),
|
||||||
className: this.overlayClass,
|
className: this.overlayClass,
|
||||||
customStyle: this.overlayStyle
|
customStyle: this.overlayStyle
|
||||||
});
|
});
|
||||||
@ -105,12 +102,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$el.style.zIndex = context.plusKeyByOne('zIndex');
|
this.$el.style.zIndex = context.plusKey('zIndex');
|
||||||
this.opened = true;
|
this.opened = true;
|
||||||
|
|
||||||
if (this.preventScroll) {
|
if (this.preventScroll) {
|
||||||
document.addEventListener('touchstart', this.recordPosition, false);
|
document.addEventListener('touchstart', this.recordPosition);
|
||||||
document.addEventListener('touchmove', this.watchTouchMove, false);
|
document.addEventListener('touchmove', this.watchTouchMove);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -120,11 +117,6 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.$emit('input', false);
|
this.$emit('input', false);
|
||||||
|
|
||||||
if (this.lockOnScroll) {
|
|
||||||
document.body.classList.remove('van-overflow-hidden');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.opened = false;
|
this.opened = false;
|
||||||
this.doAfterClose();
|
this.doAfterClose();
|
||||||
},
|
},
|
||||||
@ -132,18 +124,18 @@ export default {
|
|||||||
doAfterClose() {
|
doAfterClose() {
|
||||||
manager.closeModal(this._popupId);
|
manager.closeModal(this._popupId);
|
||||||
|
|
||||||
|
if (this.lockOnScroll) {
|
||||||
|
document.body.classList.remove('van-overflow-hidden');
|
||||||
|
}
|
||||||
|
|
||||||
if (this.preventScroll) {
|
if (this.preventScroll) {
|
||||||
document.removeEventListener('touchstart', this.recordPosition, false);
|
document.removeEventListener('touchstart', this.recordPosition);
|
||||||
document.removeEventListener('touchmove', this.watchTouchMove, false);
|
document.removeEventListener('touchmove', this.watchTouchMove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
context.instances[this._popupId] = null;
|
this.doAfterClose();
|
||||||
manager.closeModal(this._popupId);
|
|
||||||
if (this.lockOnScroll) {
|
|
||||||
document.body.classList.remove('van-overflow-hidden');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import context from './popup-context';
|
import context from './context';
|
||||||
|
|
||||||
const modalDefaultConfig = {
|
const modalDefaultConfig = {
|
||||||
className: '',
|
className: '',
|
||||||
customStyle: {}
|
customStyle: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const PopupManager = {
|
const manager = {
|
||||||
getModal() {
|
getModal() {
|
||||||
let { modal } = context;
|
let { modal } = context;
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ const PopupManager = {
|
|||||||
el: document.createElement('div')
|
el: document.createElement('div')
|
||||||
});
|
});
|
||||||
modal.$on('click', () => {
|
modal.$on('click', () => {
|
||||||
PopupManager.handleOverlayClick();
|
manager.onClickOverlay();
|
||||||
});
|
});
|
||||||
|
|
||||||
context.modal = modal;
|
context.modal = modal;
|
||||||
@ -27,23 +27,23 @@ const PopupManager = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// close popup when click modal && closeOnClickOverlay is true
|
// close popup when click modal && closeOnClickOverlay is true
|
||||||
handleOverlayClick() {
|
onClickOverlay() {
|
||||||
const { top } = context;
|
const { top } = context;
|
||||||
if (top) {
|
if (top) {
|
||||||
const instance = context.instances[top.id];
|
const { instance } = top;
|
||||||
if (instance && instance.closeOnClickOverlay) {
|
if (instance && instance.closeOnClickOverlay) {
|
||||||
instance.close();
|
instance.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
openModal(config) {
|
openModal(instance, config) {
|
||||||
const { id, dom } = config;
|
const { id, dom } = config;
|
||||||
const exist = context.stack.some(item => item.id === id);
|
const exist = context.stack.some(item => item.id === id);
|
||||||
|
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
|
const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
|
||||||
context.stack.push({ id, config, targetNode });
|
context.stack.push({ instance, id, config, targetNode });
|
||||||
this.updateModal();
|
this.updateModal();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -63,16 +63,15 @@ const PopupManager = {
|
|||||||
|
|
||||||
updateModal() {
|
updateModal() {
|
||||||
const modal = this.getModal();
|
const modal = this.getModal();
|
||||||
const el = modal.$el;
|
|
||||||
|
|
||||||
if (el.parentNode) {
|
if (modal.$el.parentNode) {
|
||||||
modal.visible = false;
|
modal.visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context.top) {
|
if (context.top) {
|
||||||
const { targetNode, config } = context.top;
|
const { targetNode, config } = context.top;
|
||||||
|
|
||||||
targetNode.appendChild(el);
|
targetNode.appendChild(modal.$el);
|
||||||
Object.assign(modal, {
|
Object.assign(modal, {
|
||||||
...modalDefaultConfig,
|
...modalDefaultConfig,
|
||||||
...config,
|
...config,
|
||||||
@ -82,4 +81,4 @@ const PopupManager = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PopupManager;
|
export default manager;
|
18
yarn.lock
18
yarn.lock
@ -6696,9 +6696,9 @@ vue-lazyload@^1.1.4:
|
|||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/vue-lazyload/-/vue-lazyload-1.1.4.tgz#94dbb3fcb047f147f37900c0e22ad4fd478e31c4"
|
resolved "https://registry.yarnpkg.com/vue-lazyload/-/vue-lazyload-1.1.4.tgz#94dbb3fcb047f147f37900c0e22ad4fd478e31c4"
|
||||||
|
|
||||||
vue-loader@^13.6.0:
|
vue-loader@^13.6.1:
|
||||||
version "13.6.0"
|
version "13.6.1"
|
||||||
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.6.0.tgz#c1c9570e1e57475f8acb02cda35551b812f88086"
|
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-13.6.1.tgz#3ad365271b3db382722ab2eb0d6936d8d52ec2ce"
|
||||||
dependencies:
|
dependencies:
|
||||||
consolidate "^0.14.0"
|
consolidate "^0.14.0"
|
||||||
hash-sum "^1.0.2"
|
hash-sum "^1.0.2"
|
||||||
@ -6729,9 +6729,9 @@ vue-style-loader@^3.0.0:
|
|||||||
hash-sum "^1.0.2"
|
hash-sum "^1.0.2"
|
||||||
loader-utils "^1.0.2"
|
loader-utils "^1.0.2"
|
||||||
|
|
||||||
vue-template-compiler@^2.5.11:
|
vue-template-compiler@^2.5.13:
|
||||||
version "2.5.11"
|
version "2.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.11.tgz#7dda6905e464ff173c8e70e1dfd1769a7888b7e8"
|
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.5.13.tgz#12a2aa0ecd6158ac5e5f14d294b0993f399c3d38"
|
||||||
dependencies:
|
dependencies:
|
||||||
de-indent "^1.0.2"
|
de-indent "^1.0.2"
|
||||||
he "^1.1.0"
|
he "^1.1.0"
|
||||||
@ -6740,9 +6740,9 @@ vue-template-es2015-compiler@^1.6.0:
|
|||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
|
resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
|
||||||
|
|
||||||
vue@^2.5.11:
|
vue@^2.5.13:
|
||||||
version "2.5.11"
|
version "2.5.13"
|
||||||
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.11.tgz#80ca2657aa81f03545cd8dd5a2f55454641e6405"
|
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.13.tgz#95bd31e20efcf7a7f39239c9aa6787ce8cf578e1"
|
||||||
|
|
||||||
watchpack@^1.4.0:
|
watchpack@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user