Vue 中的 scoped

238 阅读1分钟

scoped 是 Vue 中 css <style> 标签的 一个属性,当 <style scopde> 时,css样式只会影响当前组件。

用人话来说就是如果在Vue 的某个组件中 <style> <style/> 标签上添加了 scoped 这个属性,那么你就不能在当前组件的 css 控制其它组件的样式。

什么?Vue每个组件的样式还可以互相控制?

答案是yes(前提是有import)


image.png

我让HelloWord.vue 引入Son.vue

App.vue 里面已经引入了 HelloWord.vue

HelloWord.vue代码如下

<template>
 <div class="hello">
   <h1>{{ msg }}</h1>
   <h3>Installed CLI Plugins</h3>
   <ul>
    <li>1</li>
    <li>2</li>
   </ul>
   <Son class="bb" />  //son在这
 </div>
</template>

<script>
import Son from "./Son";

export default {
 name: "HelloWorld",
 components: {
   Son
 },
 props: {
  msg: String,
 },
};
</script> 

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="less" scoped>
h3 {
   margin: 40px 0 0;
}

ul {
  list-style-type: none;
 padding: 0;
}

li {
 display: inline-block;
 margin: 0 10px;

}
.bb {
  border: 1px solid blue; 
  color: chartreuse;
  font-size: 70px;
/* display: flex; */

}
.bb p {
  background:cadetblue
}
/* .bb li {
     height:20px;
} */

</style>

Son.vue 代码

 <template>
 
  <div class="fa">
   <h1>nnnnnnnnn</h1>
   <p>hjhjjhj</p>
  </div>

</template>

<script>

 export default {
  name: "Son",
 };

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

h1 {

   /* color:red; */
   background-color: brown;
}

</style>
 
 

一、 我在HelloWord.vue 中引入了 Son.vue,并且给它一个class='bb'

class会在Son.vue组件中的最外围标签出现

image.png

我在HelloWorld.vue中对.bb 添加样式效果如下图

.bb {                      
   border: 1px solid blue; 
   color: chartreuse; 
   font-size: 70px;
   /* display: flex; */ 
 }

image.png

外边框border有了,h1标签中的font-size、color 也都生效了。注意此时HelloWord.vue 中 css 是有scoped 属性的!

为什么呢?不是说好了scoped 只对当前组件样式生效吗?

原因:1、

这点在官方文档 vue-loader 中 Scoped CSS篇章中有提到

image.png

所以这里我们也可以通过这个 class 对 子组件 Son.vue 进行部分的样式调节,尽管当前组件 css 有scoped

原因 2、 scoped 并不能阻止继承属性的样式 所以font-size、color才会对Son.vue 中 的p 、h1 标签生效

由此可见scoped 的隔离并不是绝对的


二、我们回到开头发出的问题:如果不加 scoped 是否能在 HelloWorld.vue 修改其子组件 Son.vue 的样式呢?

//我们在 `HelloWord.vue` 去掉<style> 标签上的` scoped` 试图修改Son.vue 中的 h1 标签的样式
     
.bb h1 {
  font-size: 16px;
  color: red;

}
    

image.png

注意看 nnnn... 的部分就是 h1 标签,确实修改成功了。

但是当加上 scoped 属性时,想修改 .bb 内部的标签是没用的

所以说scoped 确实能在一定程度上限制各组件的样式让其私有化,防止各组件的样式污染


三、深度选择器

官方文档

如果你想在组件css有 scoped 的情况下 去修改子组件的样式,那么你就可以用它

  1. >>>
  2. /deep/ 或者 ::v-deep
<style scoped>
.bb >>> h1 {
    /* height:20px; */
    font-size: 16px;
    color: red;
}

</style>

有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。