Vue3$View-CSS
1. Scoped CSS
1.1 基本情况
<style scoped> 可以使 CSS 应用到当前组件(以及单根元素子组件的 root 元素 )。Vue 是通过 PostCSS 来实现的。(尽量使用 class, 而不是 element)
data-v-xxxxxxxx attribute 加到哪里?
- HTML 中加到每个元素上的;单根子组件的根节点加上了,但是多根子组件的根节点并没加上。
- CSS 中只有叶子结点使用了该 attribute:
<template>
<div class="parent-container">
Parent Content
<div class="parent-item">
Parent Item
</div>
<ChildCssOne></ChildCssOne>
<ChildCssMany></ChildCssMany>
</div>
</template>
<script setup>
import ChildCssOne from './ChildCssOne.vue';
import ChildCssMany from './ChildCssMany.vue';
</script>
<style lang="scss" scoped>
.parent-container {
background-color: red;
.parent-item {
background-color: pink;
}
.child-one {
background-color: blue;
}
.child-many {
background-color: blue;
}
}
</style>
转换成:
<template>
<div data-v-dee03032 class="parent-container">
Parent Content
<div data-v-dee03032 class="parent-item"> Parent Item </div>
<div data-v-3d1b755b data-v-dee03032 class="child-one"> Single </div>
<div data-v-1cf14803 class="child-many"> One </div>
<div data-v-1cf14803 class="child-many"> Two </div>
</div>
</template>
<style>
.parent-container[data-v-dee03032] {
background-color: red;
}
.parent-container .parent-item[data-v-dee03032] {
background-color: pink;
}
.parent-container .child-one[data-v-dee03032] {
background-color: blue;
}
.parent-container .child-many[data-v-dee03032] {
background-color: blue;
}
</style>
1.2 Deep Selector
如果希望父组件中定义的样式能影响子组件,可以使用 deep selector :deep()。(单根组件根元素的样式不需要 deep,因为就像上面提及的,单根组件根元素会有 data-v-xxxxxxx 这样的属性)
:deep() 是把里面的选择器的 data-v-xxxxxx 向左移。
<style scoped>
.a :deep(.b) {
/* ... */
}
</style>
编译成:
.a[data-v-f3f3eg9] .b {
/* ... */
}
DOM content created with `v-html` are not affected by scoped styles, but you can still style them using deep selectors.
1.3 Slotted Selectors
<style scoped>
:slotted(div) {
color: red;
}
</style>
1.4 Global Selectors
<style scoped>
:global(.red) {
color: red;
}
</style>
2. CSS Modules
2.1 基本使用
A <style module> tag is compiled as CSS Modules and exposes the resulting CSS classes to the component as an object under the key of $style:
<template>
<p :class="$style.red">This should be red</p>
</template>
<style module>
.red {
color: red;
}
</style>
需要注意的是,CSS Module 没有嵌套关系:a 里面有b, 生成的对象的属性 a 下面没有 b。
<template>
<div :class="$style.a">
aa
<div :class="$style.b">bb</div>
</div>
</template>
<script setup>
import { useCssModule } from 'vue'
const o = useCssModule()
console.log(o)
/*
{
"a": "_a_eva5k_1",
"b": "_b_eva5k_4"
}
*/
</script>
<style module lang="scss">
.a {
background-color: coral;
.b {
color: green;
}
}
</style>
2.2 Custom Inject Name
<template>
<p :class="classes.red">red</p>
</template>
<style module="classes">
.red {
color: red;
}
</style>
2.3 Usage with Composition API
import { useCssModule } from 'vue'
// default, returns classes for <style module>
useCssModule()
// named, returns classes for <style module="classes">
useCssModule('classes')
3. v-bind() in CSS
props 的属性不加 props. 前缀
<script setup>
import { ref } from 'vue'
const theme = ref({
color: 'red',
})
</script>
<template>
<p>hello</p>
</template>
<style scoped>
p {
color: v-bind('theme.color');
}
</style>