首页 > 其他分享 >利用css var函数让你的组件样式输出规范样式API,可定制性更高;

利用css var函数让你的组件样式输出规范样式API,可定制性更高;

时间:2023-05-10 12:45:20浏览次数:34  
标签:组件 样式 height -- API var desc

我们平时在使用Elementui Antdesing这些UI库时,难免会碰到使用deep强行侵入式去修改组件内部样式的情况;   比如下列代码,我们需要把ant的分页样式进行高度自定义,就得使用deep去修改;   这种实现方式确实能够达到我们的目的,但在开发时确总觉得不太合适: 1、他属于强行入侵组件内部去修改,虽然不会有大问题,但总觉得这种取巧方式有点不可取。 2、每次写deep时需要手动检查DOM元素进行编辑,UI文档中并不会有相关API文档;   为了解决心中的这两个结症,趁最近写组件的机会探索了下CSS 的var函数,发现他可以很好的解决以上问题。   利用var函数我们可以具体解决组件开发的以下问题:   1、组件样式自定义可以更加个性化   2、现在很多组件库实现一些样式控制还是依靠props传参的形式,这种var函数结合Style可完全避免props传参的情况,把样式跟props区分开;   3、在组件文档中可明确定制样式属性API;使组件样式可以跟Props属性一样以传参概念去进行高度定制,在使用组件样式时不需要像使用deep一样打开f12去一层一层的找   4、不会侵入式的改动组件内部样式   5、这个方案与deep互不排斥,如果开放的样式API不够用还是可以继续使用deep;   看下面需求,是如何利用css var函数实现一个可自定义大小,颜色,以及子元素样式的卡片  上代码

//Card.vue
<template>
    <div class="card">
        <img class="card-img" :src="img" />
        <p class="card-desc">{{ desc }}</p>
    </div>
</template>
<style lang="scss" scoped>
    .card {
        // 这些以"--"开头的变量就是我们开放可自定义的样式属性了,可以在组件使用文档中明确开放
        //卡片根元素样式
        --width: 150px;
        --height: auto;
        --border-size: 1px;
        --border-color: #ccc;
        --border-radius: 5px;
        --bg: #eee;
        // 图片可定样式
        --img-width: 130px;
        --img-height: 130px;
        --img-radius: 50%;
        // 卡片描述样式
        --desc-size: 16px;
        --desc-line-height: 32px;
        --desc-color: #333;

        height: var(--height);
        width: var(--width);
        border: var(--border-size) solid var(--border-color);
        border-radius: var(--border-radius);
        background: var(--bg);
        padding: 10px;
        &-img {
            width: var(--img-width);
            height: var(--img-height);
            border-radius: var(--img-radius);
            overflow: hidden;
        }
        &-desc {
            font-size: var(--desc-size);
            color: var(--desc-color);
            line-height: var(--desc-line-height);
            text-align: center;
        }
    }
</style>

 

这时候我们在API文档则可明确规定样式定制属性了: 组件使用方式:
//demo.vue
<template>
    <div >
        <Card desc="我是默认的样式我是默认的样式我是默认的样式" :img="img" />
        <Card class="card_1" desc="自定义样式,子元素图片变小了" :img="img" />
        <Card class="card_2" desc="自定义样式,圆角没了,描述字变小了,高度高了" :img="img" />
    </div>
</template>
<script>...</script>
<style lang="scss" scoped>
    .card_1 {
        --width: 100px;
        --height: 200px;
        --border-radius: 20px;
        --img-width: 80px;
        --img-height: 50px;
        --img-radius: 10px;
        --desc-color: #f00;
        --desc-size: 12px;
        --desc-line-height: 21px;
    }

    .card_2 {
        --height: 300px;
        --border-radius: 0px;
        --bg: #fff;
        --img-radius: 50px;
        --desc-size: 14px;
        --desc-line-height: 21px;
    }
</style>

 

以上就是一个基本的组件实现; 还种情况我们在使用UI库时也会碰到需要使用Props传过来计算的参数,比如下列代码:

 这种我们也可以把这些全提出来使用style属性。让样式与js参数彻底隔离

//demo.vue
  <template>
        <card
            desc="我是默认的样式我是默认的样式"
            :img="img"
            :style="hoverStyle"
            @mouseout="hoverStyle = {}"
            @mouseover="handleHover"
        />
</template>
<script setup>
    let hoverStyle = ref({});
    const handleHover = () => {
        hoverStyle.value = { '--bg': '#f0f', '--width': '180px' };
    };
</script>

 

我们在组件内

JS可以使用props.style获取到设置的值, css中可以使用calc变量与var结合去计算你想要的值
//card.vue
<template>
    <div class="card" :style="style">
        {{ width }}
        <img class="card-img" :src="img" />
        <p class="card-desc">{{ desc }}</p>
    </div>
</template>
<script setup>
    const $props = defineProps({
        img: {
            type: String,
            default: '',
        },
        desc: {
            type: String,
            default: '',
        },
        style: {
            type: Object,
            default: () => ({}),
        },
    });
    //假如你在js中需要用到宽度
    let width = computed(() => {
        return parseInt($props.style['--width'] || 150);
    });
