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

ratiw commented 8 years ago

@mozami I actually haven been working on it and have a working example for Semantic UI for a week already. It is structured exactly as you've mentioned. Each component is in its own Vueify file because I like the idea of vueify very much, very easy and clean.

However, I mainly follow vue-cli with webpack example and I'm still trying to get to know it. Anyway, the main problem right now is that the way I embeded vuetable-pagination component inside vuetable making it no longer extensible because in order for the vueify version of vuetable to know the existing vuetable-pagination components, the pagination components have to be declared in the components section of vuetable.

I have been researching if there is any way to programmatically insert child component afterward, but it doesn't seem to be possible. So, I think I have to split the vuetable-pagination out of vuetable, which should be easy enough. But you will now have to manually include vuetable-pagination manually and it should still be extensible (I think). I will play around with it this week and let you know how it goes.

mozami commented 8 years ago

Im glad to hear you're already been working on this! Webpack is also a better choice than browserify, so that would be great.

I think I understand your problem.... your suggestion of splitting the vuetable-pagination from the vuetable looks a suitable workaround for now. If a better way of injecting the pagination directly into the component can be found in future (whilst still keeping it extensible), then the component can always be improved upon.

nacr commented 8 years ago

Hello I'm using browserify and I cant get this to work :|

nacr commented 8 years ago

Any help ?

ratiw commented 8 years ago

@nacr-dev I've never work with browserify before, but if you could show me your gulpfile.js and the html maybe I can figure something out.

nacr commented 8 years ago

Ok I will give it a go,

gulpfile:

var elixir = require('laravel-elixir');

require('laravel-elixir-vueify');

elixir(function(mix) {
   mix.browserify('app.js');
}

app,js


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

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

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

new Vue({
    el: '#app',

    components: {
        Clients
    },

    computed: {

    },

    ready() {
        console.log('APP Ready to go!');
    }

});

Clients.vue


<template>

    <div class="row">
        <div class="col-md-8">
            <div class="form-inline form-group">
                <label>Search:</label>
                <input v-model="searchFor" class="form-control" @keyup.enter="setFilter">
                <button class="btn btn-primary" @click="setFilter">Go</button>
                <button class="btn btn-default" @click="resetFilter">Reset</button>
            </div>
        </div>
        <div class="col-md-4">
            <div class="dropdown pull-right">
                <button class="btn btn-default dropdown-toggle" data-toggle="dropdown">
                    <i class="glyphicon glyphicon-cog"></i>
                </button>
                <ul class="dropdown-menu">
                    <li v-for="field in fields">
                            <span class="checkbox">
                                <label>
                                    <input type="checkbox" v-model="field.visible">
                                    {{ field.title == '' ? field.name.replace('__', '') : field.title | capitalize }}
                                </label>
                            </span>
                    </li>
                </ul>
            </div>
        </div>
    </div>

    <div class="table-responsive">

        <vuetable
                api-url="http://vuetable.ratiw.net/api/users"
                pagination-path=""
                :fields="fields"
                :sort-order="sortOrder"
                table-class="table table-bordered table-striped table-hover"
                ascending-icon="glyphicon glyphicon-chevron-up"
                descending-icon="glyphicon glyphicon-chevron-down"
                pagination-class=""
                pagination-info-class=""
                pagination-component-class=""
                pagination-component="vuetable-pagination-bootstrap"
                :item-actions="itemActions"
                :append-params="moreParams"
        ></vuetable>

    </div>

</template>

<style>

</style>

<script>

    export default{
        data(){
            return{
                msg:'hello vue'
            }
        },
        components:{

        }
    }

</script>

Then in the console I get:

app-94115391c7.js:15547Uncaught ReferenceError: Vue is not defined
75 @ app-94115391c7.js:15547
s @ app-94115391c7.js:1
(anonymous function) @ app-94115391c7.js:1
76../components/clients/Clients.vue @ app-94115391c7.js:16104
s @ app-94115391c7.js:1
e @ app-94115391c7.js:1
(anonymous function) @ app-94115391c7.js:1

Does it help?

nacr commented 8 years ago

I believe the problem is as @mozami referied in is initial post.

vuetable, vuetable-pagination, vuetable-pagination-dropdown have to be in three split .vue files.

ratiw commented 8 years ago

@nacr-dev @mozami After I've made the .vue file, where should I put them?

src\components or components

How would you include them in your source code with browserify and webpack?

nacr commented 8 years ago

Well maybe in src\components I am not shore of this.

the include part I believe it would be done in my app.js or in my .vue file, like this.

import theName from 'theName';

and then refer to it in the components I believe would need to test this.

but attention I'm using bootstrap and does components are semantic ready correct?

I that case I would not be using douse components.

nacr commented 8 years ago

well i made a simple test and I believe there is more to it than this.

I'm over my head here sorry.

ratiw commented 8 years ago

@nacr-dev This puzzles me a lot since most of the components I've seen has only one file, so it is easy to identify in the webpack.config.js or package.json. I'll keep researching and hopefully find a useful example. The vueify version is coming along quite well. I just don't understand how to release it for those who use browserify and webpack yet.

nacr commented 8 years ago

ok I will keep a eye on this issue :) :+1:

