【问题标题】:vue.js child component isn't updatingvue.js 子组件没有更新
【发布时间】:2020-05-23 00:39:49
【问题描述】:

我有一个父组件和一个子组件。父组件“邀请”包含多个“邀请”子组件。当我刷新网站时,所有邀请都会显示在网站上,但是一旦我更新了邀请数组(添加邀请),它就不会显示在页面上,即使我可以在 vue 开发人员上看到数组正在更新安慰。我必须刷新页面才能看到它。

当某些东西被添加到数组(更新)时,它看起来像这样: see here

将页面添加到数组后刷新页面时看起来像这样。

see here

see here

这是我的两个组件:

invitations.vue

<template>
<li class="nav-item dropdown" id="invitations">
    <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"
       data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
        Invitations <i class="far fa-bell"></i>
    </a>

    <div class="dropdown-menu" style="min-width: 20rem" aria-labelledby="navbarDropdown" 
    id="dropdownMenu">

        <div v-for="invitation in invitations" v-bind:key="invitation.id" v- 
    bind:invitations="invitations">

            <Invitation :invitation="invitation" v-on:accept-invitation="accept" v-on:reject- 
    invitation="reject" v-bind:invitation="invitation"></Invitation>

        </div>
    </div>
</li>
</template>

<script>
import Invitation from "./Invitation";

export default {
    name: "Invitations",
    props: {
        invitations: {
            type: Array,
            default: [],
            required: true
        },
        user: {
            type: Object,
            required: true
        }
    },
    methods: {
        accept(team_id) {
            axios.get('/request/accept/' + team_id)
                .then((response) => {
                    this.invitations = this.invitations.filter(invitation => invitation.id)
                });
        },
        reject(team_id) {
            axios.get('/request/reject/' + team_id)
                .then((response) => {
                    this.invitations = this.invitations.filter(invitation => invitation.id)
                });
        },
        handleIncoming(invitation) {
            this.saveNewInvitation(invitation);
            return;
        },
        saveNewInvitation(invitation) {
            this.invitations.push(invitation);
        },
    },
    mounted() {
        Echo.channel('invitations.' + this.user.id)
            .listen('NewInvitation', (e) => {
                this.handleIncoming(e);
            });
    },
    components: {Invitation}
}
</script>

invitation.vue

<template>
<div :id="invitation.id" class="mb-2">
    <a class="ml-4" title="Show team info" style="margin-right: 90px"
       :href="'/team/index/' + invitation.id" v-bind:name="invitation.name">{{invitation.name}}</a>

    <a class="float-right mr-3" href="#" @click="$emit('reject-invitation', invitation.id)">
        <i class="fas fa-times reject" :teamId="invitation.id"></i>
    </a>

    <a class="float-right mr-3" href="#" @click="$emit('accept-invitation', invitation.id)">
        <i class="fas fa-check accept" :teamId="invitation.id"></i>
    </a>
</div>
</template>

<script>
export default {
    name: "Invitation",
    props: {
        invitation: {
            type: Object,
            default: null
        }
    }
}
</script>

谁能告诉我怎么了?

【问题讨论】:

  • 你为什么有:invitation="invitation" .... v-bind:invitation="invitation" - 因为:invitation 只是v-bind:invitation 的简写 - 即它们是同一个东西......虽然不是说这是问题
  • 我尝试用 v-bind 解决它,但没有成功。但即使没有,它也不起作用。
  • 道具是对象,因此可能需要对子组件进行深度观察
  • 这是做什么的:this.invitations = this.invitations.filter(invitation =&gt; invitation.id)
  • 它应该在您接受或拒绝邀请时从列表中删除邀请。

标签: javascript node.js vue.js


【解决方案1】:

我不是 100% 知道您专门使用哪个函数来修改数组,但我注意到一个潜在的挂起的地方是......

saveNewInvitation(invitation) {
  this.invitations.push(invitation);
}

在 Vue 文档 (link to "Reactivity in Depth -- For Arrays") 中,Vue 特别警告它不会注意到底层数组的变化。

Vue 无法检测到数组的以下更改:

当您直接使用索引设置项目时,例如vm.items[indexOfItem] = newValue

当您修改数组的长度时,例如vm.items.length = newLength

虽然.push() 可能不会立即触发警报,但当您阅读推送方法(link to MDN Docs)的文档时,您会注意到它正在改变数组,而不是创建新数组。

push() 方法将一个或多个元素添加到数组的末尾并返回数组的新长度。 [强调]

正如之前的 Stack Overflow 问题 (link to discussion) 中所见,push 方法的内部工作只做两件事——改变长度,并按索引设置项目——这是 Vue 唯一的两件事 看不到。

创建新数组对象的方法之一是concat()

saveNewInvitation(invitation) {
  this.invitations = this.invitations.concat(invitation)
}

...因为,正如 concat() (link to MDN Docs) 的文档中所述:

返回值:一个新的 Array 实例。

...哪个 Vue 会正确看到。

【讨论】:

    猜你喜欢
    • 2019-10-05
    • 2020-01-22
    • 1970-01-01
    • 2019-10-10
    • 2018-04-28
    • 2018-06-08
    • 2019-04-06
    • 1970-01-01
    • 2019-06-13
    相关资源
    最近更新 更多