Vue.js - two components of the same type will not switch correctly

I have two components inside the template of another component, which switches depending on the click of the answer and edit buttons.

<comment-form :model="model" :model-id="modelId" :comment="comment" v-if="showEditForm && canComment" @closeForm="closeForm"></comment-form>
<comment-form :model="model" :model-id="modelId" :parent-id="comment.id" :reply-to="comment" v-if="showReplyForm && canComment" @closeForm="closeForm"></comment-form>

The problem is that it never closes the first open instance for any reason. When I press "edit" and then "reply", it seems that the "edit" instance remains open, but does not close it and opens the "reply" instance.

These are the methods that switch the display of forms:

methods: {
    closeForm: function () {
        this.showReplyForm = false;
        this.showEditForm = false;
    },
    reply: function () {
        this.showReplyForm = true;
        this.showEditForm = false;
    },
    editComment: function () {
        this.showEditForm = true;
        this.showReplyForm = false;
    },
},

I would like to understand the reason for this behavior and how to fix it.

Here is the whole file comment.vue:

<template>
    <div class="comment">
        <div class="header">
            <div v-if="!comment.user">
                <span class="name">{{comment.name}}</span>
                wrote on
                <span class="time">{{comment.created}}</span>:
            </div>
            <div v-else>
                <span class="name">{{comment.user.username}}</span> wrote on {{comment.created}}:
            </div>
        </div>
        <div class="body">
            <template v-for="line in comment.body.split('\n')">{{line}}<br></template>
        </div>
        <div class="footer">
            <a href="#" class="reply-btn" v-on:click.prevent="reply()" v-if="!isLoginRequired || isLoggedIn">
                reply
            </a>
            <span v-if="isMyComment">
                &nbsp;&bull;&nbsp;
                <a href="#" class="edit-btn" v-on:click.prevent="editComment()">
                    edit
                </a>
                &nbsp;&bull;&nbsp;
                <a href="#" class="delete-btn" v-on:click.prevent="deleteComment()">
                    delete
                </a>
            </span>
        </div>
        <comment-form :model="model" :model-id="modelId" :comment="comment" v-if="showEditForm && canComment" @closeForm="closeForm"></comment-form>
        <comment-form :model="model" :model-id="modelId" :parent-id="comment.id" :reply-to="comment" v-if="showReplyForm && canComment" @closeForm="closeForm"></comment-form>
        <comments-list :level="level + 1" v-if="hasChildren" :model="model" :model-id="modelId" :parent-id="comment.id"></comments-list>
    </div>
</template>

<script>
export default {
    props: {
        comment: null,
        modelId: null,
        level: null,
        parentId: null,
        model: {
            type: String,
            default: null
        },
    },
    computed: {
        hasChildren: function() {
            return this.$commentsStore.getters.hasChildren(
                this.model,
                this.modelId,
                this.comment.id,
            );
        },
        canComment: function() {
            return this.$commentsStore.getters.canPost;
        },
        isLoggedIn: function() {
            return this.$commentsStore.getters.isLoggedIn;
        },
        isMyComment: function () {
            return this.$commentsStore.getters.isMyComment(this.comment);
        },
        isLoginRequired: function() {
            return this.$commentsStore.getters.getConfig('loginRequired');
        }
    },
    methods: {
        closeForm: function () {
            this.showReplyForm = false;
            this.showEditForm = false;
        },
        reply: function () {
            this.showReplyForm = true;
            this.showEditForm = false;
        },
        editComment: function () {
            this.showEditForm = true;
            this.showReplyForm = false;
        },
        deleteComment: function () {
            return this.$commentsStore.dispatch('deleteComment', this.comment);
        }
    },
    data: function() {
        return {
            showReplyForm: false,
            showEditForm: false
        };
    }
};
</script>
+4
source share
1 answer

, key. , , v-for.

, , v-if s. Vue , , comment-form, . . โ€‹โ€‹Vue, tbh, - key .

new Vue({
  el: '#app',
  data: {
    showEditForm: true,
    showReplyForm: false
  },
  components: {
    commentForm: {
    	methods: {
      	close() {
        	this.$emit('close-form');
        }
      }
    }
  },
  methods: {
    closeForm: function() {
      this.showReplyForm = false;
      this.showEditForm = false;
    },
    reply: function() {
      this.showReplyForm = true;
      this.showEditForm = false;
    },
    editComment: function() {
      this.showEditForm = true;
      this.showReplyForm = false;
    },
  }
})
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <button @click="reply">
    Reply
  </button>
  <button @click="editComment">
    Edit
  </button>
  <comment-form v-if="showEditForm" key="edit" @close-form="closeForm" inline-template>
    <div>
      This is the edit form
      <button @click="close">
        Close it
      </button>
    </div>
  </comment-form>
  <comment-form id="reply" key="reply" v-if="showReplyForm" @close-form="closeForm" inline-template>
    <div>
      This is the reply form
      <button @click="close">
        Close it
      </button>
    </div>
  </comment-form>
</div>
Hide result
+4

Source: https://habr.com/ru/post/1692767/


All Articles