首页 > 技术分享 > Vue
收藏

Vue组件中css的用法,Vue组件使用class选择器,解决Vue组件样式冲突的问题

11/29 22:45
大潇博客 原创文章,转载请标明出处

目录


1、style基本结构

Vue 规定:组件内的 <style> 节点是可选的,开发者可以在 <style> 节点中编写样式美化当前组件的 UI 结构。

<style lang="css">

h1{

font-weight: normal;

}

</style>

其中 <style> 标签上的 lang="css" 属性是可选的,它表示所使用的样式语言。默认只支持普通的 css 语法,可选值还有 less、scss 等。


2、使用less语法

如果希望使用 less 语法编写组件的 style 样式,可以按照如下两个步骤进行配置:

⑴ 安装less依赖包,从而提供less语法的编译支持

npm install less -D

npm install less-loader -D

⑵ 在 <style> 标签上添加 lang="less" 属性,即可使用 less 语法编写组件的样式

<style lang="less">
h4{
  color:red;
  em{
    color: blue;
  }
}
</style>


3、样式隔离scoped

默认情况下,写在 .vue 组件中的样式会全局生效,因此容易造成多个组件之间的样式冲突问题。

解决方法1:编写组件样式时,通过 [...] 属性选择器来控制样式的作用域

<template>

<div class="container" data-01>组件内容</div>

</template>

<style>

/* 通过中括号“属性选择器”,来防止组件之间的样式冲突 */

.contarner[data-01] {

border: 1px solid;

}

</style>

解决方法2:在 style 中加上 scoped 属性,表示 style 内的样式只在组件内生效,实现元素样式的隔离,可防止 css 样式名称冲突

<style lang="less" scoped>

</style>

注意:

<style scoped> 会为当前组件的静态模板中的元素添加 data-v-xxx 属性,并生成对应的属性选择器(如 .my-class[data-v-558dbb7b])。

但 v-html 插入的内容是运行时动态生成的,Vue 不会为这些 DOM 元素添加 data-v-xxx 属性,因此 scoped 样式中的选择器匹配不到这些动态元素,样式不生效。

这种情况有解决方法,具体方式请看下面的 deep 样式穿透。


3、样式穿透deep

如果给当前组件的 style 加上 scoped 属性,则当前组件的样式对其子组件不生效。如果想让某些样式对子组件生效,可以使用 deep 深度选择器

Vue 各版本深度选择器的演化趋势:

>>> → /deep/ → ::v-deep → ::v-deep() → :deep()

注意两点:

⑴ /deep/ 和 ::v-deep 以及 ::v-deep() 都是 vue2 或 vue2 向 vue3 过渡时期使用的深度选择器,现在均已废弃或不再推荐使用

⑵ :deep() 是 Vue3 官方推荐的深度选择器

<style scoped>

.parent :deep(.child) {

/* 样式规则 */

}

</style>

注意:使用组件的样式穿透时,组件的外面一定要被 html 标签包裹,才可以使用 :deep(),否则样式不生效,如下示例:

# 父组件

<template>

<div class="pr">  <!-- 使用组件,组件间外面必须被html标签包裹,才能实现样式穿透-->

<Test />

</div>

</template>

<script>

import Test from "./components/Test.vue"; //导入组件

export default {

name: 'App',

component: {

Test //注册组件

}

}

</script>

<style scrped>

.pr :deep(.ch){ /* 也可以直接用 :deep(.ch) */

color: yellow

}

</style>


# 子组件

<template>

<div class="ch">子组件</div>

<template>

<script>

export default {

name: 'MyTest'

}

</script>

当 v-html 插入的样式不生效时,也可以使用 deep 深度选择器来解决,比如向 p 标签插入一些内容,可以这样:

<style scoped>

/* 让这个样式穿透到 v-html 生成的元素 */

:deep(p) {

color: red;

font-size: 16px;

}

.content .middle :deep(p){ ... }  /*样式穿透到 .content 下面的 .middle 下面的 p 标签*/

.content .middle :deep(p span){ ... }

</style>


4、class选择器:对类样式进行动态绑定

