组件中样式的冲突
组件中定义的样式,默认是全局都有效的,vue最终会把这些样式汇总到一起。
组件的样式最终汇总出来的顺序,取决于在父组件中引入的顺序。
例如:School中定义的样式:
<template>
<div class="demo">
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<br>
</div>
</template>
<style>
.demo {
background-color: skyblue;
}
</style>
在Student.vue中定义的样式:
<template>
<div class='demo'>
<h2>学生姓名:{{name}}</h2>
<h2>学生性别:{{sex}}</h2>
</div>
</template>
<style>
.demo {
background-color: orange;
}
</style>
如果在App组件中同时引入了School、Student两个组件,则这两个组件的样式都会被引入。因为这两个组件的模板class都叫demo
,就会产生冲突。
模板最终使用的background-color
取决于哪个组件在App中最后被引入:
import Student from './components/Student'
// 先引入Student,然后引入School,则最后的background-color使用的是School中的样式
import School from './components/School'
如果改为先引入School再引入Student,样式就会使用Student定义的样式:
import School from './components/School'
// 最后引入Student组件,则最后冲突的样式使用的是Student的样式
import Student from './components/Student'
限制样式作用域
使用scoped
属性限制该样式只对当前组件有效:
<!-- 使用了scoped限制了作用域,该样式只会对当前组件有效 -->
<style scoped>
.demo {
background-color: orange;
}
</style>
实现原理:Vue会给该组件添加一个data-v-随机数
的属性,然后在样式上也添加该属性的筛选:
.data[data-v-xxxxxx]
。这样这个样式就只会对这个组件有效了。
加了scoped
之后,这个样式只会对当前组件有效,对当前组件引入的子组件无效。
使用预编译语言编写样式
可以使用<style>
的lang
属性声明该样式使用的语言。
例如:
<!-- 声明该样式使用css编写 -->
<style lang='css'></style>
如果要使用 less 编写样式,则需要设置:(不配置时,默认使用的css)
<style lang='less'></style>
除此之外,还需要安装 less-loader:
最新版的less-loader只支持webpack5,但是目前Vue脚手架中引入的webpack是4.46版,所以不能直接下载最新版的less-load,需要加上版本限制。
# 查看webpack的所有版本
npm view webpack versions
# 查看less-loader的所有版本
npm view less-loader versions
# 限制安装的less-load版本为7.x
npm i less-loader@7
如果报错缺少less,则需再安装less:
npm i less