vue动态样式绑定改变伪元素等特殊样式(css var函数)

改变样式是我们实际开发中最常做的事情。
诸如在css中,我们添加鼠标滑入滑出效果添加不同的样式。
诸如在js中,我们根据某个条件,或者触发某个方法,去动态改变某个样式。
那么,在vue中,我们更能很轻松的达到这点。
看下常见的几种情景:

  • 情景一:我们需要根据某个变量是否存在(触发),去动态添加样式
    描述:当我们点击按钮触发了某个条件,我们需要给对应的元素添加激活效果
<div
     class="flip"
     :style="{
        background:变量?'red':'black'
     }"
/div >

这里我们通过三目判断某个触发条件的变量是否为true以此来添加不同的样式(当然也可以动态绑定class,来添加不同的类名,实现不同的效果)

  • 情景二:我们封装组件,希望外界可以自定义传入实现不同的样式
    描述:通过props定义样式值,外界可自定义传入改变,不传入则使用默认值
<template>
           <div class="rd-flop">
                   <div
                       class="flip"
                       :style="{
                           width: width,
                           height: height,
                           lineHeight: lineHeight,
                           margin: margin,
                           fontSize: `${fontSize}px`,
                           fontWeight: fontWeight,
                           border: border,
                           borderRadius: `${borderRadius}px`,
                           boxShadow: boxShadow,
                       }"
                   >
                   </div>
           </div>
   </template>
   
<script>
export default {
   name: '',
   props: {
       width: { type: String, default: '36px' }, // 宽度
       height: { type: String, default: '46px' }, // 高度
       lineHeight: { type: String, default: '46px' }, // 高度
       margin: { type: String, default: '2px' }, // 间距
       fontSize: { type: Number, default: 16 }, // 字体大小
       fontWeight: { type: Number, default: 900 }, // 字体加粗(100-500为不加粗,600-900加粗)
       border: { type: String, default: '1px solid transparent' }, // 边框
       borderRadius: { type: Number, default: 0 }, // 圆角
       boxShadow: { type: String, default: '0 0 6px rgba(0, 0, 0, 0.5)' }, // 容器阴影
   }
};
</script>

上面的组件,我们再使用的时候,当我们不传入值的时候,也能正常显示默认值达到默认效果,我们也可以传入对应的值达到不同的复用效果

  • 情景三:动态绑定实现改变伪元素等样式
    描述:以上样式都是我们最普通的样式,但是我们如何通过绑定样式改变伪元素(::before、::after)、激活、滑入等复杂的样式呢?看下下面的示例吧:
<template>
   <div class="rd-flop">
       <div class="rd-clock-card" v-if="currData" ref="rdFlop">
           <div
               class="flip"
               :style="{
                   width: width,
                   height: height,
                   lineHeight: lineHeight,
                   margin: margin,
                   fontSize: `${fontSize}px`,
                   fontWeight: fontWeight,
                   border: border,
                   borderRadius: `${borderRadius}px`,
                   boxShadow: boxShadow,
                   '--threeColumnMargin': threeColumnMargin,
               }"
               v-for="(item, index) in currValue.length"
               :key="index"
           >
               <div
                   class="digital front"
                   :style="{
                       '--pseudoElementColor': pseudoElementColor,
                       '--pseudoElementBg': pseudoElementBg,
                       '--pseudoElementBorder': pseudoElementBorder,
                       '--pseudoElementTopBorderRadius': pseudoElementTopBorderRadius,
                       '--pseudoElementBotBorderRadius': pseudoElementBotBorderRadius,
                       '--pseudoElementBoxShadow': pseudoElementBoxShadow,
                   }"
                   data-number="0"
               ></div>
               <div
                   class="digital back"
                   :style="{
                       '--pseudoElementColor': pseudoElementColor,
                       '--pseudoElementBg': pseudoElementBg,
                       '--pseudoElementBorder': pseudoElementBorder,
                       '--pseudoElementTopBorderRadius': pseudoElementTopBorderRadius,
                       '--pseudoElementBotBorderRadius': pseudoElementBotBorderRadius,
                       '--pseudoElementBoxShadow': pseudoElementBoxShadow,
                   }"
                   data-number="1"
               ></div>
           </div>
       </div>
       <p :style="{ margin: titleMargin, fontSize: `${titleFontSize}px` }">
           {{ category }}
       </p>
   </div>
