首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Vue.js中保持可排序数组和组件的顺序

如何在Vue.js中保持可排序数组和组件的顺序
EN

Stack Overflow用户
提问于 2016-03-14 14:05:48
回答 1查看 2.8K关注 0票数 6

我正在使用Vue.js和Dragula创建一个拖放瓷砖页面。每个瓷砖包含自己的数据集,因此每个瓷砖都是一个Vue组件。

问题是,一旦我拖放其中一个瓷砖,Vue实例中的DOM元素和数据数组就不同步,并开始导致问题。只是拖拽并不会造成问题,但是一旦我拖放一些东西,然后尝试删除它,一切都会出错。

这里有一个小提琴:https://jsfiddle.net/wfjawvnL/13/

下面是我的HTML,带有组件模板:

代码语言:javascript
复制
<body>
  <div id="app">
    <div id="draggable" class="wrapper">
      <template v-for="(index, item) in list">
        <block :id="index" :index="index" :item="item" :name="item.name">
        </block>
      </template>
    </div>
    <div class="footer">
      <pre>{{ $data | json }}</pre>
    </div>
  </div>
</body>

<template id="block-template">
  <div :id="index" :class="[name, 'block']">
    <div class="text name">{{ name }}</div>
    <div>Index: {{ index }}</div>
    <span class="delete" v-on:click="removeItem(item)">&#x2717;</span>
  </div>
</template> 

下面是我的Vue实例:

代码语言:javascript
复制
var vm = new Vue({
    el: '#app',

        data: {
        list: [
        {name: 'item1'},
        {name: 'item2'},
        {name: 'item3'},
        {name: 'item4'},
        {name: 'item5'}
      ]
    },

    methods: {
        reorder: function (element, sibling) {
            var children = element.parentNode.querySelectorAll(".block");

            var length = this.list.length;

            var ids = [];

            for (var i = 0; i < length; i++) {
                if (children[i].id) {
                    ids.push(children[i].id);
                }

                children[i].id = i;
            }

            var vm = this;

            var newArr = ids.map(function (id) {
                return vm.list[id];
            });

            this.list = newArr;
        }
    }
}); 

以下是组件:

代码语言:javascript
复制
Vue.component('block', {
    template: '#block-template',  

    props: ['index', 'name', 'item'],

    methods: {
        removeItem: function (item) {
           vm.list.$remove(item);
        }
    }
});

我这样称呼德拉古拉:

代码语言:javascript
复制
dragula([document.getElementById('draggable')]).on('drop', function (el, target, source, sibling) {
    vm.reorder(el, sibling);
});

此小提琴工作良好,但不使用组件:https://jsfiddle.net/z2s83yfL/1/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-15 00:24:02

我有两个问题。首先,我绑定数组索引并将其用作id。索引正在被更改,这也导致了id的更改。其次,在模板标签上使用v-for会导致一些问题。我把标签换成div了,现在起作用了。

工作小提琴:https://jsfiddle.net/wfjawvnL/18/

Vue的东西:

代码语言:javascript
复制
Vue.component('block', {
    template: '#block-template',  

    props: ['name', 'item'],

    methods: {
        removeItem: function (item) {
           vm.list.$remove(item);
        }
    }
});

var vm = new Vue({
    el: '#app',

        data: {
        list: [
        {name: 'item1'},
        {name: 'item2'},
        {name: 'item3'},
        {name: 'item4'},
        {name: 'item5'}
      ]
    },

    ready: function() {
        var self = this;
        var from = null;
        var drake = dragula([document.querySelector('#draggable')]);

        drake.on('drag', function(element, source) {
        var index = [].indexOf.call(element.parentNode.children, element);

        from = index;
        });

        drake.on('drop', function(element, target, source, sibling) {
        var index = [].indexOf.call(element.parentNode.children, element);

        self.list.splice(index, 0, self.list.splice(from, 1)[0]);
        });
    }
});

HTML内容:

代码语言:javascript
复制
<body>
  <div id="app">
    <div id="draggable" class="wrapper">
      <div class="wrapper" v-for="item in list">
        <block :item="item" :name="item.name">
        </block>
      </div>
    </div>
    <pre>{{ $data | json }}</pre>
  </div>
</body>

<template id="block-template">
  <div :class="[name, 'block']">
    <div class="text name" v-on:click="removeItem(item)">{{ name }}</div>
    <span class="delete" v-on:click="removeItem(item)">&#x2717;</span>
  </div>
</template>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35989703

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档