Vue的style scoped

Vue的style scoped

一、vue 中 style scoped 的作用

开发一个项目会有多个 css 样式,全局的、局部的、组件内的…,各个组件之间可能会存在选择器重名的问题,一不小心可能会导致样式污染而使得项目的表现出现问题。

“scoped” 这个属性就是为了使样式私有化,不至于让当前组件的 css 样式对全局造成污染。

<template>
  <div class="login-container">
    <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" autocomplete="on" label-position="left">
      <div class="title-container">
        <h3 class="title">Login Form</h3>
      </div>
...
</template>

<style lang="scss" scoped>
.login-container {
  min-height: 100%;
  width: 100%;
  background-color: $bg;
  overflow: hidden;
...
}

上述中定义 vue 组件模板,并在模板中应用 scoped 级别的 样式 login-container。

二、Vue 对 scoped 的渲染规则

scoped 修饰的 style 只给当前组件的元素使用,是如何实现的呢?

原理是给渲染后的 DOM 元素增加一个唯一标志,类似于 “data-v-123lsdfast23”,在 css 选择器上也有一个对应的相同标志,间接提升了样式的权重,使得样式更不容易被覆盖,具体如下:

1、 生成 data 属性

对于所有的 Vue 组件,只要设置了 ,Vue 就会给该组件生成一个唯一 data 值。

2、DOM 节点添加 data 属性

Vue 会将 data 值作为一个属性添加到组件内所有 HTML 的 DOM 节点。
pic

3、子组件添加 scope

如果组件内部包含子组件,这有两种情况:

  • 子组件没有设置 scoped ,则只会给子组件的最外层标签加上当前组件的 data 属性
  • 子组件设置了 scoped ,则子组件会自动生成一个自己的唯一 data 值,然后子组件最外层标签在自己的 data 属性后面添加父组件的 data 属性。

4、css 样式添加 data 属性选择器

对于组件内写在 里的样式,Vue 均会自动在每句 css 选择器的末尾添加一个当前组件的 data 属性选择器来私有化样式。
pic

基于上面四点,Vue 就实现的 scoped 的功能。因为,组件 scoped 里的样式都加了当前组件的唯一标识 data 属性。
也就是说,即使当前组件的 class 跟其他组件重名,因为每个组件的 data 属性不一样,当前组件的样式也就不能再其他组件生效了。

三、如何影响子组件

但是,这也会产生一些麻烦,scoped 属性样式只能作用于组件自身 DOM 元素,父组件的样式不会渗透到子组件中去,那如果影响子组件呢?

1、使用深度选择器来解决这个问题:

使用深度选择器,既不破坏别的组件的 css,也能覆盖子组件。

.el-collapse-item >>> .el-collapse-item__header{
    background-color: rgb(217, 237, 247);
}

注意如果这里是 scss 或者 cass,不能用 >>> 而是用 deep,而且不能并列写而是有层级关系!

.el-collapse-item {
    /deep/ .el-collapse-item__header{
        background-color: rgb(217, 237, 247);
    }
}

2、将全局属性和局部属性分开处理

<style>
/* global styles */
</style>
<style scoped>
/* local styles */
</style>

评论

暂无

添加新评论