Vue.js - 当子组件在 <transition> 内时,无法访问 this.$parent
Posted
技术标签:
【中文标题】Vue.js - 当子组件在 <transition> 内时,无法访问 this.$parent【英文标题】:Vue.js - no access to this.$parent when child component is inside <transition> 【发布时间】:2021-05-26 18:06:01 【问题描述】:我想要什么:我有两个组件,父组件(Wall.vue)和子组件(PostItem.vue)。每个PostItem
都有一个删除 按钮。单击时,会发送对我的 API 的请求,并从数据库中删除该项目。然后我想调用父组件的getPosts
函数再次获取所有帖子(这次没有删除帖子)。
问题:在子组件内部,我无法访问this.$parent
对象(或者更具体地说,它只是空的并且不包含函数),所以我不能调用getPosts
-函数。当我删除父组件中包含子组件的 <transition-group>
时,一切正常。
这里有什么问题?
父组件(Wall.vue)
模板部分:
<template>
<div class="Wall view">
<transition-group name="wallstate">
<template v-else-if="messages">
<PostItem
v-for="(message, index) in messages"
:key="index"
:message="message"
:index="index"
class="PostItem"
/>
</template>
<h1 v-else>
Could not load messages. Please try later.
</h1>
</transition-group>
</div>
</template>
脚本部分:
<script>
import mapGetters from 'vuex';
import postsAPI from '../services/posts.service.js';
import PostItem from '../components/PostItem.vue';
export default
components:
PostItem,
,
data()
return
messages: null,
;
,
methods:
getPosts()
///////Do stuff
;
</script>
子组件(PostItem.vue)
模板部分
<template>
<div class="PostItem__message frosted">
<p class="PostItem__messageContent"> message.content </p>
<p>
by: <strong> message.user.username </strong>
</p>
<a
@click="deletePost"
:data-id="message._id"
v-if="message.user._id === user.id"
>
Delete
</a>
</div>
</template>
脚本部分:
<script>
import postsAPI from '../services/posts.service.js';
import mapGetters from 'vuex';
export default
name: 'PostItem',
props:
message:
type: Object,
required: true,
,
index:
type: Number,
required: true,
,
,
computed:
...mapGetters(
user: 'auth/user',
),
,
methods:
deletePost(e)
const id = e.target.dataset.id;
postsAPI.removeOne(id).then((res) =>
this.$parent.getPosts(); <-------- PROBLEM HERE
);
,
,
;
</script>
【问题讨论】:
【参考方案1】:通常认为使用this.$parent
是一种不好的做法(它会耦合组件并降低封装/代码清晰度。)子组件在想要向祖先组件发送信息时应该发出事件。
删除直接访问和$emit
一个名为“已删除”的事件:
deletePost(e)
const id = e.target.dataset.id;
postsAPI.removeOne(id).then((res) =>
this.$emit('deleted'); // Emitting the event
);
,
父级应该监听deleted
事件并运行事件处理程序:
<PostItem
v-for="(message, index) in messages"
:key="index"
:message="message"
:index="index"
class="PostItem"
@deleted="getPosts"
/>
当被@deleted
事件监听器触发时,父级会调用getPosts
方法。
【讨论】:
【参考方案2】:在方法部分,而不是:
methods:
deletePost(e)
const id = e.target.dataset.id;
postsAPI.removeOne(id).then((res) =>
this.$parent.getPosts();
);
,
,
你可以试试这个:
methods:
deletePost(e)
const id = e.target.dataset.id;
let self=this;
postsAPI.removeOne(id).then((res) =>
self.$parent.getPosts();
);
由于作用域链,.then() 中的 'this' 与变量 'self' 指向的变量环境不同。所以也许这就是它无法工作的原因。
【讨论】:
@Beso 请突出显示您认为是复制的部分和复制的内容:)以上是关于Vue.js - 当子组件在 <transition> 内时,无法访问 this.$parent的主要内容,如果未能解决你的问题,请参考以下文章