我们平时在使用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、命名空间问题导致命名会有点长。
 
欢迎分享更好的解决方案。

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

  1. css中var函数

    引言: 在学习elementui的时候看到一个var.css, 其中写的全部都是以--开头的属性,上google查询不是css3新增的属性,于是决定一探究竟 :root { /* Transition ...

  2. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  3. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法(转)

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  4. 利用css+原生js制作简易钟表

    利用css+原生js制作简单的钟表.效果如下所示 实现该效果,分三大块:html.javascript.css html部分html部分比较简单,定义一个clock的div,内部有原点.时分秒针.日期 ...

  5. 利用CSS、JavaScript及Ajax实现图片预加载的三大方法及优缺点分析

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布 ...

  6. 现代 CSS 解决方案:CSS 数学函数

    在 CSS 中,其实存在各种各样的函数.具体分为: Transform functions Math functions Filter functions Color functions Image ...

  7. 利用css实现搜索过滤

    无意中找到一种利用css就可实现的搜索过滤的方法,不得不说看了代码之后确实被惊艳到了,亏我之前面试还因为做这个功能做太慢而拖了后腿.在此记录下代码: <!DOCTYPE html> < ...

  8. 在vue中结合render函数渲染指定的组件到容器中

    1.demo 项目结构: index.html <!DOCTYPE html> <html> <head> <title>标题</title> ...

  9. CSS 数学函数与容器查询实现不定宽文本溢出跑马灯效果

    在许久之前,曾经写过这样一篇文章 -- 不定宽溢出文本适配滚动.我们实现了这样一种效果: 文本内容不超过容器宽度,正常展示 文本内容超过容器的情况,内容可以进行跑马灯来回滚动展示 像是这样: 但是,之 ...

  10. iOS基本动画/关键帧动画/利用缓动函数实现物理动画效果

    先说下基本动画部分 基本动画部分比较简单, 但能实现的动画效果也很局限 使用方法大致为: #1. 创建原始UI或者画面 #2. 创建CABasicAnimation实例, 并设置keypart/dur ...

随机推荐

  1. 通过yum命令只下载rpm包不安装

    方法一:yumdownloader# 如果只想通过 yum 下载软件的软件包,但是不需要进行安装的话,可以使用 yumdownloader 命令: yumdownloader 命令在软件包 yum-u ...

  2. loadrunner之录制脚本

    LoadRunner是一款性能测试软件,通过模拟真实的用户行为,通过负载.并发和性能实时监控以及完成后的测试报告,分析系统可能存在的瓶颈,LoadRunner最为有效的手段之一应该就是并发控制,通过在 ...

  3. maven常用镜像源

    <mirrors> <mirror> <id>ibiblio</id> <mirrorOf>central</mirrorOf> ...

  4. 廖雪峰python教程

    来源于廖雪峰博客园python教程 8-25 编程语言分类 机器语言 计算机内部只能接受二进制代码,用二进制代码0和1描述的指令称为机器指令,全部机器指令的集合构成计算机的机器语言,用机器语言编程的程 ...

  5. 调用搜狐js接口获取客户端IP及省分城市

    <!-- 引入,搜狐IP地址查询接口(默认GBK) --> <!-- <script src="http://pv.sohu.com/cityjson"&g ...

  6. Flink模式

    Per-job Cluster 该模式下,一个作业一个集群,作业之间相互隔离. 在Per-Job模式下,集群管理器框架用于为每个提交的Job启动一个 Flink 集群.Job完成后,集群将关闭,所有残 ...

  7. Typora编辑区域空白过大问题

    参考博客:https://blog.csdn.net/m0_55485287/article/details/115207178 在哪个文件编辑? 1.找到使用的主题,打开主题文件夹 2.找到对应的c ...

  8. FastJson 反序列化漏洞原理分析

    Fastjson 简介 fastjson框架:https://github.com/alibaba/fastjson fastjson-jndi:https://github.com/earayu/f ...

  9. 超全!Python图形界面框架PyQt5使用指南!

    使用Python开发图形界面的软件其实并不多,相对于GUI界面,可能Web方式的应用更受人欢迎.但对于像我一样对其他编程语言比如C#或WPF并不熟悉的人来说,未必不是一个好的工具. 常见GUI框架 P ...

  10. java网络编程--2 IP,端口,通信协议,TCP/UDP对比

    java网络编程--2 IP,端口,通信协议,TCP/UDP对比 1.3.IP ip地址:InetAddress 唯一定位一台网络上的计算机 127.0.0.1 :本机localhost IP地址的分 ...