【问题标题】:Get v-slot's value获取 v-slot 的值
【发布时间】:2021-06-02 14:26:01
【问题描述】:

我有一个这样的组件:

<template>
  <Popover v-slot="{ open }" :ref="`${name}-parent`">
    <div>
      <PopoverButton :ref="name">
        <div>
          <slot name="buttoncontent"></slot>
        </div>
        <ChevronDownIcon/>
      </PopoverButton>
    </div>
    <transition>
      <PopoverPanel>
        <slot name="popovercontent"></slot>
      </PopoverPanel>
    </transition>
  </Popover>
</template>

<script>
import {Popover, PopoverButton, PopoverPanel} from '@headlessui/vue'
import {ChevronDownIcon} from '@heroicons/vue/solid'

export default {
  name: 'PopoverMenu',
  props: {
    name: {
      type: String,
    },
    title: {
      type: String,
      default: ''
    },
  },
  components: {
    Popover,
    PopoverButton,
    PopoverPanel,
    ChevronDownIcon,
  },
  setup () {
    return {}
  },
  watch: {
    '$route' () {
      // this.$refs[this.name] ... do fancy stuff on route change here
    },
  },
  mounted () {
    console.log(this.$refs[`${this.name}-parent`])
  }
}
</script>

现在我想根据route 的变化来改变open 的状态。 Ergo:如果用户点击一个链接,弹出框应该关闭。

PopoverPopoverButtonPopoverPanel 由 headlessui 提供,仅在组件内提供 open 插槽。我的想法是访问open 属性并手动更改它。

【问题讨论】:

  • mounted 方法是在包含 Popover 的父组件上,对吧?作用域变量实际上是在父组件中定义的,它不是已经有 open 值了吗?
  • 我编辑了我最初的问题: 组件来自 headlessui,我正在尝试从中创建一个可重用的组件。

标签: vue.js vuejs3


【解决方案1】:

我的想法是访问open 属性

访问open 属性很容易,您的模板中已经有了它。如果您想保留它(例如,保留对 open 的引用以便稍后使用它),您可以将您的插槽内容转换为组件并作为道具接收 open。

并手动更改。

但是,这是被禁止的。当您尝试改变 open 时,您会收到一条警告,说它是只读的。一般来说,属性总是只读的,这是由 vue 强制执行的。作用域槽只是与 lambda 函数非常相似的匿名组件,而 open 变量只是槽的属性之一。

理想情况下,您正在使用的库不仅应向插槽公开open 状态,还应公开另外两个方法(open()close())。不幸的是,并非所有的库都经过深思熟虑。

当你的路线改变时,你可以尝试将焦点移到其他一些元素上,看看是否可以关闭弹出框。如果没有,您可以手动实现弹出框的 vue 包装器。这是我会做的事情,对于简单的用例(即弹出一些面板),使用弹出框实现是微不足道的。

【讨论】:

    猜你喜欢
    • 2021-02-27
    • 2021-04-22
    • 2019-08-06
    • 1970-01-01
    • 2020-10-24
    • 2016-04-25
    • 2022-11-01
    • 1970-01-01
    • 2021-04-10
    相关资源
    最近更新 更多