Vue3$View-CSS

88 阅读1分钟

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 基本使用

<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>

Links

VueCssFeatures