Browse Source

feat(config): expose config.useEventDelegation and default to false

Evan You 7 năm trước cách đây
mục cha
commit
3be1c5d67e

+ 10 - 0
src/core/config.js

@@ -19,6 +19,7 @@ export type Config = {
   warnHandler: ?(msg: string, vm: Component, trace: string) => void;
   ignoredElements: Array<string | RegExp>;
   keyCodes: { [key: string]: number | Array<number> };
+  useEventDelegation: boolean;
 
   // platform
   isReservedTag: (x?: string) => boolean;
@@ -83,6 +84,15 @@ export default ({
   // $flow-disable-line
   keyCodes: Object.create(null),
 
+  /**
+   * Use event delegation - this works around a few async edge cases caused by
+   * microtask / DOM event racing conditions, and should in theory save some
+   * memory.
+   *
+   * Off by default for backwards compatibility.
+   */
+  useEventDelegation: false,
+
   /**
    * Check if a tag is reserved so that it cannot be registered as a
    * component. This is platform-dependent and may be overwritten.

+ 8 - 2
src/platforms/web/runtime/modules/events.js

@@ -1,5 +1,6 @@
 /* @flow */
 
+import config from 'core/config'
 import { isDef, isUndef } from 'shared/util'
 import { updateListeners } from 'core/vdom/helpers/index'
 import { isIE, isPhantomJS, supportsPassive } from 'core/util/index'
@@ -50,7 +51,12 @@ function add (
   capture: boolean,
   passive: boolean
 ) {
-  if (!capture && !passive && delegateRE.test(name)) {
+  if (
+    !capture &&
+    !passive &&
+    config.useEventDelegation &&
+    delegateRE.test(name)
+  ) {
     const count = eventCounts[name]
     let store = target.__events
     if (!count) {
@@ -150,7 +156,7 @@ function remove (
   _target?: HTMLElement
 ) {
   const el: any = _target || target
-  if (!capture && delegateRE.test(name)) {
+  if (!capture && config.useEventDelegation && delegateRE.test(name)) {
     el.__events[name] = null
     if (--eventCounts[name] === 0) {
       removeGlobalHandler(name)

+ 4 - 0
test/e2e/specs/async-edge-cases.html

@@ -6,6 +6,10 @@
     <script src="../../../dist/vue.min.js"></script>
   </head>
   <body>
+    <script>
+      // this is necessary to make these cases pass
+      Vue.config.useEventDelegation = true
+    </script>
 
     <!-- #4510 click and change event on checkbox -->
     <div id="case-1">

+ 1 - 0
types/test/vue-test.ts

@@ -75,6 +75,7 @@ class Test extends Vue {
     config.keyCodes = { esc: 27 };
     config.ignoredElements = ['foo', /^ion-/];
     config.async = false
+    config.useEventDelegation = true
   }
 
   static testMethods() {

+ 1 - 0
types/vue.d.ts

@@ -74,6 +74,7 @@ export interface VueConfiguration {
   warnHandler(msg: string, vm: Vue, trace: string): void;
   ignoredElements: (string | RegExp)[];
   keyCodes: { [key: string]: number | number[] };
+  useEventDelegation: boolean;
   async: boolean;
 }