mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-22 10:30:34 +03:00
fix: memory leak when positioning with popper (#1094)
* fix: memory leak when positioning with popper * docs: update calculate position docs Co-authored-by: Jeff <sagalbot@gmail.com>
This commit is contained in:
@@ -22,7 +22,7 @@ import { createPopper } from '@popperjs/core';
|
|||||||
export default {
|
export default {
|
||||||
data: () => ({countries, placement: 'top'}),
|
data: () => ({countries, placement: 'top'}),
|
||||||
methods: {
|
methods: {
|
||||||
withPopper (dropdownList, component, {width},) {
|
withPopper (dropdownList, component, {width}) {
|
||||||
/**
|
/**
|
||||||
* We need to explicitly define the dropdown width since
|
* We need to explicitly define the dropdown width since
|
||||||
* it is usually inherited from the parent with CSS.
|
* it is usually inherited from the parent with CSS.
|
||||||
@@ -39,7 +39,7 @@ export default {
|
|||||||
* wrapper so that we can set some styles for when the dropdown is placed
|
* wrapper so that we can set some styles for when the dropdown is placed
|
||||||
* above.
|
* above.
|
||||||
*/
|
*/
|
||||||
createPopper(component.$refs.toggle, dropdownList, {
|
const popper = createPopper(component.$refs.toggle, dropdownList, {
|
||||||
placement: this.placement,
|
placement: this.placement,
|
||||||
modifiers: [
|
modifiers: [
|
||||||
{
|
{
|
||||||
@@ -56,6 +56,12 @@ export default {
|
|||||||
},
|
},
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To prevent memory leaks Popper needs to be destroyed.
|
||||||
|
* If you return function, it will be called just before dropdown is removed from DOM.
|
||||||
|
*/
|
||||||
|
return () => popper.destroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ transition: {
|
|||||||
|
|
||||||
When `appendToBody` is true, this function is responsible for positioning the drop down list.
|
When `appendToBody` is true, this function is responsible for positioning the drop down list.
|
||||||
|
|
||||||
|
If a function is returned from `calculatePosition`, it will be called when the drop down list
|
||||||
|
is removed from the DOM. This allows for any garbage collection you may need to do.
|
||||||
|
|
||||||
See [Dropdown Position](../guide/positioning.md) for more details.
|
See [Dropdown Position](../guide/positioning.md) for more details.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
@@ -139,6 +142,7 @@ calculatePosition: {
|
|||||||
* @param width {string} calculated width in pixels of the dropdown menu
|
* @param width {string} calculated width in pixels of the dropdown menu
|
||||||
* @param top {string} absolute position top value in pixels relative to the document
|
* @param top {string} absolute position top value in pixels relative to the document
|
||||||
* @param left {string} absolute position left value in pixels relative to the document
|
* @param left {string} absolute position left value in pixels relative to the document
|
||||||
|
* @return {function|void}
|
||||||
*/
|
*/
|
||||||
default(dropdownList, component, {width, top, left}) {
|
default(dropdownList, component, {width, top, left}) {
|
||||||
dropdownList.style.top = top;
|
dropdownList.style.top = top;
|
||||||
|
|||||||
@@ -537,9 +537,13 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When `appendToBody` is true, this function
|
* When `appendToBody` is true, this function is responsible for
|
||||||
* is responsible for positioning the drop
|
* positioning the drop down list.
|
||||||
* down list.
|
*
|
||||||
|
* If a function is returned from `calculatePosition`, it will
|
||||||
|
* be called when the drop down list is removed from the DOM.
|
||||||
|
* This allows for any garbage collection you may need to do.
|
||||||
|
*
|
||||||
* @since v3.7.0
|
* @since v3.7.0
|
||||||
* @see http://vue-select.org/guide/positioning.html
|
* @see http://vue-select.org/guide/positioning.html
|
||||||
*/
|
*/
|
||||||
@@ -551,6 +555,7 @@
|
|||||||
* @param width {string} calculated width in pixels of the dropdown menu
|
* @param width {string} calculated width in pixels of the dropdown menu
|
||||||
* @param top {string} absolute position top value in pixels relative to the document
|
* @param top {string} absolute position top value in pixels relative to the document
|
||||||
* @param left {string} absolute position left value in pixels relative to the document
|
* @param left {string} absolute position left value in pixels relative to the document
|
||||||
|
* @return {function|void}
|
||||||
*/
|
*/
|
||||||
default(dropdownList, component, {width, top, left}) {
|
default(dropdownList, component, {width, top, left}) {
|
||||||
dropdownList.style.top = top;
|
dropdownList.style.top = top;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ export default {
|
|||||||
if (context.appendToBody) {
|
if (context.appendToBody) {
|
||||||
const {height, top, left} = context.$refs.toggle.getBoundingClientRect();
|
const {height, top, left} = context.$refs.toggle.getBoundingClientRect();
|
||||||
|
|
||||||
context.calculatePosition(el, context, {
|
el.unbindPosition = context.calculatePosition(el, context, {
|
||||||
width: context.$refs.toggle.clientWidth + 'px',
|
width: context.$refs.toggle.clientWidth + 'px',
|
||||||
top: (window.scrollY + top + height) + 'px',
|
top: (window.scrollY + top + height) + 'px',
|
||||||
left: (window.scrollX + left) + 'px',
|
left: (window.scrollX + left) + 'px',
|
||||||
@@ -13,9 +13,14 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
unbind (el, bindings, vnode) {
|
unbind (el, bindings, {context}) {
|
||||||
if (vnode.context.appendToBody && el.parentNode) {
|
if (context.appendToBody) {
|
||||||
el.parentNode.removeChild(el);
|
if (el.unbindPosition && typeof el.unbindPosition === 'function') {
|
||||||
|
el.unbindPosition();
|
||||||
|
}
|
||||||
|
if (el.parentNode) {
|
||||||
|
el.parentNode.removeChild(el);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user