Tks m:8ball:

nacr commented 8 years ago

@ratiw any Idea when we could test this out?

mozami commented 8 years ago

@ratiw Perhaps put your work in a separate git branch and we can see and test or contribute to it?

Ive been looking around at other components (that use multiple vue files), e.g VueBoot or vue-waterfall and think it may be possible to inject the pagination into the main vuetable component.

I can try and test with webpack as well.

ratiw commented 8 years ago

@nacr-dev I'm looking at publishing a dev branch with npm. I think you could try to pull in the dev branch and try it out using import or require and reference the path like so.

  var Vuetable = require('vuetable/src/components/Vuetable.vue')

@mozami Right now, I've found a way work with vuetable-pagination without having to take it out of vuetable. This is quite simple than I thought.

   var Vue = require('vue')
   var Vuetable = require('vuetable/src/components/Vuetable.vue')
   var VuetablePaginationBootstrap = require('vuetable/src/components/VuetablePaginationBootstrap.vue')

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

By registering components with Vue instead of declaring them in the components: section, Vue can now see and use it. That means you should be able to create your own pagination component, register it with Vue, and then use it by passing its name via vuetable's pagination-component prop.

nacr commented 8 years ago

ah! That would be fantastic :D as soon as it is online I will test it :+1:

mozami commented 8 years ago

@ratiw - That seems like it might work! Will also give it a test once its up

ratiw commented 8 years ago

@nacr-dev @mozami I've published the beta version of vuetable via npm. This contains the vueify version in src/components directory.

According to the related doc, you will have to pull it in using this command:

npm install vuetable --tag beta

You would require it in your .js file like so,


var Vue = require('vue')
var VueResource = require('vue-resource')
var Vuetable = require('./components/Vuetable.vue')
var VuetablePaginationBootstrap = require('./components/VuetablePaginationBootstrap.vue')

Vue.use(VueResource)

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

new Vue({
    //...
})

I think it will work but I might be wrong. Please try and let me know how it goes.

ratiw commented 8 years ago

The beta tag does not pull in the develop branch as I thought. Will look into that first.

ratiw commented 8 years ago

Using this method instead,

npm install git://github.com/ratiw/vue-table#develop --save
ratiw commented 8 years ago

If you're using bower,

bower install git://github.com/ratiw/vue-table#develop --save
ratiw commented 8 years ago

@nacr-dev @mozami Ok, got it working as expected! :)

Please try it and let me know if there's any problem.

ratiw commented 8 years ago

See https://github.com/ratiw/vuetable-example-vueify-bootstrap

If everything is ok, I'll publish v1.0.11 afterward.

nacr commented 8 years ago

Hello, will use this method npm install git://github.com/ratiw/vue-table#develop --save

Will give feedback in minutes! :)

nacr commented 8 years ago

Hello,

