第二十节:Vue3中CSS用法(scoped、选择器、module、v-bind) 和 Less 、Sass的使用
一. CSS相关
(详见官网:https://cn.vuejs.org/api/sfc-css-features.html)
1. scoped作用域
(1). 当 <style> 标签带有 scoped attribute 的时候,它的 CSS 只会影响当前组件的元素
原理:在标签上生成一个 data-xxxx 属性,通过该属性实现唯一性,详见截图
(2). 使用 scoped 后,父组件的样式将不会渗透到子组件中。不过,子组件的根节点会同时被父组件的作用域样式和子组件的作用域样式影响
A. 子组件的根节点会收父组件的影响,非根节点不是影响。
如果子组件child1中最外层div的类名也叫box1,则会被父组件的样式替代
如果子组件child1中非外层div的类名也叫box1,则不受父组件影响
B. 子组件被添加两个 data-xxx属性 <div class="childbox1" data-v-c74b84a5="" data-v-beda6b21="">我是子组件</div>
<template>
<h2>测试作用域scoped</h2>
<br />
<div class="box1">我是box1</div>
<br />
<child1></child1>
</template>
<script setup>
import child1 from "@/components/child1.vue";
</script>
<style scoped>
.box1 {
width: 200px;
height: 200px;
background-color: pink;
color: black;
}
</style>
2. 选择器
(1) :deep() 深度选择器,可以直接选中组件中的内容
(2) :global() 全局选择器,所以声明的样式组件中也会生效
如果想让其中一个样式规则应用到全局,比起另外创建一个 <style>,可以使用 :global 伪类来实现
(3) :slotted() 插槽选择器
默认情况下,作用域样式不会影响到 <slot/> 渲染出来的内容,因为它们被认为是父组件所持有并传递进来的
注:这里是指在子组件中写样式,对父组件插槽渲染出来的内容生效!!!
(4) 全局样式和局部样式混用
<style>
/* 全局样式 */
</style>
<style scoped>
/* 局部样式 */
</style>
查看代码
<template>
<h2>测试选择器</h2>
<br />
<div class="box1">我是box1</div>
<br />
<child1> <div class="box3">我是插槽中的默认内容</div></child1>
</template>
<script setup>
import child1 from "@/components/child1.vue";
</script>
<style scoped>
.box1 {
width: 200px;
height: 200px;
background-color: pink;
color: black;
}
/* 深度选择器 */
/* :deep(.box2) {
font-weight: bold;
font-size: 20px;
color: red;
} */
/* 全局选择器 */
:global(.box2) {
font-weight: bold;
font-size: 20px;
color: red;
}
</style>
<style>
/* 全局样式 */
/* .box2 {
font-weight: bold;
font-size: 20px;
color: red;
} */
</style>
查看代码
<template>
<div class="childbox1">
我是子组件
<div class="box1">我是子组件的内容1</div>
<div class="box2">我是子组件的内容2</div>
<slot> </slot>
</div>
</template>
<script setup></script>
<style scoped>
.childbox1 {
width: 200px;
height: 300px;
background-color: bisque;
color: green;
}
/* 插槽选择器 */
:slotted(.box3) {
font-weight: bold;
font-size: 28px;
color: pink;
}
</style>
3. css module
(1). 一个 <style module> 标签会被编译为 CSS Modules 并且将生成的 CSS class 作为 $style 对象暴露给组件。 (通俗的说:就是template 和 script中可以直接获取 css的类对象)
注:得出的 class 将被哈希化以避免冲突,实现了同样的将 CSS 仅作用于当前组件的效果。
(2). 可以通过 useCssModule API 在 setup() 和 <script setup> 中访问注入的 class。
(3). 另外module还可以自定义名称,比如 <style module="ypf">
A. template中调用则:<div :class="ypf.box1">我是box1</div>
B. script中调用则:let myObj = useCssModule("ypf");
查看代码
<template>
<h2>测试CSS Module用法</h2>
<br />
<div :class="$style.box1">我是box1</div>
<br />
</template>
<script setup>
import { useCssModule } from "vue";
// 默认情况下, 返回 <style module> 的 class
let myObj = useCssModule();
console.log(myObj); //{box1: '_box1_l659s_19'}
</script>
<style module>
.box1 {
width: 200px;
height: 200px;
font-weight: 600;
background-color: pink;
color: white;
}
</style>
4. v-bind
(1). 支持响应式
(2). 对象属性的形式需要加引号;单独的变量引号可加可不加
(3). 实际的值会被编译成哈希化的 CSS 自定义属性,因此 CSS 本身仍然是静态的。自定义属性会通过内联样式的方式应用到组件的根元素上,并且在源值变更的时候响应式地更新。
<script setup>
import { reactive, ref } from "vue";
let myTheme = reactive({
bgColor: "green",
});
let myColor = ref("white");
const test1 = () => {
myTheme.bgColor = "pink";
myColor.value = "yellow";
};
</script>
<style scoped>
.box1 {
width: 200px;
height: 200px;
/* background-color: pink; */
/* color: wheat; */
/* 对象属性的形式需要加引号 */
background-color: v-bind("myTheme.bgColor");
/* 单独的变量引号可加可不加 */
color: v-bind(myColor);
}
</style>
二. Less的使用
在Vue项目中,需要通过npm安装相关包(开发依赖即可)
然后直接使用即可:
<style scoped lang="less">
.box1 {
width: 400px;
height: 400px;
background-color: antiquewhite;
.childBox {
width: 200px;
height: 200px;
background-color: aqua;
}
}
</style>
三. Sass的使用
在Vue项目中,需要通过npm安装相关包(开发依赖即可)
然后直接使用即可:
<style scoped lang="scss">
.box1 {
width: 400px;
height: 400px;
background-color: antiquewhite;
.childBox {
width: 200px;
height: 200px;
background-color: aqua;
}
}
</style>
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。