上抛出一个错误,但如果我删除......" /> 上抛出一个错误,但如果我删除......"> 上抛出一个错误,但如果我删除......" />
查看 Vuetify example code for v-toolbar
,v-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 }">
上抛出一个错误,但如果我删除它,页面就会呈现。
你可能指的是这个例子:
<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>
以下行声明了一个名为 activator
的 scoped 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
方法。
我认为最初的问题是关于理解“on”对象。最好在这里解释:
https://github.com/vuetifyjs/vuetify/issues/6866
本质上,“on”是从激活器传入的道具。 v-on="on" 所做的是将其 on prop 绑定到组件。 “on”本身就是从激活器传递的所有事件侦听器。
要提出可读性提示,可以使用以下语法:
<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-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 文档所说:
由于 Internet Explorer 对 <template>
标记的支持有限,您必须将完全编译的 dom 元素发送到浏览器。这可以通过提前构建您的 Vue 代码或通过创建帮助组件来替换 dom 元素来完成。例如,如果直接发送到 IE,这将失败:
<!-- Vue Component -->
<template v-slot:items="props">
<td>{{ props.item.name }}</td>
</template>