It seems I will need to use full path like this,

'../../../node_modules/vuetable/src/components/Vuetable.vue'

and I get a error when I run Gulp:

[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
nacr commented 8 years ago

Hmmm I get the same for Vuetable.vue

[09:35:29] gulp-notify: [Laravel Elixir] Browserify Failed!: Unexpected token

C:\Users\Nuno.Rodrigues\Code\zitauto\node_modules\vuetable\src\components\Vuetable.vue:1
<template>
^
ParseError: Unexpected token
ratiw commented 8 years ago

@nacr-dev It seems like browserify does not understand .vue file. There might be something missing in your guilpfile.js. In webpack, .vue file will be piped through vue-loader which parses out the template, script, and style sections.

ratiw commented 8 years ago

@nacr-dev Did you setup like this? https://github.com/JeffreyWay/laravel-elixir-vueify

nacr commented 8 years ago

Hello yes just like that.

nacr commented 8 years ago

If I do this,

import Vuetable from 'Vuetable';
import VuetablePaginationBootstrap from 'VuetablePaginationBootstrap';

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

Vuetable will pass but VuetablePaginationBootstrap will fail.

nacr commented 8 years ago

Now like this,

import Vuetable from 'Vuetable';

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

Gulp has no error! Nack in five to check.

nacr commented 8 years ago

I Still get the Vue is not defined erro :-1:

ratiw commented 8 years ago

@nacr-dev How do you import Vue?

nacr commented 8 years ago

On my app.js file I have it like this,

import Vue from 'vue';
import Resource from 'vue-resource';
import Validator from 'vue-validator';
nacr commented 8 years ago

I have my custom components an all is ok and I am look at yours and I can see the problem.

nacr commented 8 years ago

Hmmm checking this!

https://laracasts.com/discuss/channels/vue/parseerror-unexpected-token-template

ratiw commented 8 years ago

I think you have to import it like i did

Import Vuetable from 'vuetable/src/components/Vuetable.vue'

From my understanding import and require are the same.

nacr commented 8 years ago

@ratiw that way I still get

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

But if I do this

https://laracasts.com/discuss/channels/vue/parseerror-unexpected-token-template

no error.

Will give feed back in 10m

ratiw commented 8 years ago

Will have to go out for an hour or two. Will check back later though.

nacr commented 8 years ago

ok :+1:

nacr commented 8 years ago

This last method worked for me. It seems, .vue files have to be in the resource folder!

nacr commented 8 years ago

The only error I'm having is this

app-4ce6c70882.js:6502 [Vue warn]: Failed to resolve component: vuetable-pagination-bootstrap (found in component: <vuetable>)
ratiw commented 8 years ago

@nacr-dev Did you import and register it?

Import Vue from 'vue'
Import VueResource from 'vue-resource'
Import Vuetable from 'vuetable/src/components/Vuetable.vue'
Import VuetablePaginationBootstrap from 'vuetable/src/components/VuetablePaginationBootstrap.vue'

Vue.use(VueResource)

Vue.component('vuetable', Vuetable)
Vue.component('vuetable-pagination-bootstrap', VuetablePaginationBootstrap)
mozami commented 8 years ago

Seems like im missing out on the action here - Im going to give this a try shortly and report back as well.

@ratiw - did you test this with webpack or browserify?

ratiw commented 8 years ago

@mozami with webpack. See here

mozami commented 8 years ago

@ratiw Thanks - I've got browserify setup at the moment, will check there first and then with webpack as well later.

nacr commented 8 years ago

@mozami give some feedback on browserify so I can check if I missed something

nacr commented 8 years ago

@ratiw I will check!

nacr commented 8 years ago

@ratiw since I'm in side a component my self what I did was

components:{
            Vuetable, VuetablePaginationDropdown, VuetablePaginationBootstrap
},
mozami commented 8 years ago

@nacr-dev So far i'm getting exactly the same errors that you experienced earlier, so pretty much following your answers at the moment. Hang tight, I will report back here once I have something working or if can't get any further...