Vue – CSS样式冲突与 scoped 底层原理
简介
默认情况下,写在 .vue 组件中的样式会全局生效,因此很容易造成多个组件之间的样式冲突问题
原因
导致组件之间样式冲突的根本原因是:
① 单页面应用程序中,所有组件的DOM 结构,都是基于唯一的index.html 页面进行呈现的
② 每个组件中的样式,都会影响整个index.html 页面中的DOM 元素
Vue 解决原理
Vue 在样式中使用 "属性选择器",以准确的识别组件元素,它们的区别如下
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
在正常情况下,所有 DOM 元素
<div id="app" data-v-xxxxxx>
<img alt="Vue logo" src="./assets/logo.png" data-v-xxxxxx>
<HelloWorld msg="Welcome to Your Vue.js App" data-v-xxxxxx/>
</div>
为每个组件分配唯一的自定义属性,在编写组件样式时,通过属性选择器来控制样式的作用域.
在 Vue 开启样式冲突问题时,所有 DOM 元素,会自动为该组件所有元素增加 data-v-xxxxxx 的属性,而在样式表中,同时也自动增加样式的“属性选择器”
#app[data-v-xxxxx]{ ... }
在样式中增加一个固定关键词 scoped 即可达到效果。
<style lang="less" scoped>
只影响子组件样式
如上章所述,当样式中加入 scoped 时,该样式只会作用于该组件。
但如果该组件包含子组件,而该组件的样式希望只影响其下的子组件,同时不进行修改子组件的样式的情况下,可以使用 /deep/ 关键字。
/deep/ .foo{
color: red;
}
在样式前加入 /deep/ 关键字,则将影响子组件中对样的元素样式
其原理是 在子组件 div 元素中也一并加入 data-v-xxxxx 属性
共有 0 条评论