如何防止Vue.js自动合并CSS类?
How to prevent Vue.js from automatically merging CSS classes?
我最近开始使用 Vue.js,我真的很喜欢它,但我遇到了一些我不知道该怎么做的事情。我已经搜索并阅读了文档,但没有找到解决方案。
当您将 CSS class 添加到您的任何组件时 Vue.js 将自动添加或合并 CSS classes 与根元素在您的子组件中。
这是一个不错的功能,但我需要为特定组件停用此功能,因为我希望将 classes 添加到根元素的子元素中。
我做这个fiddle是为了说明http://jsfiddle.net/rasmuswoelk/9m2j0a9s/3
<div id="demo">
<child-component class="some-class"></child-component>
</div>
(正在自动添加 "some-class" 并添加绿色背景色)
如何防止 Vue.js 自动合并 CSS classes?
我认为您会希望将整个内容包装在另一个 <div></div>
中,因为 Vue 会合并顶部元素上的 类。如果您只想要 <h1>
的样式,请尝试这样做:
template: `<div><h1 class="child">Hello</h1></div>`
这应该会给你预期的行为,如果它不起作用请告诉我。
已更新
我不同意将应用于组件的 class 由该组件移动到内部元素是直观的,所以我的建议仍然是:将其作为道具传递。
但是,有一些注意事项,您可以做您想做的事。该组件将有一个属于外部元素的 classes 列表。在 mounted
中,它查看 $el.classList
并找到不在已知外部元素 class 中的 classes。那些被应用到内部元素并从外部元素中移除。警告:如果外部元素 classes 之一应用于组件,它将不会移动到内部元素。并且不会捕获对已应用 class 的任何更新。
Vue.component('child-component', {
template: `<div :class="outerClasses"><h1 :class="childClasses">Hello</h1></div>`,
data() {
return {
outerClasses: ['child'],
childClasses: []
};
},
mounted() {
this.childClasses = Array.from(this.$el.classList).filter((c) => !this.outerClasses.includes(c));
for (const c of this.childClasses) this.$el.classList.remove(c);
}
});
var demo = new Vue({
el: '#demo'
});
.child {
border: 1px solid red;
padding: 20px;
text-align: center;
}
.some-class {
background-color: green;
}
<script src="//vuejs.org/js/vue.min.js"></script>
<div id="demo">
<child-component class="some-class a b c"></child-component>
</div>
您不能将模板中的包装器 div 抽象出来,并且尝试使组件以 div 不存在的方式工作只会导致混淆和不正确的样式。
假设您设法让您的组件将外部 class
应用于其模板中的嵌套元素(这正是您想要的)。现在,当人们使用该组件并对其应用 class 时,样式将应用于输入元素,就好像整个组件仅由输入元素组成,没有这样的包装器 div (这就是你想要的行为)。
这样做的问题是某些样式会起作用(如 background-color
,或任何外观样式),但其他影响布局的样式将不起作用(如 position: absolute
,因为它将导致输入元素相对于包装器 div 定位,这不是预期的)。
使用该组件的人应该了解模板的结构,以便他们可以正确设置样式,因为实际上 是 一个包装器 div 他们在那里需要考虑。
我应该提一下,您可以通过使用 Web 组件或影子 DOM 抽象出包装器 div,但这超出了 Vue 的上下文。
更简单的方法(imo)是将传入的class属性和动态class属性绑定到数据,并在[=13=期间将它们从vnode(虚拟节点)中删除]勾.
Vue.component('child-component', {
template: `
<div class="child">
<h1 :class="staticClass">Hello</h1>
</div>
`,
data() {
return {
staticClass: [],
}
},
created() {
// dynamic :class prop
this.staticClass.push(this.$vnode.data.class)
// delete if not applying on this.$el
delete this.$vnode.data.class
// static class attr
this.staticClass.push(this.$vnode.data.staticClass)
// delete if not applying on this.$el
delete this.$vnode.data.staticClass
},
});
var demo = new Vue({
el: '#demo',
data: {
dynamicClass: 'dynamic-class'
},
});
.child {
border: 1px solid red;
padding: 20px;
text-align: center;
}
.some-class {
background-color: green;
}
.dynamic-class {
border: 1px solid yellow;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<div id="demo">
<child-component :class="dynamicClass" class="some-class"></child-component>
</div>
我最近开始使用 Vue.js,我真的很喜欢它,但我遇到了一些我不知道该怎么做的事情。我已经搜索并阅读了文档,但没有找到解决方案。
当您将 CSS class 添加到您的任何组件时 Vue.js 将自动添加或合并 CSS classes 与根元素在您的子组件中。
这是一个不错的功能,但我需要为特定组件停用此功能,因为我希望将 classes 添加到根元素的子元素中。
我做这个fiddle是为了说明http://jsfiddle.net/rasmuswoelk/9m2j0a9s/3
<div id="demo">
<child-component class="some-class"></child-component>
</div>
(正在自动添加 "some-class" 并添加绿色背景色)
如何防止 Vue.js 自动合并 CSS classes?
我认为您会希望将整个内容包装在另一个 <div></div>
中,因为 Vue 会合并顶部元素上的 类。如果您只想要 <h1>
的样式,请尝试这样做:
template: `<div><h1 class="child">Hello</h1></div>`
这应该会给你预期的行为,如果它不起作用请告诉我。
已更新 我不同意将应用于组件的 class 由该组件移动到内部元素是直观的,所以我的建议仍然是:将其作为道具传递。
但是,有一些注意事项,您可以做您想做的事。该组件将有一个属于外部元素的 classes 列表。在 mounted
中,它查看 $el.classList
并找到不在已知外部元素 class 中的 classes。那些被应用到内部元素并从外部元素中移除。警告:如果外部元素 classes 之一应用于组件,它将不会移动到内部元素。并且不会捕获对已应用 class 的任何更新。
Vue.component('child-component', {
template: `<div :class="outerClasses"><h1 :class="childClasses">Hello</h1></div>`,
data() {
return {
outerClasses: ['child'],
childClasses: []
};
},
mounted() {
this.childClasses = Array.from(this.$el.classList).filter((c) => !this.outerClasses.includes(c));
for (const c of this.childClasses) this.$el.classList.remove(c);
}
});
var demo = new Vue({
el: '#demo'
});
.child {
border: 1px solid red;
padding: 20px;
text-align: center;
}
.some-class {
background-color: green;
}
<script src="//vuejs.org/js/vue.min.js"></script>
<div id="demo">
<child-component class="some-class a b c"></child-component>
</div>
您不能将模板中的包装器 div 抽象出来,并且尝试使组件以 div 不存在的方式工作只会导致混淆和不正确的样式。
假设您设法让您的组件将外部 class
应用于其模板中的嵌套元素(这正是您想要的)。现在,当人们使用该组件并对其应用 class 时,样式将应用于输入元素,就好像整个组件仅由输入元素组成,没有这样的包装器 div (这就是你想要的行为)。
这样做的问题是某些样式会起作用(如 background-color
,或任何外观样式),但其他影响布局的样式将不起作用(如 position: absolute
,因为它将导致输入元素相对于包装器 div 定位,这不是预期的)。
使用该组件的人应该了解模板的结构,以便他们可以正确设置样式,因为实际上 是 一个包装器 div 他们在那里需要考虑。
我应该提一下,您可以通过使用 Web 组件或影子 DOM 抽象出包装器 div,但这超出了 Vue 的上下文。
更简单的方法(imo)是将传入的class属性和动态class属性绑定到数据,并在[=13=期间将它们从vnode(虚拟节点)中删除]勾.
Vue.component('child-component', {
template: `
<div class="child">
<h1 :class="staticClass">Hello</h1>
</div>
`,
data() {
return {
staticClass: [],
}
},
created() {
// dynamic :class prop
this.staticClass.push(this.$vnode.data.class)
// delete if not applying on this.$el
delete this.$vnode.data.class
// static class attr
this.staticClass.push(this.$vnode.data.staticClass)
// delete if not applying on this.$el
delete this.$vnode.data.staticClass
},
});
var demo = new Vue({
el: '#demo',
data: {
dynamicClass: 'dynamic-class'
},
});
.child {
border: 1px solid red;
padding: 20px;
text-align: center;
}
.some-class {
background-color: green;
}
.dynamic-class {
border: 1px solid yellow;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.min.js"></script>
<div id="demo">
<child-component :class="dynamicClass" class="some-class"></child-component>
</div>