【问题标题】:Vue.js - no access to this.$parent when child component is inside <transition>Vue.js - 当子组件在 <transition> 内时,无法访问 this.$parent
【发布时间】:2021-05-26 18:06:01
【问题描述】:

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

问题:在子组件内部,我无法访问this.$parent 对象(或者更具体地说,它只是空的并且不包含函数),所以我不能调用getPosts-函数。当我删除父组件中包含子组件的 &lt;transition-group&gt; 时,一切正常。

这里有什么问题?

父组件(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>

【问题讨论】:

    标签: javascript vue.js vuejs2 vue-component vue-transitions


    【解决方案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 请突出显示您认为是复制的部分和复制的内容:)
      猜你喜欢
      • 2018-02-23
      • 2019-04-05
      • 1970-01-01
      • 2021-01-10
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多