实际开发中经常会遇到动态操作元素样式的需求,因此vue允许开发者通过 v-bind 属性绑定指令,为元素动态绑定 class 属性和行内的 style 样式

:class="{ 类(属性)名字:true }" //大括号表示一个对象,其中写 js 代码,要不要用类的名字,取决于后面的参数是 true 或 false

可以通过三元表达式,动态为元素绑定 class 属性

:class=" 1==1? '类名' : '' "

举例说明:

<template>

<!-- 当data中的colorFlag值为true时,使用color类,此处注意使用大括号,舍去将报错 -->

<h1 :class="{ color:colorFlag }">{{title}}</h1>

<!-- 当data中的italicFlag值为true时,使用italic类,否则为空 -->

<h2 :class=" italicFlag ? 'italic' : '' ">奥斯特洛夫斯基</h2>

</template>

<script>

export default {

name: "MyApp",

data() {

title: "钢铁是怎样炼成的",

colorFlag: true,

italicFlag: false,

}

}

</script>

<style>

.color {

color: blue;

}

.italic {

font-style: italic;

}

</style>


5、以数组语法绑定HTML的class

如果元素需要动态绑定多个 class 的类名,此时可以使用数组的语法格式:

<h1 :class="[ 参数1 ? 'class name1' : '' , 参数2 ? 'class name2' : '' ]">-</h1>

比如

<template>

<div :class="[ italic ? 'text' : '', color ? 'color' : '' ]">世界上最宽阔的是海洋,比海洋更宽阔的是天空,比天空更宽阔的是人的心灵。”</div>

<button @click="italic=!italic">改变字体</button>

<button @click="color=!color">改变颜色</button>

</template>

<script>

export default {

name: "Article",

data() {

return {

italic: false,

color: false,

}

}

}

</script>

<style>

.text{

text-decoration: line-through;

}

.color{

color: blue;

}

</style>

使用数组语法动态绑定class,会导致模板结构臃肿的问题,此时可以使用对象语法进行简化

<template>

<!-- 使用v-bind:class 绑定一个对象 -->

<div :class="classObj">世界上最宽阔的是海洋,比海洋更宽阔的是天空,比天空更宽阔的是人的心灵。”</div>

<button @click="classObj.text=!classObj.text">改变上文字体</button>

<button @click="classObj.color=!classObj.color">改变上文颜色</button>

</template>

<script>

export default {

name: "Article",

data() {

return {

// class绑定的对象

classObj: {

text: false,  // 格式,class类名: 布尔值

color: false

}

}

}

}

</script>

<style>

.text{

text-decoration: line-through;

}

.color{

color: blue;

}

</style>


6、动态绑定style样式

:style=""

比如

<template>

<h3 :style="style ">西游记</h3>

</template>

<script>

export default {

data() {

style: 'font-weight: 200'

}

}

</script>


7、以对象语法绑定内联的style

:style 的对象语法十分直观,看着非常像 css,但其实是一个 javascript 对象。css property 名可以用驼峰式(camelCase)或短横线分割(需用引号括起来)来命名,用法有如下区别

驼峰式:即把常用 css 名称中的短横线去掉,短横线后面的字母大写,可直接使用,比如:font-size=>fontSize、background-color=>basckgroundColor

短横线:使用时需要用引号括起来

<!-- 驼峰式的 fontSize 和 引号括起来的 'background-color' -->

<div :style="{ color:styleObj.color, fontSize:styleObj.size+'px', backgroundColor:styleObj.bgcolor }">丑在美的旁边,畸形靠近着优美,丑怪藏在崇高背后,美与丑并存,光明与黑暗相共。</div>

<button @click="styleObj.size=styleObj.size-1">减小上文字体</button>

<button @click="styleObj.size=styleObj.size+1">增加上文字体</button>

<script>

export default {

name: "Article",

data() {

return {

styleObj: {

color: 'red',

size: 18,

bgcolor: 'yellow'

}

}

}

}

</script>


打赏

上一篇:Vue插槽slot使用方法

下一篇:webpack入门

阅读排行

大家都在搜

博客维护不易,感谢你的肯定
扫码打赏,建议金额1-10元
  • 15601023311