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>
结果:
结果却不尽人意。。。。
加上插槽选择器: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>
结果:
成功啦!!!
全局选择器(: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>
效果图:
可以看到,我只在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>
效果:
CSS样式绑定对象中的属性
可以看到下面的代码中,CSS的样式直接绑定了对象的属性报错了:
正确的做法,加上一个引号:
<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>
效果:
动态切换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 module 的用法
使用cssmodule的话,就需要将scoped给去掉
<style module>
</style>
具体的用法:
-
定义css样式:
<style module> .div { color: pink; } </style> -
在标签上使用:
<div :class="$style.div">text</div>绑定
class属性,使用$style.类名,$style是module的默认名称,如果给module起了名字,那么就得像下面这样用:css:
<style module="dt"> .div { color: pink; } </style>html:
<div :class="dt.div">text</div>绑定多个类:
绑定多个类的话,可以使用数组 css:
<style module> .div { color: red; } .header { font-size: 68px; } </style>html:
<div :class="[$style.div, $style.header]">text</div>