vue 3 第二十六章:样式(scoped、深度选择器、全局选择器、css modules、自定义注入名称、css中v-bind)

文章介绍了在Vue中如何使用scoped特性来限制组件样式的作用域,以及如何通过深度选择器(:deep)、插槽选择器(:slotted)、全局选择器(:global)来扩展样式控制。同时,提到了CSSModules和自定义注入名称来实现更细粒度的样式隔离,并展示了如何在CSS中使用v-bind绑定动态变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 介绍

在 Vue 中,我们可以使用 scoped 特性来给组件的样式添加作用域。通过为组件的 <style> 标签添加 scoped 特性,我们可以确保组件的样式仅应用于该组件的模板中,而不会影响其他组件或全局样式。

2. 基本使用

<template>
  <div class="example">
    <h1>Scoped Styles</h1>
  </div>
</template>

<style scoped>
.example {
  color: red;
}
</style>

在上面的例子中,.example 类的样式只会应用于该组件的模板中,而不会影响其他组件或全局样式。

3. scoped原理

  • 给当前元素及子元素都加上data-v-开头的一串随机 hash 值
    在这里插入图片描述
  • css中通过属性选择器选择这个 hash ,这样就确保了唯一性,避免样式污染
    在这里插入图片描述

4. 深度选择器

  • :bind()

我们用vue开发过程中,总是会用到各种组件库,如:ElmentUI/andt design等等,或者我们自己封装的组件,这些组件库提供的组件样式有时并不满足实际需求,这时候就需要使用深度选择器来修改样式。

下面是一个使用深度选择器的例子:
在这里插入图片描述
此时我们在自己的组件中修改 btn 组件的样式,发现并没有效果
在这里插入图片描述
vue提供了:deep()选择器:

<template>
  <div class="example">
    <btn>Scoped Styles</btn>
  </div>
</template>

<style lang="scss" scoped>
.example {
  :deep(.content) {
    color: red;
  }
}
</style>

在这里插入图片描述
当然了在 sass 中我们还可以使用 ::v-deep (在 less 中使用 /deep/ )来修改样式,也是可以实现的。

5. 插槽选择器

  • :slotted()

默认情况下,作用域样式不会影响到<slot/>渲染出来的内容,因为它们被认为是父组件所持有并传递进来的。使用 :slotted伪类以明确地将插槽内容作为选择器的目标:
在这里插入图片描述
渲染效果如下:
在这里插入图片描述

  • 代码如下:
<template>
  <div class="example">
    <button class="content">
      <slot></slot>
      <slot name="title"></slot>
    </button>
  </div>
</template>

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

<style lang="scss" scoped>
/* 直接修改插槽元素的样式,不生效 */
.example {
   .unname-class {
     color: red;
   }
}

/* 使用:slotted()插槽选择器可以修改插槽内元素的样式 */
.example {
  :slotted(.unname-class) {
    color: red;
  }
  :slotted(.name-class) {
    color: orange;
  }
}
</style>

</style>

6. 全局选择器

  • :global()

在实际开发中我们可能会封装比较多的公共样式文件,但在某个组件中我们想去修改某个公共样式,那这个时候比起另外创建一个<style></style>标签来说,更推荐使用:global()选择器:

<style scoped lang="scss">
:global(.global-color) {
  color: red;
}
</style>

在这里插入图片描述
修改前文字颜色为橙色,修改后文字颜色已经发生改变,效果如下:
在这里插入图片描述

7. 混合使用局部与全局样式

  • 可以在同一个.vue文件里使用 scoped 和非scoped
<style>
// ......
</style>

<style scoped lang="scss">
// ......
</style>

8. CSS Modules

  • 除了scoped之外,我们也同样可以使用module实现样式的私有化
  • scoped是通过生成一串data-v开头,随机的自定义属性,通过属性选择器实现的样式私有
  • module是通过生成一个随机的类名,实现样式私有
  • module将生成的 CSS class 作为$style对象暴露给组件

先看效果:
在这里插入图片描述
示例代码:

<template>
  <div class="example">
    <header :class="$style.header">头部</header>
    <main :class="$style.main">内容</main>
    <footer :class="$style.footer">底部</footer>
  </div>
</template>

<style module lang="scss">
.header,
.main,
.footer {
  height: 100px;
  width: 500px;
  border: 1px solid #000;
  font-size: 18px;
  font-weight: bold;
}
.header {
  margin-bottom: 20px;
  color: palevioletred;
}
.main {
  margin-bottom: 20px;
  color: green;
}
.footer {
  color: blue;
}
</style>

9. 自定义注入名称

  • module除了以上用法之外,还提供自定义名称的功能
  • 效果和$style是一样的
<template>
  <div class="example">
    <header :class="myStyle.header">头部</header>
    <main :class="myStyle.main">内容</main>
    <footer :class="myStyle.footer">底部</footer>
  </div>
</template>

<style module="myStyle" lang="scss">
.header,
.main,
.footer {
  height: 100px;
  width: 500px;
  border: 1px solid #000;
  font-size: 18px;
  font-weight: bold;
}
.header {
  margin-bottom: 20px;
  color: palevioletred;
}
.main {
  margin-bottom: 20px;
  color: green;
}
.footer {
  color: blue;
}
</style>

10. CSS 中的 v-bind()

  • 单文件组件的<style>标签支持使用v-bind CSS 函数将 CSS 的值链接到动态的组件状态
  • 简单来说就是可以在css中通过v-bind()函数动态绑定js中的变量
  • 实际的值会被编译成哈希化的 CSS 自定义属性,并且在源值变更的时候响应式地更新

渲染效果:
在这里插入图片描述

代码示例:

<template>
  <div class="example">
    <div class="example-text">css中v-bind绑定变量</div>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
const color = ref("red");
</script>

<style scoped lang="scss">
.example-text {
  color: v-bind(color);
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

剑九_六千里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值