Vue.js - 当子组件在内部时无法访问 this.$parent <transition>

Vue.js - no access to this.$parent when child component is inside <transition>

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

问题: 在子组件内部,我无权访问 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>

通常认为使用 this.$parent 是一种不好的做法(它耦合组件并降低封装/代码清晰度。)当子组件想要将信息发送到祖先组件时,它应该发出一个事件。

删除直接访问和 $emit 名为 'deleted' 的事件:

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 方法。

在方法部分,而不是:

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