vue中的scoped

文章类型:Vue

发布者:hp

发布时间:2025-02-20

一概述:

在vue项目开发过程中,我们使用scoped进行样式隔离,避免了样式之间相互覆盖,那么,是怎么实现的呢?

二:类别

1:BEM方案:通过.block__element--modifier即.模块名__元素名--修饰符名这种CSS命名方式实现样式隔离和模块化

2:CSS Modules:将CSS文件进行编译后,使之具备模块化的能力

3:CSS-IN-JS:使用 js 来编写CSS规则

三:定义

1:Vue设置样式的方法则是通过单文件组件中的style标签进行样式,你只要在style标签上添加一个scoped属性,就能轻松实现样式隔离,

2:代码

 <style scoped>
   .container {
       background: red;
   }
 </style>
 <style scoped>
   .container[data-v-mlxsojjm] {
       background: red;
   }
 </style>

四:原理

1:目的

在style标签上增加scoped属性后,最终编译出来的结果会在选择器上增加一个唯一的attribute(比如data-v-mlxsojjm),

每个.vue文件编译出来的attribute都不一样,从而实现了样式隔离

2:流程

通过解析编译包@vue/compiler-sfc来进行解析

 const { compileStyle } = require("@vue/compiler-sfc");
 const css = `
 .container {
     width: 100px;
     height: 100px;
     background-color: red;
 }
 `;
 const { code } = compileStyle({
   source: css, // css源代码
   scoped: true, // 是否要启用scoped
   id: `data-v-${Math.random().toString(36).substring(2, 10)}`, // scoped的id
 });
 console.log(code);

3:输出

编译后会被加上一个属性选择器,名字以data-v开头,后边自定义,保证全局唯一

 .container[data-v-mlxsojjm] {
     width: 100px;
     height: 100px;
     background-color: red;
 }

五:拓展

(1):子组件的根节点会同时被自己以及父组件的样式所影响

使用 scoped 后,父组件的样式将不会渗透到子组件中,子组件的根节点会同时被父组件的作用域样式和子组件的作用域样式影响。为了让父组件可以从布局的角度出发,调整其子组件根元素的样式

(2):scoped对插槽slot的影响

slot中的内容最终编译出来会同时含有父子组件scopedId,所以会同时受父子两个组件的的样式影响

(3):深度选择器

1:>>>

2:/deep/

3:::deep{}

4::deep()

六:总结

1:主要就是通过生成一个唯一的attribute来实现的,并且带大家通过程序编译了一下带有scoped属性css的.vue文件