ratiw / vue-table

data table simplify! -- vuetable is a Vue.js component that will automatically request (JSON) data from the server and display them nicely in html table with swappable/extensible pagination component.
MIT License
1.83k stars 303 forks source link

Making vue-table work with browserify / webpack #12

Closed mozami closed 8 years ago

mozami commented 8 years ago

I've played around with this component and like it so far. Thank you @ratiw!

I tried to use it in a new laravel project (via browserify & using laravel elixir) and noticed it stopped working. Digging around, I see that because of the way it's structured, it wont work with browserify as it is trying to access Vue globally. Are there any plans to restructure it so it can be pulled into a project via require('vuetable') statement?

Im not an expert at this and still figuring out vue & browserify myself, but I think the component would need to be modularize / split into three .vue files: vuetable, vuetable-pagination, vuetable-pagination-dropdown. Each of these will have its own script, style and template code.

I might try and do this if I get some time and a chance to figure it out. I've added some links below for reference:

http://vuejs.org/guide/application.html#Modularization https://github.com/vuejs/vueify http://blog.tighten.co/setting-up-your-first-vuejs-site-using-laravel-elixir-and-vueify

Laracasts: https://laracasts.com/series/learning-vue-step-by-step/episodes/13 https://laracasts.com/series/painless-builds-with-laravel-elixir/episodes/9

nacr commented 8 years ago

tks m:8ball:

nacr commented 8 years ago

well I changed the code to this:

components:{
            'vuetable': Vuetable,
            'vuetable-pagination-dropdown': VuetablePaginationDropdown,
            'vuetable-pagination-bootstrap': VuetablePaginationBootstrap,
},

Same result.

ratiw commented 8 years ago

@nacr-dev Try registering pagination components outside like I did.

Vue.component('vuetable-pagination-dropdown', VuetablePaginationDropdown)
Vue.component('vuetable-pagination-bootstrap', VuetablePaginationBootstrap)

Please note the, vuetable-pagination and vuetable-pagination-dropdown use Semantic UI for styling. Since they are embbed inside vuetable, you cannot set its props directly. You have to broadcast event vuetable-pagination:setting from main vue instance to it.

new Vue({
    // ..
    ready: function() {
        this.$broadcast('vuetable-pagination:setting', 'icons', { prev: 'glyphicon glyphicon-chevron-left', next: 'glyphicon glyphicon-chevron-right'})
    }
})
nacr commented 8 years ago

Ok, I stand corrected :)

nacr commented 8 years ago

So at this moment I have no errors:

On main js in my case app.js,

import Vue from 'vue';
import Resource from 'vue-resource';
import Validator from 'vue-validator';

import Vuetable from './components/global/components/vuetable/Vuetable.vue';
import VuetablePaginationBootstrap from './components/global/components/vuetable/VuetablePaginationBootstrap.vue';
import VuetablePaginationDropdown  from './components/global/components/vuetable/VuetablePaginationDropdown.vue';

import Clients from './components/clients/Clients.vue';

Vue.use( Resource );
Vue.use( Validator );

Vue.component('vuetable', Vuetable);
Vue.component('vuetable-pagination-dropdown', VuetablePaginationDropdown)
Vue.component('vuetable-pagination-bootstrap', VuetablePaginationBootstrap)

And

in Clients.vue

I implement your sample code and all is working, I still have some stuff to check but no error in console.

nacr commented 8 years ago

But having to copy the .vue files to a dir in resource dir bugs me !

mozami commented 8 years ago

@nacr-dev Same here - im also trying to avoid that route. Playing around with the package now to see if we can do it another way.

nacr commented 8 years ago

image

@ratiw is there something missing the check boxes are not working.

nacr commented 8 years ago

@mozami will wait for you on that one :)

mozami commented 8 years ago

@nacr-dev unfortunately, havent gotten very far at the moment. I have also encountered the exact same issues as you. Will keep at it for now, and post back later with some updates.

ratiw commented 8 years ago

@nacr-dev The checkboxes are working fine with my example. Please check if you've bound them with v-model?

May be I'll try an example with browserify if I have time.

nacr commented 8 years ago

hmmm I simply changed the tableColumns data and the url from your exemple :|

mozami commented 8 years ago

@ratiw @nacr-dev I think im making some progress with browserify, though it will mean modifications on the package itself. If i get it working properly, Ill upload my work here or send a pull request. Im not sure if this will break the existing webpack integration, but Ill test out webpack later to ensure. Im heading out for a bit, will post back here a little later.

nacr commented 8 years ago

@mozami :+1:

mozami commented 8 years ago

I think the problem was quite small in the end. @nacr-dev had gone through most of the issues before me, so I just picked up from where he (or she) left off.

