在vue中怎么写⾏内样式⾼_vue组件中如何写内部样式?
在现代化的 Web 开发中,CSS 还远未完美,这⼀点应该没有什么意外。
现今的项⽬通常都相当复杂,⽽ css 样式天⽣⼜是全局性的,所以到最后总是极容易地就发⽣样式冲突——要么是样式相互覆盖,要么就是隐式地级联到了下⾯那些我们未考虑到的元素。
在减轻 CSS 存在的主要痛点⽅⾯,我们普遍采⽤的解决⽅案是引⼊ BEM (Block Element Modifier) ⽅法学。不过这只能解决我们这个⼤问题的很⼩⼀部分。
我们⾮常幸运,社区已经开发出了⼀些解决⽅案,他们可以帮我们处理这些问题。说不定你已经听说过了 CSS Modules、Styled Components、Glamorous、JSS——这些只是众多流⾏的⼯具中的少数⼏个。如果你对这个话题感兴趣,你可以查看这篇帖⽂——作者Indrek Lasn 对 CSS-in-JS 的思想做了⾮常详尽的讲解。
每个通过 vue-cli 创建的 Vue.js 应⽤都内置了两个很好的解决⽅案:Scoped CSS 和 CSS Modules (模块式 CSS)。两种⽅案各有优缺点,所以下⾯我们就仔细看下哪种⽅案在你的案例中更适⽤。
Scoped 样式
我们只需要在 style 标签上添加⼀个 scoped 属性即可启⽤ scoped 样式:
.button {
color: red;
}
这样就会使得我们的样式只被应⽤到这个组件中的元素上。这是借助 PostCSS 实现的,它会将上⾯的代码转换成下⾯这样:
.button[data-v-f61kqi1] {
color: red;
}
就像你看到的这样,整个过程不需要做什么就可以达到很好的 scoped 样式效果。
现在假设你需要调整⼀个视图中的某个组件的宽度,那么你可以像你平时那样做的⼀样:在这个组件上添加⼀个额外的 class 来设置其样式。
contentcss怎么创建
.pricing-panel {
width: 300px;
margin-bottom: 30px;
}
经转换后:
.base-panel[data-v-d17eko1] {
...
}
.pricing-panel[data-v-b52c41] {
width: 300px;
margin-bottom: 30px;
}
content
这次还是⼀样,不需要做什么你就获得了对布局的彻底控制。
不过请注意:这个特性存在⼀个缺陷,即如果你⼦组件的根元素上有⼀个类已经在这个⽗组件中定义过了,那么这个⽗组件的样式就会泄露到⼦组件中。如果想更好地理解这个问题,可以查看这个 CodeSandbox 例⼦。
还有⼀些情况是我们需要对我们的⼦组件的深层结构设置样式——虽然这种做法并不受推荐且应该避免。为了简便起见,我们假设我们的⽗组件现在要对 BasePanel 的标题设置样式,在 scoped 样式中,这种情况可以使⽤ >>> 连接符(或者 /deep/ )实现。
.pricing-panel >>> .title {
font-size: 24px;
}
经转换后:
.pricing-panel[data-v-b52c41] .title {
font-size: 24px;
}
⾮常简单,是吧?可是别忘记,我们却因此失去了组件的封装效果。这个组件内的所有的 .title 类的样式都会被这些样式所浸染——即便是孙节点。
模块式 CSS
模块式 CSS 的流⾏源于 React 社区,它获得了社区的迅速的采⽤。
Vue.js 更甚之,其强⼤、简便的特性在加上通过 vue-cli 对其开箱即⽤的⽀持,将其发展到另⼀个⾼度。
现在让我们来看下怎么使⽤它:
.button {
color: red
}
这次我们使⽤的不是 scoped 属性,⽽是 module。这等于告诉 vue-template-compiler 和 vue-cli 的 webpack 配置要对这⼀部分采⽤哪些相应的 loader,进⽽⽣成像下⾯这样的 CSS:
.ComponentName__button__2Kxy {
color: red;
}
它的特殊之处以及和 scoped 样式不⼀样的地⽅就在于所有创建的类可以通过这个组件的 $style 对象获取。因此,要将这个类进⾏应⽤,我们需要像下⾯这样进⾏ class 绑定:
.button {
color: red
}
这段代码将⽣成下⾯的 HTML 及相关的样式:
.ComponentName__button__2Kxy {
color: red;
}
它的第⼀点好处就是,当我们在 HMTL 中查看这个元素时我们可以⽴刻知道它所属的是哪个组件;第⼆点好处是,⼀切都变成显式的了,我们拥有了彻底的控制权——不会再有什么奇怪的现象了。和 scoped 样式那种把普通的标签也加上那些 data 属性的做法不⼀样,这些普通标签在转换后还是最初的样⼦。
⽐较 scoped 样式中的第⼆个例⼦,我们来看下我们可以怎么对那个组件设置样式:
content
.pricing-panel {
width: 300px;
margin-bottom: 30px;
}
其转换后:
.BasePanel__d17eko1 {
/* some styles */
}
.ComponentName__pricing-panel__a81Kj {
width: 300px;
margin-bottom: 30px;
}
content
毫⽆意外,跟我们期望的结果⼀样。此外,因为所有的 CSS 类可以通过 $style 对象获取到,所以我
们可以通过 props 将这些类传递到任何我们希望的深度中,这样,在⼦组件中的任意位置使⽤这些类就会变得极其容易:
title="Lorem ipsum"
:titleClass="$style.title"
>
Content
模块式 CSS 与 JS 有着很好的互操作性 (interoperability),这⼀点不只局限于 CSS 类。我们还可以使⽤ :export 关键字将其他的东西导出到 $style 对象上。
例如,想象⼀下你有⼀个图表需要开发 —— 你可以在 CSS 中定义你的⾊彩变量的同时将其导出,以供你的组件使⽤:
{{ $style.primaryColor }}
$primary-color: #B4DC47;
:
export {
primaryColor: $primary-color
}
对于模块式 CSS的概念,我这⾥还只是讲到了它的⽪⽑,它实际要宽泛的多,建议你查看下它完整的规范以了解更多。
总结
其实两种⽅案都⾮常简单、易⽤,在某种程度上解决的是同样的问题。 那么你该选择哪种呢?
scoped 样式的使⽤不需要额外的知识,给⼈舒适的感觉。它所存在的局限,也正是它的使⽤简单的原因。它可以⽤于⽀持⼩型到中型的应⽤。
在更⼤的应⽤或更复杂的场景中,这个时候,对于 CSS 的运⽤,我们就会希望它更加显式,拥有更多的控制权。虽然在模板中⼤量使⽤$style 看起来并不那么“性感”,但却更加安全和灵活,为此我们只需付出微⼩的代价。还有⼀个好处就是我们可以⽤ JS 获取到我们定义的⼀些变量(如⾊彩值、样式断点),这样我们就⽆需⼿动保持其在多个⽂件中同步。
本站⽂章均为深正⽹站建设摘⾃权威资料,书籍,或⽹络原创⽂章,如有版权纠纷或者违规问题,请即刻删除,我们欢迎您分享,引⽤和转载,但谢绝直接搬砖和抄袭!感谢...
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论