【问题标题】:How to keep sortable arrays and components in order in Vue.js如何在 Vue.js 中保持可排序数组和组件的顺序
【发布时间】:2016-03-14 14:05:48
【问题描述】:

我正在使用 Vue.js 和 Dragula 来制作拖放磁贴页面。每个 tile 都包含自己的一组数据,因此每个 tile 都是一个 Vue 组件。

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

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

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

<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 实例:

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

这是组件:

Vue.component('block', {
    template: '#block-template',  

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

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

我这样称呼 Dragula:

dragula([document.getElementById('draggable')]).on('drop', function (el, target, source, sibling) {
    vm.reorder(el, sibling);
});

这个小提琴工作正常,但不使用组件:https://jsfiddle.net/z2s83yfL/1/

【问题讨论】:

    标签: javascript drag-and-drop vue.js


    【解决方案1】:

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

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

    Vue 的东西:

    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 的东西:

    <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>
    

    【讨论】:

    猜你喜欢
    • 2022-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 2017-07-07
    • 2012-11-22
    相关资源
    最近更新 更多