</script>
<style lang="scss" scoped>
.card{
    ...
    //假如你有个子级元素需要基于宽度计算
    .item{
        width: calc(var(--width) - 100)
    }
    ...
}
</style>

 

但是这种实现有命名空间的问题 所以需要稍微注意下变量命名,最好加独有的命名规则。防止变量覆盖;
//比如这样
.ch-card{
    --ch-card-width:100px;
    --ch-card-height:100px;
}

 

总结下这种方案的优缺点: 优点 1、组件样式自定义可以更加个性化 2、现在很多组件库实现一些样式控制还是依靠props传参的形式,这种var函数结合Style可完全避免props传参的情况,把样式跟props区分开; 3、在组件文档中可明确定制样式属性API;使组件样式可以跟Props属性一样以传参概念去进行高度定制,在使用组件样式时不需要像使用deep一样打开f12去一层一层的找 4、不会侵入式的改动组件内部样式 5、这个方案与deep互不排斥,如果开放的样式API不够用还是可以继续使用deep;   缺点: 1、开发组件时会工作量会增大,但是磨刀不误砍柴功 2、命名空间问题导致命名会有点长。   欢迎分享更好的解决方案。

标签:组件,样式,height,--,API,var,desc
From: https://www.cnblogs.com/hrw3c/p/17387649.html

相关文章

  • SpringBoot定义优雅全局统一Restful API 响应框架四
    如果没有看前面几篇文章请先看前面几篇SpringBoot定义优雅全局统一RestfulAPI响应框架SpringBoot定义优雅全局统一RestfulAPI响应框架二SpringBoot定义优雅全局统一RestfulAPI响应框架三目前我们好像似乎解决所有问题,达到了我们理想的效果如下但是在业务错误返回时候......
  • CSS学习1 认识CSS;三种CSS的编写样式;CSS注释;常见的CSS样式;元素link;CSS颜色表示方法;浏览
    1_认识CSSwhat:为网页添加样式(美化界面);一门样式表语言,不是编程语言发展历史css1(两个人合作发布)css2(w3c)css3(模块化持续发展中)总结:美化HTML,让HTML与CSS分离方式一:添加样式,例如颜色、字体,大小方式二:布局,按照某种结构显示2_三种CSS的编写样式声明:例如【color:red......
  • chatgpt帮我创建一个由go+mysql+jwt+gorm搭建的restapi
    好的,下面是一个简单的由go+mysql+jwt+gorm搭建的RESTAPI示例:首先,你需要创建一个新的Go模块。你可以使用如下命令来创建一个名为example的新模块:gomodinitexample接下来,你需要安装需要的依赖库,使用以下命令进行安装:gogetgithub.com/gorilla/muxgogetgithub.com/jinzhu......
  • 自定义 li 标签序列的样式
    第一步删除li标签的默认样式,取消::mark代理样式(默认样式)。第一步已经把默认样式取消了,自然没有了序号,使用CSS的counter()函数和counter-increment属性来自定义序列号。通过list-style-type:none删除li标签的默认样式在li标签样式中设置counter-increment:st......
  • 深入理解前端字节二进制知识以及相关API
    当前,前端对二进制数据有许多的API可以使用,这丰富了前端对文件数据的处理能力,有了这些能力,就能够对图片等文件的数据进行各种处理。本文将着重介绍一些前端二进制数据处理相关的API知识,如Blob、File、FileReader、ArrayBuffer、TypeArray、DataView等等。字节在介绍各种API之前,......
  • Hadoop API使用 大坑
      这几天一直在困扰我pycurl版本和本机的版本不符合他连接又连接的自己自带的版本与系统不相同低级也会报错 https://blog.csdn.net/u010910682/article/details/89496550/?ops_request_misc=&request_id=&biz_id=102&utm_term=pycurl7.45.2%20%E6%90%AD%E9%85%8Dlibcu......
  • React笔记-样式(二)
    React学习笔记-样式(二)内联样式importReactfrom"react";exportdefaultclassLearnStyleextendsReact.Component{render(){return(<div>{/*以下两种方法都可以一种不用引号将css以小驼峰方式写另一种加上引号写......
  • fastapi篇(六)
    关于请求体参数、路径参数、请求参数的声明函数参数按照如下的顺序进行识别匹配:(1)、如果这个参数已经在路径中被声明过,那么它就是一个路径参数。(2)、如果这个参数的类型是单类型的(如str、float、int、bool等),那么它就是一个请求参数。(3)、如......
  • fastapi篇(五)
    get请求的请求参数1、如果函数里的参数不是路径参数的一部分,那么这样的参数就自动被解释为请求参数。2、请求参数就是URL中问号('?')后面以'&'间隔开的键值对,它们是URL的一部分,并且参数类型都是字符串类型。@app.get("/str")defget_str(item:str="1"):print......
  • fastapi篇(四)
    路径参数声明借助类型注解。fastapi会自动对request前端请求参数实现自动转换@app.get("/str/{item}")defget_str(item:str):print(item,type(item))return"只有永不遏止的奋斗,才能使青春之花,即便是凋谢,也是壮丽的凋谢"6<class'str'>还有其他的一些比......