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

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

作者: 坏丶毛病 | 来源:发表于2020-12-16 09:47 被阅读0次

    改变样式是我们实际开发中最常做的事情。
    诸如在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中动态改变特殊样式时的技巧。
    如有问题,请指出,接收批评。

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/pykngktx.html