vuejs / vue

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core
http://v2.vuejs.org
MIT License
207.97k stars 33.68k forks source link

Is it better to trigger attached event after ready event? #1404

Closed jiangfengming closed 9 years ago

jiangfengming commented 9 years ago

Sometimes the attached hook need to wait for ready to do some one-time initial DOM related operations, so the logic of attached hook will be different when it is attached for the first time or re-attached. Currently I have to use Promise.

{
  attached: function() {
    var self = this;
    this.ready = new Promise(function(resolve) {
      self.readyResolve = resolve;
    });

    this.ready.then(function() {
      self.animation.play();
      $(self.$els.bar).somePlugin('update');
    });
  },

  ready: function() {
    // create a GSAP animation object
    this.animation = new TimelineLite().to(this.$els.foo, { opacity: 1 });

    // init a jQuery plugin
    $(this.$els.bar).somePlugin();

    this.readyResolve();
  }
}
AlexandreBonaventure commented 9 years ago

Why don't you use the activate hook ? https://github.com/yyx990803/vue/issues/1169

jiangfengming commented 9 years ago

@AlexandreBonaventure activate is called BEFORE component insertion. What I need is a one-time event after DOM insertion and before attached, so I can do some DOM related initial jobs before attached.

yyx990803 commented 9 years ago

There's no need to do this sort of juggling. The timeline is not DOM-dependent, you can just create it in the created hook or compiled hook.

jiangfengming commented 9 years ago

The example isn't very clear, I have added some key parts. TimelineLite (part of GSAP animation library) is surely DOM-dependent. And I'm not talking about GSAP only, this is just a example of use case.

Most of the jQuery plugins and many libraries are DOM-dependent, you can't initiate them in the created hook, there is no elements at that time. Even in the 'compiled` hook, some libraries won't work, because the elements haven't been inserted into the DOM tree.

yyx990803 commented 9 years ago

It's still possible to use attached only though:

attached: function () {
  if (!this.animation) {
    this.animation = new TimelineLite().to(this.$els.foo, { opacity: 1 });
  }
  if (!this.pluginInitialized) {
    $(this.$els.bar).somePlugin()
    this.plguinInitialized = true
  }
  this.animation.play();
  $(this.$els.bar).somePlugin('update');
}
jiangfengming commented 9 years ago

OK, this is a acceptable solution : )