Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vm.$off not working when passing an array as first argument #6945

Closed
cheng-kang opened this issue Oct 27, 2017 · 3 comments
Closed

vm.$off not working when passing an array as first argument #6945

cheng-kang opened this issue Oct 27, 2017 · 3 comments
Labels

Comments

@cheng-kang
Copy link

Version

2.5.2

Reproduction link

https://jsfiddle.net/CHENGKANG/4owjvLLk/5/

Steps to reproduce

  1. Add multiple custom event listeners
this.$on(['event1', 'event2'], () => {
    console.log('This is callback.')
})
  1. Try to remove them with vm.$off
this.$off(['event1', 'event2'])
  1. Try to emit the removed events
this.$emit('event1')

What is expected?

Nothing should happen because the event listeners should have been removed.

What is actually happening?

Got "This is callback." printed in the console, which means that the event listeners are not removed as expected.


Please check my post in Vue forum for more details.

@cheng-kang
Copy link
Author

Changing the condition for specific event from arguments.length === 1 to !fn should do.

  // Fixed Version
  Vue.prototype.$off = function (event?: string | Array<string>, fn?: Function): Component {
    const vm: Component = this
    // all
    if (!arguments.length) {
      vm._events = Object.create(null)
      return vm
    }
    // array of events
    if (Array.isArray(event)) {
      for (let i = 0, l = event.length; i < l; i++) {
        this.$off(event[i], fn)
      }
      return vm
    }
    // specific event
    const cbs = vm._events[event]
    if (!cbs) {
      return vm
    }
    if (!fn) {
      vm._events[event] = null
      return vm
    }

    // specific handler
    let cb
    let i = cbs.length
    while (i--) {
      cb = cbs[i]
      if (cb === fn || cb.fn === fn) {
        cbs.splice(i, 1)
        break
      }
    }
    return vm
  }
  // Current Version
  Vue.prototype.$off = function (event, fn) {
    var this$1 = this;

    var vm = this;
    // all
    if (!arguments.length) {
      vm._events = Object.create(null);
      return vm
    }
    // array of events
    if (Array.isArray(event)) {
      for (var i = 0, l = event.length; i < l; i++) {
        this$1.$off(event[i], fn);
      }
      return vm
    }
    // specific event
    var cbs = vm._events[event];
    if (!cbs) {
      return vm
    }
    if (arguments.length === 1) {
      vm._events[event] = null;
      return vm
    }
    if (fn) {
      // specific handler
      var cb;
      var i$1 = cbs.length;
      while (i$1--) {
        cb = cbs[i$1];
        if (cb === fn || cb.fn === fn) {
          cbs.splice(i$1, 1);
          break
        }
      }
    }
    return vm
  };

@madskonradsen
Copy link
Contributor

Thanks to the nice description and analysis by @cheng-kang , I have just submitted #6949 with a passing test.

@yyx990803
Copy link
Member

closed via c24f3e4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants