2015-09-24 17 views
9

Sto cercando di implementare Vue.js + i DataTable di jQuery ma si verificano cose strane.Implementazione corretta di Vue.js + DataTable

Scegli questa violino su firefox (non funziona su Chrome): http://jsfiddle.net/chrislandeza/xgv8c01y/

quando cambio lo stato di DataTable (ad esempio, ordinare, ricercare, ecc):

  • nuovi dati aggiunti sulla lista scompare
  • il DOM non legge le direttive o le proprietà vue

Sono abbastanza sicuro che chiunque abbia provato a mescolare vue.js + datatables abbia riscontrato questo problema. cosa hai fatto per risolvere questo?

oppure esiste un puro script/plug-in Vue.js che ha la stessa funzionalità (o chiusa) come DataTable di jQuery? (impaginazione, ricerca, ordinamento, numero di voci da mostrare, ecc.).

Ecco il codice del violino sopra:

HTML:

<div class='container-fluid' id="app"> 
     <div class='row'> 
      <div class='col-md-9'> 
       <table class="table table-bordered" id="app-datatable"> 
        <thead> 
         <tr> 
          <th>Name</th> 
          <th>Age</th> 
          <th></th> 
         </tr> 
        </thead> 
        <tbody> 
         <tr v-repeat="user: users"> 
          <td>{{ user.name }}</td> 
          <td>{{ user.age }}</td> 
          <td> 
           <button type="button" v-on="click: foo(user)">Action</button> 
          </td> 
         </tr> 
        </tbody> 
       </table> 
      </div> 
      <div class='col-md-3'> 
       <div class="form-group"> 
        <label>Name</label> 
        <input type="text" 
          class="form-control" 
          v-model="newUser.name" 
          > 
       </div> 

       <div class="form-group"> 
        <label>Age</label> 
        <input type="name" 
          class="form-control" 
          v-model="newUser.age" 
          > 
       </div> 
       <button type="submit" class="btn btn-primary" v-on="click: addUser()">Add</button> 
      </div> 
     </div> 
    </div> 

JavaScript:

$(document).ready(function() { 
    var dT = $('#app-datatable').DataTable(); 
}); 

var vm = new Vue({ 
    el: '#app', 
    data: { 
     newUser: {}, 
     users: [ 
      {name: 'Chris', age: 1}, 
      {name: 'John', age: 2} 
     ] 
    }, 
    methods:{ 
     addUser: function(){ 
      this.users.push(this.newUser); 
      this.newUser = {}; 
     }, 
     foo: function(user){ 
      console.log(user.name); 
     } 
    } 
}); 

tutti i suggerimenti sono molto apprezzate.

+0

il violino non funziona perché ci si riferisce a githubusercontent direttamente - si dovrebbe utilizzare rawgithub.com -> ** http: //jsfiddle.net/cLd46juf/** vedere [** Reference GitHub file in jsFiddle **] (http://stackoverflow.com/q/9841026/1407478) – davidkonrad

+2

Il problema è analogo a quando si utilizza dataTables lo stile jQuery in angolare. Entrambi stanno cercando di manipolare il DOM, vue sta vincendo la battaglia. Triste a dirsi, non penso che esista una soluzione semplice e immediata. – davidkonrad

risposta

17

per ottenere il DataTable Plugin integrati correttamente con Vue, ci sono alcune cose da tenere a mente:

  1. Per il tuo esempio, è possibile utilizzare var dT = $('#app-datatable').DataTable(); per inizializzare i DataTable se hai già i dati pronti e reso al DOM. Se non hai il rendering completo del DOM <table></table> (forse a causa di dati popolati tramite una chiamata ajax in ritardo), non puoi inizializzare i DataTable finché i dati non sono pronti. Ad esempio, se hai un metodo fetchData nel componente, puoi inizializzare il DataTable una volta che la promessa è stata soddisfatta.

  2. Per aggiornare la tabella dopo l'inizializzazione, forse a causa di una modifica dei dati della tabella sottostante, il migliore (forse l'unico modo) consiste nel distruggere prima la tabella, prima che i nuovi dati siano ricevuti e scritti nel DOM per Vue:

    var dT = $('#app-datatable').DataTable(); 
    dT.destroy(); 
    

    Poi, una volta che i dati (nel tuo caso, la matrice degli utenti) è stato aggiornato, reinizializzare il DataTable come così:

    this.$nextTick(function() { 
        $('#app-datatable').DataTable({ 
         // DataTable options here... 
        }); 
    }) 
    

    il $ nextTick è necessario assicurarsi che Vue abbia svuotato i nuovi dati su DOM, prima di reinizializzare. Se il DOM viene aggiornato dopo che il plug-in DataTable è stato inizializzato, vedrai i dati della tabella, ma il solito ordinamento, impaginazione, ecc. Non funzionerà.

  3. Un altro punto importante, è quello di avere una fila id nel set di dati, e impostare la chiave nella <tr></tr>:

    <tr v-repeat="user: users" track-by="id">

    Senza la track-by, Vue si lamentano quando si lava i nuovi dati al DOM dopo che DataTables è stato inizializzato, probabilmente a causa della mancata ricerca di elementi DOM hi-jacked da DataTables.

+3

Ho appena creato il mio account per darti 1 punto. Non hai idea di quanto la cosa id track sia appena mi ha aiutato! –

0

forse si possono usare i ganci del ciclo di vita, infatti queste cose strane sono causate dalla competizione di manipolazione del DOM. nel vostro caso vue, aggiungere un creato gancio() poi inizializzare il DataTable, proprio come il seguente:

var vm = new Vue({ 
el: '#app', 
data: { 
    newUser: {}, 
    users: [ 
     {name: 'Chris', age: 1}, 
     {name: 'John', age: 2} 
    ] 
}, 
methods:{ 
    addUser: function(){ 
     this.users.push(this.newUser); 
     this.newUser = {}; 
    }, 
    foo: function(user){ 
     console.log(user.name); 
    } 
}, 
created(){ 
     this.$nextTick(function() { 
     $('#app-datatable').DataTable(); 
     }) 
    } 

});