metafizzy / packery

:bento: Gapless, draggable grid layouts
https://packery.metafizzy.co
4.13k stars 315 forks source link

How to trigger "shiftLayout" inside Vue JS component on @click event? #503

Closed tophat1986 closed 6 years ago

tophat1986 commented 6 years ago

I've recently ported my code and packery layout over into a Vue JS component and I have some success. I've used the npm here to achieve - https://www.npmjs.com/package/vue-packery-plugin

I've got it working nicely with Vue and inside a component so it's packing as needed. However, I have these cards that expand "vertically" on a @click event to show more info and from researching, I need to use the "shiftLayout" function to redraw (I think) all the cards as they are affected from this vertical height change. Like so:

$grid.packery('shiftLayout');

But..... I'm only a novice at Vue/JS and I don't know how to trigger this necessary function in my Vue component setup. I just keep getting the console error "packery is not a function". Because I've initialised it as a package I am out of my depth here on how to call the packery plugin inside a method!?

_Sorry, I didn't think a test case would be of benefit this line of question. Any VueJs users able to help? The NPM for this Vue wrapper is not very popular YET, so not much guidance written. 😞

desandro commented 6 years ago

Hello! Thanks for reporting this issue. Sorry, I do not have expertise with Vue. From looking at the component's source code, I believe Packery's API needs to be exposed in the Vue component. You'll have to open an issue on the component's tracker. Sorry I cannot be of more help here.

tophat1986 commented 6 years ago

Thanks for your reply @desandro!

Since I posted this, the package I mentioned has been updated by the owner to work with events with Vue which is great!

I also came over a problem when using Vue (in a Virtual DOM) to initiate Packery on the "nextTick" so it will load after the page is rendered. You can also use it in the updated hook without nextTick for reference.

Unfortunately the issue I have is still happening annoyingly! I've spent days on this now :( I don't think it's anything to do with Vue now and more to do with using "min-height" in CSS to control the size of the DIV?

Anyway, I've made a reduced test case now so you can see how Packery is handling this - https://codepen.io/top_hat/pen/QrvEwK

desandro commented 6 years ago

Again, I'm don't have any experience with Vue. I believe the issue is that you need layout to be called after the changes in the DOM have been made. I'm not sure if Vue provides that kind of functionality.

One hack to show the issue is to use a setTimeout for layout.

    showIt() {
      this.show_info = !this.show_info;
      setTimeout( function() {
        $grid.packery('layout'); 
      });
    }

See demo on CodePen

tophat1986 commented 6 years ago

Thanks for this hack. I've got it working now! :)

Part of the solution: https://github.com/t-k-f/vue-packery-plugin/issues/3

Also, for some reason, one bug I had was that it wouldn't work with with Vue Transitions on the component! https://vuejs.org/v2/guide/transitions.html#CSS-Transitions