简体   繁体   English

属性值未在子组件Vue.js中更新

[英]Prop value isn't updating in child component Vue.js

I'm adding a way for the parent App.vue tell all child components to close every modal you have open and for any given child to tell the parent to hide the overlay if someone clicks on the main app div. 我为父App.vue添加了一种方法, App.vue告诉所有子组件关闭您打开的每个模式,并让任何给定的子组件告诉父如果某人单击主应用div则可以隐藏覆盖。 So for example if the services page has a modal open to view some details, an overlay will be active that is set in the parent App.vue component, and if I click anywhere outside of the modal, the modal will close and the child will tell the parent to close the overlay. 因此,例如,如果服务页面打开了一个模态以查看一些详细信息,则将在父App.vue组件中设置一个叠加层,如果我单击模态之外的任何位置,则模态将关闭,子级将关闭告诉父母关闭覆盖层。 I have it setup this way so that it's something globally available and not isolated to a single component. 我以这种方式设置它,以便它在全球范围内可用,而不是孤立于单个组件。

<template>
  <div id="app" v-cloak :class="{'overlay-layer' : overlay.active}" v-on:click="close($event)">

    <Header/>

    <transition>
      <router-view v-on:overlay="overlay.active = $event" :closeAllModals="overlay.close"/>
    </transition>

    <Footer/>

  </div>
</template>

<script>
import Header from '@/components/header/Header.vue';
import Footer from '@/components/footer/Footer.vue';

export default {
  components: {
    Header,
    Footer
  },
  props: {
    closeAllModals: Boolean
  },
  data: function() {
    return {
      overlay: { active: false, close: false }
    };
  },
  methods: {
    close(e) {
      if (this.overlay.active && e.toElement.id === 'app') {
        this.overlay = {
          active: false,
          close: true
        }
      }
    }
  }
};
</script>

The problem is that this only executes once, so for example in the services page I have: 问题是,这仅执行一次,因此例如在服务页面中,我有:

import Header from '@/components/header/Header.vue';
import Footer from '@/components/footer/Footer.vue';

export default {
  name: 'services',
  components: {
    Header,
    Footer
  },
  props: {
    closeAllModals: Boolean
  },
  data: function() {
    return {
      overlay: false,
      activeMember: Object,
    };
  },
  methods: {
    setActiveMember(member, open) {
      this.activeMember = member;
      if (open) {
        this.activeMember.active = true;
        this.overlay = true;
      } else {
        this.activeMember.active = false;
        this.overlay = false;
      }
      this.$emit('overlay', this.overlay);
      this.$forceUpdate();
    },
  watch: {
    closeAllModals: function() {
      this.activeMember.active = false;
      this.overlay = false;
      this.$forceUpdate();
      console.log('runs once');
    }
  }
};

So this works, but only works the first time. 因此这有效,但仅在第一次有效。 The prop only sends the updated value to the child only once. 该道具仅将更新后的值发送给孩子一次。 I've tried watching the prop in the child and using forceUpdate too but it isn't working. 我尝试在孩子中观看道具并使用forceUpdate,但它不起作用。 How do I make this run every single time? 如何使每次运行?

A global event bus could help when components have to talk to each other across different parent/child levels. 当组件必须在不同的父/子级别之间相互通信时,全局事件总线可能会有所帮助。 Below is a good write up on that: 以下是关于此的很好的写法:

https://alligator.io/vuejs/global-event-bus https://alligator.io/vuejs/global-event-bus

Note: but be sure to use it only when necessary and remove the listeners in beforeDestroy life cycle of the component 注:但可以肯定的只有在必要时才使用,并删除在听众beforeDestroy组件的生命周期

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM