javascript - Vue.js - Remove specific component dynamically - Stack Overflow

I am trying to dynamically createremove a Vue ponent. I have figured out how to dynamically add the po

I am trying to dynamically create/remove a Vue ponent. I have figured out how to dynamically add the ponent, but I am having some troubles with allowing the users to remove the specific ponent.

Consider below two Vue files:

TableControls.vue

<a v-on:click="addColumn">Add Column</a>

<script>
    export default {
        methods: {
            addColumn: function () {
                Event.$emit('column-was-added')
            }
        }
    };

</script>

DocumentViewer.vue:

<div v-for="count in columns">
   <VueDragResize :id="count">
      <a @click="removeColumn(count)">Remove Column</a>
   </VueDragResize>
</div>

<script>
import VueDragResize from 'vue-drag-resize';

    export default {
        ponents: {
            VueDragResize
        },
        data() {
            return {
                columns: [1],
            }

        },
        created() {
            Event.$on("column-was-added", () => this.addColumn())
        },

        methods: {
            addColumn: function () {
                this.columns.push(this.columns.length + 1)
            },
            removeColumn: function (id) {
                this.columns.splice(id, 1)
            }
        }
    };
</script>

As you can see, whenever a user clicks on <a v-on:click="addColumn">Add Column</a>, it will submit an event, and the DocumentViewer.vue file will pick up it, firing the addColumn method. This will ultimately create a new <VueDragResize></VueDragResize> ponent.

This works great.

The problem is when I want to remove the ponent again. My removeColumn method simply removes an id from the columns array:

removeColumn: function (id) {
    this.columns.splice(id, 1)
}

This results in that a column is in fact removed. However, consider below example. When user clicks on the remove icon for the first column, it will remove the 2nd column instead. (And when there is only one column present, it cannot be removed).

I believe this is due to the fact that I splice() the array, but I cannot see how else I can remove the ponent dynamically?

I am trying to dynamically create/remove a Vue ponent. I have figured out how to dynamically add the ponent, but I am having some troubles with allowing the users to remove the specific ponent.

Consider below two Vue files:

TableControls.vue

<a v-on:click="addColumn">Add Column</a>

<script>
    export default {
        methods: {
            addColumn: function () {
                Event.$emit('column-was-added')
            }
        }
    };

</script>

DocumentViewer.vue:

<div v-for="count in columns">
   <VueDragResize :id="count">
      <a @click="removeColumn(count)">Remove Column</a>
   </VueDragResize>
</div>

<script>
import VueDragResize from 'vue-drag-resize';

    export default {
        ponents: {
            VueDragResize
        },
        data() {
            return {
                columns: [1],
            }

        },
        created() {
            Event.$on("column-was-added", () => this.addColumn())
        },

        methods: {
            addColumn: function () {
                this.columns.push(this.columns.length + 1)
            },
            removeColumn: function (id) {
                this.columns.splice(id, 1)
            }
        }
    };
</script>

As you can see, whenever a user clicks on <a v-on:click="addColumn">Add Column</a>, it will submit an event, and the DocumentViewer.vue file will pick up it, firing the addColumn method. This will ultimately create a new <VueDragResize></VueDragResize> ponent.

This works great.

The problem is when I want to remove the ponent again. My removeColumn method simply removes an id from the columns array:

removeColumn: function (id) {
    this.columns.splice(id, 1)
}

This results in that a column is in fact removed. However, consider below example. When user clicks on the remove icon for the first column, it will remove the 2nd column instead. (And when there is only one column present, it cannot be removed).

I believe this is due to the fact that I splice() the array, but I cannot see how else I can remove the ponent dynamically?

Share Improve this question edited Jun 17, 2019 at 6:30 oliverbj asked Jun 17, 2019 at 6:18 oliverbjoliverbj 6,08230 gold badges98 silver badges198 bronze badges 2
  • there are missing parts in your sample. Where is the part that generates the columns ? – y_nk Commented Jun 17, 2019 at 6:24
  • @y_nk sorry, I have updated my question. – oliverbj Commented Jun 17, 2019 at 6:31
Add a ment  | 

3 Answers 3

Reset to default 3

I see, Array on Vue does not re render when you modify them.

You need to use the

Vue.set(items, indexOfItem, newValue)

if you want to modify

and use

Vue.delete(target, indexOfObjectToDelete);

If you want to delete an item from an array

You may read the additional info here https://v2.vuejs/v2/api/#Vue-delete

If you want to delete an item from array. Using this will cause the ponent to rerender.

In this case it will be intuitive to do this

removeColumn: function (id) {
   Vue.delete(this.columns, id)
}

Note that id should be the index. Vue.delete ensures the re-render of the ponent.

EDIT, you must use the index, instead of the count here.

<div v-for="(count, index) in columns">
   <VueDragResize :id="index">
      <a @click="removeColumn(index)">Remove Column</a>
   </VueDragResize>
</div>

I would remend reshaping your data, each element should be an object with an id and whatever other properties you want. Not simply an id then you would need something like this:

removeColumn(id) {
                const elToRemove = this.columns.findIndex(el => el.id === id)
                let newArr = [elToRemove, ...this.columns]
                this.columns = newArr
            }

Also make another puted property for columns like this to make sure they change dynamically (when you add/remove):

puted: {
      dynColumns(){ return this.columns}
    }

I have same problem, and I found the solution of this problem. It is need to set #key with v-for. This is Built-in Special Attributes.

By default, if you do not set "#key", array index is set to#key. So if array length is 3, #key is 0,1,2. Vue identify each v-for elements by key. If you remove second value of array, then array index is 0 and 1, because array length is 2. Then Vue understand that #key==2 element removed, So Vue remove 3rd ponent. So if you remove second value of array, if no #key, third ponent will be removed. To avoid this, need to set #key to identify ponent like this:

let arr = [
  { id: 'a', ...},
  { id: 'b', ...},
  { id: 'c', ...}
];

<div v-for="obj in arr" :key="obj.id">
  <someYourComponent>
    ...
  </someYourComponent>
</div>

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745658215a4638670.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信