Vue.js - 两种相同类型的组件无法正确切换

时间:2018-01-26 13:50:00

标签: javascript vue.js vue-component

我在另一个组件的模板中有两个组件,根据点击"回复"和"编辑"按钮。

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

现在的问题是,它永远不会因任何原因关闭第一个打开的实例。当我点击&#34;编辑&#34;然后&#34;回复&#34;似乎&#34;编辑&#34;的实例保持开放而不是关闭它并打开&#34;回复&#34;实例

这些是切换表单显示的方法:

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

我想了解这种行为的原因以及解决方法。

以下是整个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>

1 个答案:

答案 0 :(得分:4)

这有点疯狂,但你需要一个key。这是我见过的第一个你需要new之外的例子。

发生的事情是你在两个v-for中拥有相同的组件。当Vue进行更新时,它会发现它应该有一个v-if,它已经有了。它不承认差异。我称之为Vue中的错误,但是解决方法是为每个组件实例提供comment-form

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