正确实现Vue.js + DataTables

时间:2015-09-24 07:37:54

标签: javascript jquery datatables vue.js

我试图实现Vue.js + jQuery的DataTables,但发生了一些奇怪的事情。

在firefox上检查这个小提琴(不使用chrome)http://jsfiddle.net/chrislandeza/xgv8c01y/

当我更改DataTable的状态(例如排序,搜索等)时:

  • 列表中新添加的数据消失
  • DOM不读取指令或vue属性

我非常确定任何试图混合vue.js +数据表的人都会遇到这个问题。你做了什么来解决这个问题?

或者是否有一个纯粹的Vue.js脚本/插件,它具有与jquery的DataTable相同(或接近)的功能? (分页,搜索,排序,要显示的条目数等)。

这里是上面小提琴的代码:

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);
        }
    }
});

非常感谢任何建议。

3 个答案:

答案 0 :(得分:28)

要使用Vue正确集成DataTables插件,需要注意以下几点:

  1. 根据您的示例,如果已准备好数据并将其呈现给DOM,则可以使用var dT = $('#app-datatable').DataTable();初始化DataTable。如果您没有完全呈现DOM <table></table>(可能是由于通过延迟的ajax调用填充了数据),则无法初始化DataTable,直到数据准备就绪。例如,如果组件中有fetchData方法,则可以在履行承诺后初始化DataTable。

  2. 要初始化后更新表,可能是由于基础表数据的更改,最好(也许是唯一的方法)是在收到新数据并将其写入之前首先销毁表。 DOM by Vue:

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

    然后,一旦数据(在您的情况下,用户数组)已更新, 重新初始化DataTable:

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

    在重新初始化之前,$ nextTick是确保Vue将新数据刷新到DOM所必需的。如果在初始化DataTable插件后更新了DOM,您将看到表数据,但通常的排序,分页等都无法正常工作。

  3. 另一个重点是,在数据集中包含行ID,并在<tr></tr>中设置密钥:

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

    如果没有track-by,Vue会在DataTables初始化后将新数据刷新到DOM时抱怨,可能是由于没有找到DataTables支持的DOM元素。

答案 1 :(得分:0)

也许你可以使用生命周期钩子,事实上这些奇怪的事情是由操纵DOM的竞争引起的。在你的vue实例中,添加一个created()钩子,然后初始化DataTable,如下所示:

conn.assigns.current_user

});

答案 2 :(得分:0)

我已经从外部提供了表数据(不是来自DataTable的Ajax调用),并且仅使用这些生命周期钩子销毁/重新创建了表:

beforeUpdate: function() {
    if (this.dataTable) {
        this.dataTable.destroy()
    }
},
updated: function() {
    this.dataTable = $(this.$el).DataTable()
}

来自https://alligator.io/vuejs/component-lifecycle/

“” beforeUpdate“挂接在组件上的数据更改之后运行,并且更新周期开始,就在修补和重新呈现DOM之前。它使您能够在组件上的任何反应性数据实际获得之前获取其新状态。呈现。”

“更新的挂钩将在组件上的数据更改后重新运行,并且DOM重新呈现。如果在属性更改后需要访问DOM,这可能是最安全的位置。”

相关问题