上抛出一个错误,但如果我删除......" /> 上抛出一个错误,但如果我删除......"> 上抛出一个错误,但如果我删除......" />
ChatGPT解决这个技术问题 Extra ChatGPT

v-slot 的含义:activator="{ on }"

查看 Vuetify example code for v-toolbarv-slot:activator="{ on }" 的用途是什么?例如:

<template v-slot:activator="{ on }">
  <v-toolbar-title v-on="on">
    <span>All</span>
    <v-icon dark>arrow_drop_down</v-icon>
  </v-toolbar-title>
</template>

<script>
  export default {
    data: () => ({
      items: [
        'All', 'Family', 'Friends', 'Coworkers'
      ]
    })
  }
</script>

据我所见,on 在任何地方都不是定义的变量,所以我看不出它是如何工作的。当我在我的项目中尝试它时,Internet Explorer 在 <template v-slot:activator="{ on }"> 上抛出一个错误,但如果我删除它,页面就会呈现。


t
tony19

你可能指的是这个例子:

<v-toolbar color="grey darken-1" dark>
  <v-menu :nudge-width="100">
    <template v-slot:activator="{ on }">
      <v-toolbar-title v-on="on">
        <span>All</span>
        <v-icon dark>arrow_drop_down</v-icon>
      </v-toolbar-title>
    </template>

    ...
  </v-menu>
</v-toolbar>

以下行声明了一个名为 activatorscoped slot,并为它提供了一个范围对象(来自 VMenu),其中包含一个名为 on 的属性:

<template v-slot:activator="{ on }">

这在范围对象上使用 destructuring syntax,即 IE does not support

对于 IE,您必须从范围对象本身取消引用 on

<template v-slot:activator="scope">
  <v-toolbar-title v-on="scope.on">

理想的 IMO 解决方案是使用 Vue CLI 生成的项目,其中包括 Babel 预设 (@vue/babel-preset-app),以自动包含 target 浏览器所需的转换/polyfill。在这种情况下,babel-plugin-transform-es2015-destructuring 将在构建期间自动应用。

激活器插槽的详细信息

VMenu 允许用户指定一个名为 activator 的带槽模板,其中包含在某些事件(例如 click)时激活/打开菜单的组件。 VMenu 为这些事件 via an object 提供侦听器,传递到 activator 槽:

<v-menu>
  <template v-slot:activator="scopeDataFromVMenu">
    <!-- slot content goes here -->
  </template>
</v-menu>

槽内容可以像这样访问 VMenu 的事件侦听器:

<v-menu>
  <template v-slot:activator="scopeDataFromVMenu">
    <button v-on="scopeDataFromVMenu.on">Click</button>
  </template>
</v-menu>

为了提高可读性,范围内的数据也可以是模板中的 destructured

<!-- equivalent to above -->
<v-menu>
  <template v-slot:activator="{ on }">
    <button v-on="on">Click</button>
  </template>
</v-menu>

范围对象中的侦听器使用 v-on 的对象语法传递给 <button>,该语法将一个或多个事件/侦听器对绑定到元素。对于 on 的这个值:

{
  click: activatorClickHandler // activatorClickHandler is an internal VMenu mixin
}

...按钮的点击处理程序绑定到 VMenu 方法。


P
PropertyWebBuilder

我认为最初的问题是关于理解“on”对象。最好在这里解释:

https://github.com/vuetifyjs/vuetify/issues/6866

本质上,“on”是从激活器传入的道具。 v-on="on" 所做的是将其 on prop 绑定到组件。 “on”本身就是从激活器传递的所有事件侦听器。


t
tony19

要提出可读性提示,可以使用以下语法:

<v-menu>
    <template v-slot:activator="{ on: activationEvents }">
        <v-btn v-on="activationEvents">
            I like turtles 🐢
        </v-btn>
    </template>
</v-menu>

在我的大脑中,这比 v-on="on" 具有更流畅的可读性,对我来说,这就像观察一个仅包含以下内容的对话:

第一个人:“嘿”

第 2 个人:“是的”

理解? ;)

顺便说一句,activationEvents 可以是任何 alias,例如“slotEvents”、“listeners”、“anyOldEvent”,或者对读者来说更有意义的对神秘 on 的重命名。


这与仅在元素上使用 v-if="show" 来显示/隐藏和在按钮上使用 @click="show=!show" 来控制它有什么不同?
我相信插槽中的事件可能不仅仅是单击,例如悬停或聚焦等。这对于集成到具有激活相关内部行为的特定 Vuetify 组件中尤为重要。
好吧,没有什么能阻止您使用@@hover 或@@focus :) 我会理解激活器可能有用的一些极端情况,但99% 的时间,一个简单的显示变量似乎就可以了。
H
HaoQiRen

运行下面的代码,你就会知道 v-menu 中的 'attrs' 和 'on' 是什么。

<v-menu>
    <template v-slot:activator="{ on, attrs }">
        <div v-bind="attrs" v-on="on">
            v-menu slot activator:
            <br />
            attrs == {{ JSON.stringify(attrs) }}
            <br />
            on == {{ '{' + Object.keys(on).map(k => k + " : " + on[k]).join(',') + '}' }}
        </div>
    </template>
</v-menu>

结果:

v-menu slot activator:
attrs == {"role":"button","aria-haspopup":true,"aria-expanded":"false"}
on == {
click:function (e) {if (_this.openOnClick) {onClick && onClick(e);}_this.absoluteX = e.clientX;_this.absoluteY = e.clientY;},
keydown:function () { [native code] }
}

解释:

<div v-bind="attrs" v-on="on"> 等于

<div 
    v-bind="{role:'button',aria-haspopup:true,aria-expanded:'false'}" 
    v-on="{click:function (e) {/*implement by v-menu*/},keydown:function () {/*implement by v-menu*/}}"
>

从 vue 2.4.0+ 开始,v-on 还支持绑定到不带参数的事件/侦听器对的对象。请注意,使用对象语法时,它不支持任何修饰符。例子:

<!-- v-on's object syntax (vue 2.4.0+) -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>

关于 Internet Explorer 中的 <template> 标记会引发错误:

正如 vuetify 文档所说:

Template caveat

由于 Internet Explorer 对 <template> 标记的支持有限,您必须将完全编译的 dom 元素发送到浏览器。这可以通过提前构建您的 Vue 代码或通过创建帮助组件来替换 dom 元素来完成。例如,如果直接发送到 IE,这将失败:

<!-- Vue Component -->
<template v-slot:items="props">
  <td>{‌{ props.item.name }‌}</td>
</template>

嗨@HaoQiRen,你的回答似乎没有提供关于“on”含义的信息,你能提供更多关于你的例子的信息吗?你读过this吗?尝试修改您的答案并添加详细信息,以使其对未来的观点有价值:)

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