【问题标题】:Using VMenu from vuetify with render function (scoped slot)使用 vuetify 中的 VMenu 和渲染功能(作用域插槽)
【发布时间】:2021-07-28 00:42:17
【问题描述】:

我正在尝试使用 Vuetify 的 VMenu 组件,我希望当用户单击按钮时,VMenu 会出现。至于docs,它说我们应该添加一个作用域插槽。使用普通模板它可以工作,但是当我切换到渲染函数方法时,它永远不会渲染按钮。

我一直在关注 Vue 的 docs 并最终得到:

h(VMenu, { props: { value: isMenuOpen.value } }, [
            h(
              "template",
              {
                scopedSlots: {
                  activator: ({ on, attrs }) => {
                     debugger; // it never reaches this debugger
                     return h(VButton, { on, attrs }, 'click me');
                  }
                },
              },
              []
            ),
            h(VList, [h(VListItem, [h(VListItemTitle, ["Logout"])])]),
          ]),

我也尝试过使用非箭头函数:

scopedSlots: { activator: function({ on, attrs }) {  return h('div', 'click me');  } }

并在非箭头函数和箭头函数中返回一个简单的h('div', 'click me'),但似乎没有任何效果。

如何将作用域插槽activator 传递给VMenu 组件?

【问题讨论】:

    标签: javascript vue.js vuetify.js


    【解决方案1】:

    我无法完全理解我的问题中描述的问题。这是一个不完全回答原始问题的答案,而是为了指导可能会遇到这个问题的未来用户。

    我没有使用作用域插槽,而是将value 属性与attach 属性结合使用。这个解决方案最终没有问题地工作。

    button(
                {
                  attrs: { "data-account-setting": true },
                  props: { plain: true, rounded: true, icon: true },
                  on: { click: onOpenMenuClick },
                },
                [h(VIcon, ["mdi-account-outline"])]
              ),
              h(
                VMenu,
                {
                  props: {
                    value: isMenuOpen.value,
                    // waiting on answer on SO
                    // @see https://stackoverflow.com/questions/67405594/using-vmenu-from-vuetify-with-render-function-scoped-slot
                    attach: "[data-account-setting]",
                    minWidth: "300px",
                    left: true,
                    offsetY: true,
                    closeOnContentClick: false,
                    rounded: true,
                  },
                  on: {
                    input: (value: boolean) => {
                      isMenuOpen.value = value;
                    },
                  },
                },
                [
                  h(VList, { props: { dense: true } }, [
                    h(VListItem, { props: { to: { name: "logout" } } }, [
                      h(VListItemTitle, { attrs: { 'data-cy-logout': true } }, ["Logout"]),
                    ]),
                  ]),
                ]
              ),
    

    【讨论】:

      【解决方案2】:

      作用域插槽通过createElement 的第二个参数的scopedSlots property{ name: props => VNode | Array<VNode> } 的形式传递。在您的情况下,scopedSlots 应该有两个条目:一个用于activator,另一个用于default

      import { VMenu, VList, VListItem, VBtn } from 'vuetify/lib'
      
      export default {
        render(h) {
          return h(VMenu, {
            scopedSlots: {
              activator: props => h(VBtn, props, 'Open'),
              default: () => h(VList, [
                h(VListItem, 'item 1'),
                h(VListItem, 'item 2'),
                h(VListItem, 'item 3'),
              ]),
            },
          })
        }
      }
      

      相当于这个模板:

      <template>
        <v-menu>
          <template v-slot:activator="{ on, attrs }">
            <v-btn v-bind="attrs" v-on="on">Open</v-btn>
          </template>
          <v-list>
            <v-list-item>item 1</v-list-item>
            <v-list-item>item 2</v-list-item>
            <v-list-item>item 3</v-list-item>
          </v-list>
        </v-menu>
      </template>
      

      demo

      【讨论】:

      • 你又一次帮助了我@tony19。非常感谢。
      猜你喜欢
      • 1970-01-01
      • 2021-04-16
      • 2020-12-26
      • 2019-06-03
      • 2020-05-02
      • 2019-10-26
      • 2021-03-19
      • 2022-01-09
      • 2021-07-28
      相关资源
      最近更新 更多