笔记-第二十三章Vue3的CSS新特性(自用)

530 阅读1分钟

Vue3的CSS新特性

插槽选择器(:slotted(选择器))

应用场景:假如我们定义了一个组件,在这个组件里面定义了一个默认插槽,然后在这个组件内去修改填充到插槽位置的内容的样式。

我们以为像下面这样就可以修改填充到插槽位置的内容的样式了? 子组件:

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script setup lang='ts'>
</script>

<style lang='scss' scoped>
.context {
  color: pink;
}
</style>

父组件:

<template>
  <div>
    <Slotted>
      <div class="context">
        hello world!
      </div>
    </Slotted>
  </div>
</template>

<script setup lang='ts'>
import Slotted from './components/Slotted.vue';
</script>

<style lang='scss' scoped></style>

结果:

image.png 结果却不尽人意。。。。

加上插槽选择器:slotted()试试: 子组件:

<template>
  <div>
    <slot></slot>
  </div>
</template>

<script setup lang='ts'>
</script>

<style lang='scss' scoped>
:slotted(.context) {
  color: pink;
}
</style>

父组件:

<template>
  <div>
    <Slotted>
      <div class="context">
        hello world!
      </div>
    </Slotted>
  </div>
</template>

<script setup lang='ts'>
import Slotted from './components/Slotted.vue';
</script>

<style lang='scss' scoped></style>

结果:

image.png

成功啦!!!

全局选择器(:global(选择器))

一般情况下,在组件中使用<style>不加scoped属性的时候,那么这里面的样式就是全局生效的。

现在又新出了一个:global()选择器,你在组件内加了scoped属性的<style>中也能让样式全局生效!

父组件

<template>
  <div>
    <h1>App</h1>
    <Slotted />
    <HelloWorld />
  </div>
</template>

<script setup lang='ts'>
import Slotted from './components/Slotted.vue';
import HelloWorld from '@/components/HelloWorld.vue'
</script>

<style lang='scss' scoped></style>

HelloWorld.vue:

<template>
  <div>
    <h1>HelloWorld</h1>
  </div>
</template>

<script setup lang='ts'>
</script>

<style lang='scss' scoped>
:global(h1) {
  color: red;
}
</style>

Slotted.vue

<template>
  <div>
    <h1>Slotted</h1>
  </div>
</template>

<script setup lang='ts'>
</script>

<style lang='scss' scoped></style>

效果图:

image.png

可以看到,我只在HelloWorld.vue设置了h1的字体样式为红色,但是父组件以及兄弟组件内h1标签的字体样式也发生了变化。这就是:global()全局选择器起的作用。

动态CSS(v-bind())

在Vue3中,style中的样式也可以动态的绑定组件内声明的变量,以便于完成动态的改变标签元素的样式。

<template>
  <div>
    <h1>App</h1>
  </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue'

const fontColor = ref('pink')
</script>

<style lang='scss' scoped>
h1 {
  color: v-bind(fontColor);
}
</style>

效果:

image.png

CSS样式绑定对象中的属性

可以看到下面的代码中,CSS的样式直接绑定了对象的属性报错了:

image.png

正确的做法,加上一个引号

<template>
  <div>
    <h1>App</h1>
  </div>
</template>

<script setup lang='ts'>
import { reactive } from 'vue'

const fontColor = reactive({
  color: 'blue'
})
</script>

<style lang='scss' scoped>
h1 {
  color: v-bind('fontColor.color');
}
</style>

效果:

image.png

动态切换css样式

<template>
  <div>
    <h1>App</h1>
    <button @click="changeStyle">改变标题的样式</button>
  </div>
</template>

<script setup lang='ts'>
import { ref } from 'vue'

// 颜色
const fontColor = ref('red')

// 改变颜色
const changeStyle = () => {
  fontColor.value = 'pink'
}
</script>

<style lang='scss' scoped>
h1 {
  color: v-bind(fontColor);
}
</style>

效果:

动态css.gif

CSS module 的用法

使用cssmodule的话,就需要将scoped给去掉

<style module>

</style>

具体的用法:

  1. 定义css样式:

    <style module>
    .div {
        color: pink;
    }
    </style>
    
  2. 在标签上使用:

    <div :class="$style.div">text</div>
    

    image.png 绑定class属性,使用$style.类名$stylemodule的默认名称,如果给module起了名字,那么就得像下面这样用:

    css:

    <style module="dt">
    .div {
        color: pink;
    }
    </style>
    

    html:

    <div :class="dt.div">text</div>
    

    image.png 绑定多个类:

    绑定多个类的话,可以使用数组 css:

    <style module>
    .div {
        color: red;
    }
    .header {
        font-size: 68px;
    }
    </style>
    

    html:

    <div :class="[$style.div, $style.header]">text</div>
    

    image.png