3

我想要什么:我有两个组件,父组件(Wall.vue)和子组件(PostItem.vue)。每个PostItem都有一个删除按钮。单击时,会发送对我的 API 的请求,并从数据库中删除该项目。然后我想调用getPosts父组件的函数再次获取所有帖子(这次没有删除的帖子)。

问题:在子组件内部,我无法访问this.$parent对象(或者更具体地说,它只是空的并且不包含函数),所以我不能调用getPosts-Function。当我删除<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>
4

2 回答 2

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

当事件监听器getPosts触发时,父级将调用该方法。@deleted

于 2021-02-24T12:22:41.523 回答
1

在方法部分内,而不是:

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' 相同的变量环境。所以也许这就是它无法工作的原因。

于 2021-12-03T03:38:10.710 回答