一、scoped
1.1 什么是scoped
scoped 属性是 HTML5 中的新属性,是一个布尔属性。
1.2 scoped作用
对于
style标签上添加scoped属性的vue组件,为了避免样式的污染,做了如下处理
-
给当前组件的所有标签添加一个不重复的data属性(形如:
data-v-40b76154)来表示唯一性 -
为了避免影响全局样式
- 给每句CSS选择器末尾(编译后生成的CSS语句)加一个当前组件的
data-v-hash属性选择器来私有化样式
- 为了避免影响子组件的样式
- 只会给子组件的最外层标签上添加当前组件的
data-v-hash属性
⬆️上述效果主要是通过PostCss转译实现的,下面来看一下转译前后代码对比⬇️
//转译前
<template>
<div class="wrap">
<div class="example">你真的了解scoped吗?</div>
</div>
</template>
<style scoped>
.wrap .example{
color: red;
}
</style>
//转译后
<template>
<div class="wrap" data-v-109a2208>
<div class="example" data-v-109a2208>你真的了解scoped吗?</div>
</div>
</template>
.wrap .example[data-v-109a2208]{
color: red;
}
所以,如果组件的style标签上有scoped,那么在当前组件的style标签上写的样式就无法作用到子组件上了
我们可以使用下面的方法来解决这个问题⬇️
二、解决方式
2.1 两个Style
2.1.1 使用方式
全局样式可以作用到当前组件的子组件上
<style>
/* 全局样式 */
</style>
<style scoped>
/* 局部样式 */
</style>
2.1.2 效果展示
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/' }">活动管理</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: "deep",
};
</script>
<style>
.el-breadcrumb__item:nth-child(1) .el-breadcrumb__inner.is-link {
color: red;
}
.el-breadcrumb__item:nth-child(2) .el-breadcrumb__inner.is-link{
color: blue;
}
</style>
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item :to="{ path: '/' }">活动管理</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: "deep",
};
</script>
<style>
.el-breadcrumb__item:nth-child(1) .el-breadcrumb__inner.is-link {
color: red;
}
</style>
<style scoped>
.el-breadcrumb__item:nth-child(2) .el-breadcrumb__inner.is-link{
color: blue;
}
</style>
2.2 穿透
2.2.1 三种深度作用选择器
>>>
介绍:如果是css原生样式,那么可以直接使用 >>>
问题:但如果是scss/sass/less的话可能无法识别
<style lang="css" scoped>
.a >>> .b{
XXX
}
</style>
/deep/
介绍:less/sass的样式穿透
问题:vue-cli3编译时,deep方式会报错或者警告
<style lang="css" scoped>
.a {
/deep/ .b {}
}
</style>
::v-deep:
介绍:推荐用这种方式
<style lang="css" scoped>
.a {
::v-deep .b {}
}
</style>
2.2.2 穿透的实现原理
没加穿透
<style scoped>
.wrap .example {
color: red;
}
</style>
.wrap .example[data-v-469af010] {
color: red;
}
添加穿透
<style scoped>
.wrap ::v-deep .example {
color: red;
}
</style>
.wrap[data-v-469af010] .example {
color: red;
}
由此可知,穿透只是改变了data-v-hash的位置
2.2.3 效果展示
此处用element-ui的el-breadcrumb组件(面包屑导航)来验证上面讲的内容
没加穿透
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: "deep",
};
</script>
<style scoped>
.el-breadcrumb__item .el-breadcrumb__inner.is-link {
color: red;
}
</style>
添加穿透
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
<el-breadcrumb-item><a href="/">活动管理</a></el-breadcrumb-item>
<el-breadcrumb-item>活动列表</el-breadcrumb-item>
<el-breadcrumb-item>活动详情</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script>
export default {
name: "deep",
};
</script>
<style scoped>
.el-breadcrumb__item ::v-deep .el-breadcrumb__inner.is-link {
color: red;
}
</style>