Vue js Vuetify自定义组件未根据显示断点渲染
Vue js Vuetify custom component not rendered based on the display breakpoint
我有一个自定义组件,它基本上是一个具有特定样式的 v-btn 组件。当我在具有基于显示断点的条件的 v-menu 激活器中使用它时,自定义组件不会显示在屏幕上。但是如果我使用常规的 v-btn,按钮会根据显示断点正确显示。我在这里做错了什么?
https://codepen.io/jgunawan-dc/pen/XWzJqRy?editors=1010
<div id="app">
<v-app id="inspire">
<div class="text-center">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<global-custom-button
v-if="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<v-btn v-else
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Dropdown
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-app>
</div>
Vue.component('global-custom-button', {
template: '<v-btn outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>'
});
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me 2' },
],
}),
})
上述情况产生了两个错误:
错误信息 1:
[Vue warn]: Error in nextTick: "NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
错误信息 2:
DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
当 Vue 尝试在另一个元素之前插入一个元素,但该元素不再存在于 DOM 中时,就会出现这种情况。
在您的情况下,将 $vuetify.breakpoint.mdAndDown
从 true 更改为 false 或 vice-versa 会清理 global-custom-button
组件或下拉列表 v-btn
.
一种可能的解决方法是使用 v-show
而不是 v-if
。
注意事项:
Note that v-show doesn’t support the element, nor does it work with v-else.
所以这个建议可行(您可以更改以满足您的需要):
<global-custom-button
v-show="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<v-btn v-show="!$vuetify.breakpoint.mdAndDown"
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Dropdown
</v-btn>
编辑:
This works 没有 v-if
或 v-show
如@Rotiken 所说,要快速修复,请使用 v-show
。
作为另一种解决方案,您还可以注册两个全局组件并 show/hide 使用额外的 condition
prop:
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<global-custom-button
:condition="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<global-custom-button-2
:condition="!$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Dropdown
</global-custom-button-2>
</template>
...
</v-menu>
...
Vue.component('global-custom-button', {
template: '<v-btn v-if="condition" outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>',
props: ['condition']
});
Vue.component('global-custom-button-2', {
template: '<v-btn v-if="condition" color="primary" dark @click="$emit(\'click\', $event)"><slot></slot></v-btn>',
props: ['condition']
});
...
根据 this CodePen,这也有效。
为什么 会发生这种情况以及为什么 v-show
使用相同的模板可以正常工作:我无法给出确切的答案,但有一些假设。
Vue.js docs 表示 v-if
从 DOM 中删除对象,而 v-show
在 CSS 中更改其显示状态,但在 [=47] 中保留它=].
由于您在 vuetify v-menu
组件中使用 v-if
,也许该组件有一些更新 v-slot:activator
内容的方法可能会发生冲突(并且不会同时执行) ) 使用 v-if
和 vuetify 显示断点进行条件渲染。
如果您熟悉 TypeScript,可以查看 v-menu sources or into activatable mixin sources。也许在这里你会找到这种行为的真正原因。
如果您只想避免此类问题,请在此类情况下使用v-show
。
我有一个自定义组件,它基本上是一个具有特定样式的 v-btn 组件。当我在具有基于显示断点的条件的 v-menu 激活器中使用它时,自定义组件不会显示在屏幕上。但是如果我使用常规的 v-btn,按钮会根据显示断点正确显示。我在这里做错了什么?
https://codepen.io/jgunawan-dc/pen/XWzJqRy?editors=1010
<div id="app">
<v-app id="inspire">
<div class="text-center">
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<global-custom-button
v-if="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<v-btn v-else
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Dropdown
</v-btn>
</template>
<v-list>
<v-list-item
v-for="(item, index) in items"
:key="index"
>
<v-list-item-title>{{ item.title }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</div>
</v-app>
</div>
Vue.component('global-custom-button', {
template: '<v-btn outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>'
});
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
items: [
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me' },
{ title: 'Click Me 2' },
],
}),
})
上述情况产生了两个错误:
错误信息 1:
[Vue warn]: Error in nextTick: "NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
错误信息 2:
DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
当 Vue 尝试在另一个元素之前插入一个元素,但该元素不再存在于 DOM 中时,就会出现这种情况。
在您的情况下,将 $vuetify.breakpoint.mdAndDown
从 true 更改为 false 或 vice-versa 会清理 global-custom-button
组件或下拉列表 v-btn
.
一种可能的解决方法是使用 v-show
而不是 v-if
。
注意事项:
Note that v-show doesn’t support the element, nor does it work with v-else.
所以这个建议可行(您可以更改以满足您的需要):
<global-custom-button
v-show="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<v-btn v-show="!$vuetify.breakpoint.mdAndDown"
color="primary"
dark
v-bind="attrs"
v-on="on"
>
Dropdown
</v-btn>
编辑:
This works 没有 v-if
或 v-show
如@Rotiken 所说,要快速修复,请使用 v-show
。
作为另一种解决方案,您还可以注册两个全局组件并 show/hide 使用额外的 condition
prop:
<v-menu offset-y>
<template v-slot:activator="{ on, attrs }">
<global-custom-button
:condition="$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Show on medium and lower
</global-custom-button>
<global-custom-button-2
:condition="!$vuetify.breakpoint.mdAndDown"
v-bind="attrs"
v-on="on"
>
Dropdown
</global-custom-button-2>
</template>
...
</v-menu>
...
Vue.component('global-custom-button', {
template: '<v-btn v-if="condition" outlined color="info" @click="$emit(\'click\', $event)"><slot></slot></v-btn>',
props: ['condition']
});
Vue.component('global-custom-button-2', {
template: '<v-btn v-if="condition" color="primary" dark @click="$emit(\'click\', $event)"><slot></slot></v-btn>',
props: ['condition']
});
...
根据 this CodePen,这也有效。
为什么 会发生这种情况以及为什么 v-show
使用相同的模板可以正常工作:我无法给出确切的答案,但有一些假设。
Vue.js docs 表示 v-if
从 DOM 中删除对象,而 v-show
在 CSS 中更改其显示状态,但在 [=47] 中保留它=].
由于您在 vuetify v-menu
组件中使用 v-if
,也许该组件有一些更新 v-slot:activator
内容的方法可能会发生冲突(并且不会同时执行) ) 使用 v-if
和 vuetify 显示断点进行条件渲染。
如果您熟悉 TypeScript,可以查看 v-menu sources or into activatable mixin sources。也许在这里你会找到这种行为的真正原因。
如果您只想避免此类问题,请在此类情况下使用v-show
。