当我打开当前目标时,如何在组件的所有实例中隐藏 div

How can I hide a div in all instances of a component while I open it my current target

我在点击子组件时显示 div。该组件在任何类型的循环之外的页面上多次呈现。当我在组件的这个特定实例中显示 div 时,我想在所有其他组件中隐藏它。我试过使用 ref 关闭所有带有 DOM 操作的实例,但这没有用。

 <template>
  <span>
    <div class="options--small" @click="toggleOptions" />
    <div v-show="showOptions" ref="test" class="options-menu">
      <slot />
    </div>
  </span>
</template>
<script>
export default {
  name: 'ShowOptions',
  data () {
    return {
      showOptions: false
    }
  },
  methods: {
    toggleOptions () {
      this.$refs.test.style.display = 'none'
      this.showOptions = !this.showOptions
    }
  }
}
</script>

您绝对不应该使用 ref 或直接访问 DOM;那永远是最后的手段。

每个选项菜单的可见性由相应组件的 showOptions 属性 控制。您需要一种与希望它们隐藏菜单的每个组件实例进行通信的方式。这可以通过使用事件总线来实现。为每个 Vue 项目实现这个通常是个好主意,这样您就可以执行解耦的组件间通信。

如果您使用的是 Vue 2,则可以将 Vue 实例用作事件总线。

未测试:

// event-bus.js

const v = new Vue()

export function on(event, fn) {
  v.$on(event, fn)
}

export function off(event, fn) {
  v.$off(event, fn)
}

export function emit(event, ...args) {
  v.$emit(event, ...args)
}
import * as bus from './event-bus.js'

export default {
  data() {
    return {
      showOptions: false
    }
  },
  created() {
    bus.on('ShowOptions.hide', this.onShowOptionsHide)
  },
  destroyed() {
    // Important otherwise leaks memory
    bus.off('ShowOptions.hide', this.onShowOptionsHide)
  },
  methods: {
    onShowOptionsHide() {
      // Hide our options menu when other menu shows theirs
      this.showOptions = false
    },
    toggleOptions() {
      if (this.showOptions) {
        this.showOptions = false
      } else {
        // Tell other components to hide their options menu
        bus.emit('ShowOptions.hide')
        this.showOptions = true
      }
    }
  }
}

如果您不想使用事件总线,那么您可以跟踪每个组件实例以隐藏它们的菜单。

未测试:

const instances = new Set()

export default {
  data () {
    return {
      showOptions: false
    }
  },
  created() {
    instances.add(this)
  },
  destroyed() {
    instances.delete(this)
  },
  methods: {
    hideOtherMenus() {
      for (const i of instances) {
        if (i !== this) {
          i.showOptions = false
        }
      }
    },
    toggleOptions() {
      this.hideOtherMenus()
      this.showOptions = !this.showOptions
    }
  }
}