@ratiw i have submitted a PR - Adding the browserify transform for vueify helps eliminate the following error that @nacr-dev described above:

[09:14:43] gulp-notify: [Laravel Elixir] Browserify Failed!: Unexpected token

C:\Users\Nuno.Rodrigues\Code\app\node_modules\vuetable\src\components\VuetablePaginationBootstrap.vue:1
<template>
^
ParseError: Unexpected token

All you need to do is add the following to the package.json file of the vuetable component:

  "browserify": {
    "transform": ["vueify"]
  },

This means you do not have to move anything to the resource folder.

As for declarations, I am using the same as @nacr-dev and everything seems to work fine:

import Vue from 'vue';
import Resource from 'vue-resource';
import Vuetable from 'vuetable/src/components/Vuetable.vue';
import VuetablePaginationBootstrap from 'vuetable/src/components/VuetablePaginationBootstrap.vue';
import VuetablePaginationDropdown  from 'vuetable/src/components/VuetablePaginationDropdown.vue';

Vue.use(Resource);
Vue.component('vuetable', Vuetable);
Vue.component('vuetable-pagination-dropdown', VuetablePaginationDropdown)
Vue.component('vuetable-pagination-bootstrap', VuetablePaginationBootstrap)

Although the component can be declared within the Vue instance as well without any problems for me.

@ratiw or @nacr-dev Can you confirm if this works for you?

ratiw commented 8 years ago

@mozami Yes, it does work! Browserify can now transform .vue file. Thanks a lot. :)

I've already updated the package.json of vuetable file to include the browserify section and pushed it up to the develop branch.

@nacr-dev You could run npm update and gulp should now able to compile .vue file.

mozami commented 8 years ago

@ratiw Great! Im tied up with some other stuff at the moment, but will test out with webpack later when I get a chance.

I wanted to refactor the component structure to have one index.js file that imports in the other ".vue" files, so that you would only need to require one "vuetable" component from your js. This would also require changing the way the pagination works - which is something you've already been through I believe. I ran into template fragmentation issues so put that off on hold:

[Vue warn]: Attributes "api-url=/api/urls", ":fields=columns", ":per-page=perPage" ... are ignored on component <vuetable> because the component is a fragment instance

ratiw commented 8 years ago

@mozami Yeah, the reason that I have another div to wrap around the table and pagination is to handle the fragment instant. I had been working on separating the pagination component out of vuetable as well. This will not cause fragment instance warning because it is now a separate component but the problem is that with this implementation, you are now responsible for wiring the event between vuetable and vuetable-pagination. It is not that difficult, but it is just not convenient as it is right now. But I'm open to any suggestion anyway. :)

mozami commented 8 years ago

@ratiw OK - I understand your decision. It also makes sense from the end user's point of view and keeping things simple. I'm good with how it is for now :)

nacr commented 8 years ago

Ok, now I can do It :) fantastic.

It Works.

mozami commented 8 years ago

๐Ÿ‘ ๐Ÿ‘ I guess @ratiw can publish this now. Thanks!!

ratiw commented 8 years ago

Will try to do it tonight. @nacr-dev @mozami Thank you very much for help testing this thing. I'm really learning a lot during the process. :)

nacr commented 8 years ago

@ratiw thank you for the package it solves a gap I had with vue :)

mozami commented 8 years ago

Exactly - We should be thanking you here, @ratiw! We're all figuring it out here. I might have some more questions once I begin working with vue properly - is github issues preferred place to do so or just for issues?

ratiw commented 8 years ago

@mozami I think I would prefer you ask question in Laracasts Vue channel or Vue.js Forum. I usually learning something there. For issues, please use github as it is easier for me the track it here. Just tag me, so that I know about it. :)

ratiw commented 8 years ago

@nacr-dev In v1.0.11, you can do use vuetable-pagination:set-options to set props for pagination component.

If you use my example code, you can place this code in watch: section and the VuetablePaginationDropdown will use Twitter's Bootstrap styling.

new Vue({
    //...
    watch: {
        'paginationComponent': function(val, oldVal) {
            this.$broadcast('vuetable-pagination:set-options', {
                icons: {
                    prev: 'glyphicon glyphicon-chevron-left',
                    next: 'glyphicon glyphicon-chevron-right'
                },
                wrapperClass: 'form-inline',
                dropdownClass: 'form-control',
                linkClass: 'btn btn-default'
            })
        }
    }
})

So, update to the v1.0.11 and try it out.

mozami commented 8 years ago

@ratiw noted: will use the forums for Q&A

I'll give 1.0.11 a spin tomorrow and report back if there's any issues.