</template>

<script>
export default {
   name: '',
   props: {
       title: String, // 标题
       width: { type: String, default: '36px' }, // 宽度
       height: { type: String, default: '46px' }, // 高度
       lineHeight: { type: String, default: '46px' }, // 高度
       margin: { type: String, default: '2px' }, // 间距
       threeColumnMargin: { type: String, default: '5px 30px 5px 5px' }, // 第三列间距(数字三个一组)
       fontSize: { type: Number, default: 16 }, // 字体大小
       fontWeight: { type: Number, default: 900 }, // 字体加粗(100-500为不加粗,600-900加粗)
       border: { type: String, default: '1px solid transparent' }, // 边框
       borderRadius: { type: Number, default: 0 }, // 圆角
       boxShadow: { type: String, default: '0 0 6px rgba(0, 0, 0, 0.5)' }, // 容器阴影
       pseudoElementColor: { type: String, default: '#fff' }, // 伪元素字体颜色
       pseudoElementBg: { type: String, default: '#3354e2' }, // 伪元素背景
       pseudoElementBorder: { type: String, default: '1px solid #666' }, // 伪元素边框
       pseudoElementTopBorderRadius: { type: String, default: '0 0 0 0' }, // 伪元素上半部分圆角
       pseudoElementBotBorderRadius: { type: String, default: '0 0 0 0' }, // 伪元素下半部分圆角
       pseudoElementBoxShadow: {
           type: String,
           default: '0 -2px 6px rgba(255, 255, 255, 0.3)',
       }, // 伪元素容器阴影
       titleMargin: { type: String, default: '20px 0 0 0' }, // 标题间距
       titleFontSize: {
           type: Number,
           default: 30,
       }, // 标题字体大小
   },
};
</script>

<style scoped>
.rd-clock-card .flip .digital::before,
.rd-clock-card .flip .digital::after {
   position: absolute;
   content: attr(data-number);
   left: 0;
   right: 0;
   color: var(--pseudoElementColor);
   background: var(--pseudoElementBg);
   overflow: hidden;
   perspective: 160px;
}

.flip:nth-of-type(3n) {
   margin: var(--threeColumnMargin) !important;
}

.rd-clock-card .flip .digital::before {
   top: 0;
   bottom: 50%;
   border-bottom: var(--pseudoElementBorder);
   border-radius: var(--pseudoElementTopBorderRadius);
}

.rd-clock-card .flip .digital::after {
   top: 50%;
   bottom: 0;
   line-height: 0;
   border-radius: var(--pseudoElementBotBorderRadius);
}

.rd-clock-card .flip.running .front::before {
   transform-origin: center bottom;
   animation: frontFlipDown 1s ease-in-out;
   box-shadow: var(--pseudoElementBoxShadow);
   backface-visibility: hidden;
}
</style>

上述示例中,我们在对应的样式处,通过 var(--自定义命名) 的方式定义变量(括号里面是两条杠,别写错了),在vue的标签处通过 '--var中定义的命名': props中对应的样式变量 就可以改变对应的样式。
当然了,功能远不止于此,我们在使用一些公共ui库(比如element ui)时,它的一些标签都是自动生成的,比如我们只引入了 el-dropdown 下拉菜单,但是我们通过在控制台查阅发现内部可能嵌套生成很多标签,这时我们想改变内部嵌套的子元素的样式,就没办法直接给父元素绑定诸如宽、高的方式,我们可以找到对应的类名样式,通过 var的方式(参考如下)

.VideoSurveillance .listArea .videoList .el-tree .el-tree-node__content {
    height: var(--itemGap);
    line-height: var(--itemGap);
    position: relative;
}

当然了,考虑用法前可以参考下兼容性


在这里插入图片描述

好了,如上就是vue中动态改变特殊样式时的技巧。
如有问题,请指出,接收批评。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容