使用 UnoCSS shortcuts 简化 class

UnoCSS 确实简化了不少样式书写、也降低了 CSS 打包体积,提升了样式使用率。但样式太多的话,class 也写得多,比较费眼。所幸,UnoCSS 提供了 shortcuts 来简化 class,并且可以通过 js 来控制样式的输出,灵活度非常高。

shortcuts 与 rules 不同的是,rules 只可以写 CSS 属性/值,shortcuts 是提高 rules 的利用率,且降低写太多重复的 class。

shortcuts 有动态和静态,我推荐多用动态的。我就直接丢上官方文档给出的静态 shortcuts 例子:

shortcuts: {
  // shortcuts to multiple utilities
  'btn': 'py-2 px-4 font-semibold rounded-lg shadow-md',
  'btn-green': 'text-white bg-green-500 hover:bg-green-700',
  // single utility alias
  'red': 'text-red-100'
}

下面是我写的动态 shortcuts,目的是简化 flex、items-xxx、content-xxx、justify-xxx 的使用:

const shortcuts = <UserShortcuts>[
  [
    /^f-((c|s|e)(-(c|s|e|b))*)$/,
    ([, group1, group2, group3, group4]) => {
      const matches = [
        { prefix: "c", value: "center" },
        { prefix: "s", value: "start" },
        { prefix: "e", value: "end" },
        { prefix: "b", value: "between" }
      ];

      if (group4) {
        let style = ``;

        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group2) {
            style += `flex items-${matches[i].value} content-${matches[i].value}`;
          }
        }

        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group4) {
            style += ` justify-${matches[i].value}`;
          }
        }

        return style;
      } else {
        for (let i = 0; i < matches.length; i++) {
          if (matches[i].prefix === group2) {
            return `flex items-${matches[i].value} content-${matches[i].value}`;
          }
        }
      }
    }
  ]
];

代码没有做优化。动态 shortcuts 包含多个数组元素,元素包含两个子元素。第一个元素是正则表达式;第二个是正则表达式匹配的结果。正则表达式匹配至少一个组,比如我写的正则表达式可视化图:

image

这个正则表达式匹配了四个组,而我需要的是 组2 和 组4。所以,我不需要([, group1, group2, group3, group4]) => { return "" }总的 group1、group3,而是 group2 和 group4 匹配的值,动态设置 rules。下面是使用案例,在 class 中写 f-c-s 就可以用上 flex 相关的样式:

image

并且支持匹配 f-c,该 shortcuts 不使用 justify-content 样式:

image

总结:shortcuts 获取匹配的值与正则表达式匹配的组有关系,一一对应的关系。

本文转载于网络 如有侵权请联系删除

相关文章

  • Windows 设置 Python 脚本开机自启的一些心得

    前言最近遇到一个需求,需要监测键盘输入,将其输出到指定的文件中保存,代码本身不复杂,但是配置脚本在Windows环境中自启的时候遇到了一些麻烦。脚本代码frompynput.keyboardimportListener,Key importlogging fromdatetimeimportdate directory=f"D:/key"//日志文件保存路径 today=str(date.today()) logging.basicConfig(filename=f"{directory}/{today}log.txt",level=logging.DEBUG,format="[%(asctime)s]:%(message)s") defon_press(key): logging.info(key) defon_release(key): pass withListener(on_press=on_press,on_release=on_release)aslistener: listener.join()复制

  • 2021年大数据Spark(四十五):Structured Streaming Sources 输入源

    Sources输入源从Spark2.0至Spark2.4版本,目前支持数据源有4种,其中Kafka数据源使用作为广泛,其他数据源主要用于开发测试程序。文档:http://spark.apache.org/docs/2.4.5/structured-streaming-programming-guide.html#input-sources     可以认为StructuredStreaming=SparkStreaming+SparkSQL,对流式数据处理使用SparkSQL数据结构,应用入口为SparkSession,对比SparkSQL与SparkStreaming编程: SparkStreaming:将流式数据按照时间间隔(BatchInterval)划分为很多Batch,每批次数据封装在RDD中,底层RDD数据,构建StreamingContext实时消费数据; StructuredStreaming属于SparkSQL模块中一部分,对流式数据处理,构建SparkSession对象,指定读取Stream数据和保存Streamn数据,具体语法格式:静态数据读取spark.read

  • LeetCode 0181 - Employees Earning More Than Their Managers

    EmployeesEarningMoreThanTheirManagersDesicriptionTheEmployeetableholdsallemployeesincludingtheirmanagers.EveryemployeehasanId,andthereisalsoacolumnforthemanagerId.+----+-------+--------+-----------+ |Id|Name|Salary|ManagerId| +----+-------+--------+-----------+ |1|Joe|70000|3| |2|Henry|80000|4| |3|Sam|60000|NULL| |4|Max|90000|NULL| +----+-------+--------+-----------+复制GiventheEmployeetable,writeaSQLquerythatfindsoutemployeeswhoearnmorethantheirmanagers.Fortheabovetable,Joeistheonlyemployeewhoear

  • 开源项目介绍 |TNN-跨平台AI推理框架

    2021腾讯犀牛鸟开源人才培养计划开源项目介绍滑至文末报名参与开源人才培养计划提交项目ProposalTNN项目介绍    标签:人工智能    技术栈:C++,PythonTNN-跨平台AI推理框架, 跨平台AI推理框架,同时拥有跨平台、高性能、模型压缩、代码裁剪等众多突出优势。同时也借鉴了业界主流开源框架高性能和良好拓展性的优点。目前TNN已经在腾讯业务手Q、微视、P图等广泛落地应用,欢迎大家参与协同共建,促进TNN推理框架进一步完善。TNN项目导师介绍姚达、田恒锋、王星晨姚达,TNN框架技术负责人田恒锋,TNN框架CPU侧架构师王星晨,TNN框架CPU侧架构师导师寄语:“AI推理优化是一套系统工程,希望通过TNN相关辅导,能够帮助学员在硬件架构、应用框架等方向提升发现问题、解决问题的能力”——姚达“TNN专注于深度学习推理部署,其中GPU在整个深度学习框架中占据了重要位置。希望通过相关辅导以及开源实践,帮助学员熟悉和提升GPU编程和性能调优经验,提升在整个开源社区和行业影响力。”——田恒锋“TNN是一个跨平台高性能的推理框架,通过相关实践你将了解到AI算法落地的详细过程,以及如何

  • 前端:从状态管理到有限状态机的思考

    1.状态管理 在我们前端开发中,一定会接触现在最热门的几大框架(Vue,React等等),在使用框架的过程中,我们一定会接触某些状态管理工具。 Vue我们会使用Vuex来管理全局状态,React会使用Redux来管理。首先是不是,在问为什么?在使用类似Vue,React框架时,我们一定会使用状态管理吗?这个答案是肯定的。或许我不会主动去使用Vuex,Redux,但我们编写每一个组件的时候就已经在管理状态,Vuex,Redux只是更方便我们进行全局的状态管理。为什么一定会使用状态管理?这是因为现代前端框架使用数据驱动视图的形式来描述页面。比如,Vue、React组件会有一个自己内部,外部的状态来共同决定组件的如何显示的,用户与组件交互导致数据变更,进而改变视图。框架内部状态外部状态VuedatapropsReactstate,useStateprops所以我们所写大部分业务逻辑,是在管理状态,框架会帮我们状态映射成视图,这可以说是很经典的MVVM模式。View=ViewModel(Model); //视图=状态+管理 复制代码 复制2.有限状态机:计算机中一种用来进行对象行为建模的工具其

  • c++对象特性和this指针

    对象特性:成员变量和成员函数分开存储#include<iostream> usingnamespacestd; classwood{ public: intnum;//非静态成员变量,属于类的对象上 voidfunc(){}//非静态成员函数,不属于类的对象上 staticinta;//静态成员变量,共享一份,不属于类的对象上 staticvoidfun(){}//静态成员函数,共享一份,不属于类的对象上 }; intmain() { woodd; //空对象占用内存空间:1 //是为了区分空对象占内存的位置 cout<<sizeof(d)<<endl; //当有了非静态成员变量num是,占用内存:4 cout<<sizeof(d)<<endl; //当再添加一个func函数后,占内存不变,因为成员函数和成员函数分开存储 cout<<sizeof(d)<<endl; //静态成员变量不是内对象,不算类对象内存大小 cout<<sizeof(d)<&l

  • 通过智能投放与触发,提高广告投放效率,告别无效营销

    作者:盒子菌对于品牌主来说,做投放决策时最关注的就是自己的目标群体是哪些人,如何选择渠道才能覆盖到目标人群,投放的时长和频率又该如何依据人群特性进行配置。而过去,这些投放决策大多依据阶段性流量监测和营销人员的个人经验,这就带来“转化少,成本高,效果不稳定“等令人头大的问题。究其原因,主要是因为营销人员对用户的需求认知有着错误理解,没有在合适的时间把消息推送给合适的对象。此时,如果能够做到“精准投放”并有效触达有需求的用户,或许就能打破无效营销的“魔咒”。一、数字技术赋能将成为智能投放与触发的关键随着网络人口红利的消失、移动互联网技术的成熟、传统产业与互联网的互相渗透,营销下半场的大幕已然掀起。在这样的背景下,如果仅仅依赖传统模式,投入大量人力和时间去进行测试调优,广告主不仅耗时耗力,效果也难以保障。换句话说,如果你有以下要求:· 发现某个标签的人群效果好,想扩大该类人群的投放?· 不想浪费广告费,如何屏蔽某个无效标签人群?· 各个渠道都有零散的数据,如何高效管理最大化数据价值?· 没做过广告监测,没有第一方数据,想定向投放?· 或者只是想把广告送到目标用户的手里……那么,你需要数字技术

  • 4分+基于SEER数据库子宫内膜癌预后预测模型

    大家好,这次给大家分享的文献是NomogramsforPredictingCancer-SpecificandOverallSurvivalAmongPatientsWithEndometrialCarcinoma:ASEERBasedStudy,2020年3月发表在Front.Oncol.杂志上,影响因子4.137。同样是基于seer数据库的数据,对子宫内膜癌患者肿瘤特异性生存率和总生存率相关临床特征进行研究。研究思路从SEER数据库中提取1988年至2015年间63729例子宫内膜癌患者的数据。利用X-tile软件对患者的年龄、肿瘤大小、诊断年份和不同临床分期下的诊断年份进行划分(图2、3)。采用单因素和多因素Cox回归分析筛选有意义的独立预后因素。利用这些因素构建子宫内膜癌患者的列线图模型、3年和5年肿瘤特异性生存率和总生存率的生存预测工具。子宫内膜癌患者数据筛选流程如图1所示。图1图2图31.患者基本信息根据纳入和排除标准,共有63729名子宫内膜癌患者纳入本研究(1988-2015)。将患者分为训练组(n=42486)和试验组(n=21243)。患者基本情况见表1。两组间所有

  • 产业安全专家谈丨企业如何应用“联邦学习”打破数据孤岛,助力业务创新?

    随着云计算和大数据技术的不断发展,以人工智能为基础的数据分析与数据挖掘让大数据释放出巨大价值,已成为企业业务创新、业绩增长的重要手段。然而,企业在现实中的数据利用却困难重重,在数据价值开发中,企业究竟面临哪些痛点?企业如何打破困局,充分发挥大数据的潜在价值,助力业务创新?由腾讯安全联合云+社区打造的「产业安全专家谈」第十七期邀请到腾讯安全大数据创新中心负责人罗松为大家解析企业数据应用的现实路径。Q1:产业互联网时代,数据在业务发展中越来越重要,企业在数据应用中有哪些痛点?罗松:企业数据应用最大的痛点是数据共享需求与数据隐私之间的矛盾。随着科技的发展、业务的创新,很多企业产生了大量数据。但在企业之间,甚至企业内部,数据之间常常彼此割裂,存在明显的“数据孤岛”的现象。不论对大企业还是小企业,为了提升业务质量,提高基于数据的决策能力,从而取得竞争性优势,就对在内外部进行数据融合产生了较大的需求。但是一个现实的问题是,整个社会对隐私保护越来越关注,监管对使用数据的要求也越来越严格。在这种情况下,企业急需有一套比较好的技术和方案,在隐私保护和数据合规的情况下进行内外部的大数据合作,这也是我们推出

  • Python 自动化运维 nmap

     1.对端口扫描,查看端口状态 2.实例import sys import nmap scan_row = []     input_data = raw_input("PLEASE INPUT: ") scan_row = input_data.split(" ") if len(scan_row) != 2:     print ("error")     sys.exit(0) hosts = scan_row[0]  ##输入的主机 port = scan_row[1]   ##输入的端口 try:     nm = nmap.PortScanner()  ##实例化扫描对象 except nmap.PortScannerError:         print ("Nmap not",sys.exc_info()[0])     sys.exit(0) except:     print ("unexpecterd Error:",sys.exc_info()[0])   

  • Java 面试题问与答:编译时与运行时?

    在开发和设计的时候,我们需要考虑编译时,运行时以及构建时这三个概念。理解这几个概念可以更好地帮助你去了解一些基本的原理。下面是初学者晋级中级水平需要知道的一些问题。Q.下面的代码片段中,行A和行B所标识的代码有什么区别呢?publicclassConstantFolding{ staticfinalintnumber1=5; staticfinalintnumber2=6; staticintnumber3=5; staticintnumber4=6; publicstaticvoidmain(String[]args){ intproduct1=number1*number2;//lineA intproduct2=number3*number4;//lineB } }复制 A.在行A的代码中,product的值是在编译期计算的,行B则是在运行时计算的。如果你使用Java反编译器(例如,jd-gui)来反编译ConstantFolding.class文件的话,那么你就会从下面的结果里得到答案。publicclassConstantFolding { staticfi

  • 一文了解人脸识别:从实现方法到应用场景都讲明白了

    导读:在本文中,我们将会接触到一个既熟悉又陌生的概念——人脸识别。之所以熟悉,是因为人脸识别技术在我们日常生活中应用极其广泛,例如火车站刷脸验票进站、手机人脸解锁等;之所以陌生,是因为我们可能并不了解人脸识别的原理,不了解人脸识别的任务目标、发展历程与趋势。那么,在本文中,我们将会对人脸识别技术的概念、应用、目标等做简要介绍,以便读者对这项技术有一个立体的认识。作者:王天庆如需转载请联系大数据(ID:hzdashuju)人脸识别技术是如今十分热门的一项技术,掌握人脸识别技术的优势不言而喻。下面,我们将首先介绍人脸识别的基本概况。01何为人脸识别人脸识别技术由来已久,这个概念没有一个严格的定义,一般有狭义与广义之分。狭义的表述一般是指:以分析与比较人脸视觉特征信息为手段,进行身份验证或查找的一项计算机视觉技术。从表述上看,狭义的人脸识别技术其实是一种身份验证技术,它与我们所熟知的指纹识别、声纹识别、指静脉识别、虹膜识别等均属于同一领域,即生物信息识别领域。因此,狭义上的人脸识别一般指的是通过人脸图像进行身份确认或查找的场景。生物信息识别的认证方式与传统的身份认证方式相比,具有很多显著优势

  • POJ 3041 Asteroids(匈牙利算法)

        题意就是有一个地图,然后给你几个点的坐标标记为'x',然后你有一个武器,每次可以消灭一行或一列的'x',问最少需要几次能把所有的'x'消灭完。然后我们可以构建一个二分图,然后这就是一个最小覆盖集问题,最小覆盖数=最大匹配数,根据匈牙利算法就能求了。先上代码,以后再补详细的解释。AC代码:#include<iostream> #include<cstdio> #include<cstring> usingnamespacestd; intb[10005]; intvis1[10005]; intvis[10005][10005]; intn,m,sum; boolFind(intx){ for(inti=1;i<=n;i++){ if(vis[x][i]&&!vis1[i]){ vis1[i]=1; if(b[i]==0||Find(b[i])){ b[i]=x; returntrue; } } } returnfalse; } intmain() { sca

  • 一个Angular 5教程:一步一步指导实现你的第一个Angular 5应用程序

    前言上周由于收到是开工第一天,就拖到这周了,最终没能发布这篇。现在抓紧时间弥补上。原文:AnAngular5Tutorial:StepbyStepGuidetoYourFirstAngular5App 作者:SERGEYMOISEEV-正文现在我们可以app.component.html用这个替换:Angular是由Google开发的AngularJS框架的新版本。它带有一个完整的重写,以及各种改进,包括优化构建和更快的编译时间。在这个Angular5教程中,我们将从头开始构建一个笔记应用程序。如果您一直在等待学习Angular5,本教程适合您。应用程序的最终源代码可以在这里找到。这个框架有两个主要版本:AngularJS(版本1)和Angular(版本2+)。从版本2开始,Angular不再是一个JavaScript框架,所以它们之间有很大的区别,保证了一个基本的名称变更。我应该使用Angular吗?这取决于有些开发人员会告诉你最好使用React并在没有额外代码的情况下构建自己的组件。但这也可能是一个问题。Angular是一个完全集成的框架,可以让您快速开始项目工作,无需考虑选择哪个

  • 根据 hades接口信息,做成树形表;再将相关数据显示出来

    hades是根据python2.7下的django下开发的运维管理系统相关数据的显示树形目录#!/usr/bin/envpython #-*-coding:utf-8-*- #@Time:17/8/15下午1:16 #@Author:lee #@File:test.py #@Software:PyCharm #说明:输入IP或者是Cxx得到详细信息例如:C0751 importrequests importjson importre importsys regex_XXX=re.compile(r"[CLSND]\d\d\d\d")#匹配规则 regex_IP=re.compile(r"\d+\.\d+\.\d+\.\d+")#匹配ip classCmdb_hades(object): def__init__(self,key): self.key=key self.flag2=0 #hades_ip_cid该方法可以获取IP或者CXX对应的数据 defhades_ip_cid(self,name): try: #regex_XXX.matc

  • 携程吴毅挺:OpenStack是开源IaaS平台大势所趋的集大成者

    携程技术中心作为大中华区开源云计算平台OpenStack应用的特邀代表参加2013中国香港Openstack峰会后,携程云平台研发总监吴毅挺近日又作为主要分享嘉宾,参与了“第六届中国云计算大会-OpenStack企业应用之路技术培训”并接受CSDN专访。 吴毅挺,携程云平台研发总监从零开始团队组建,基于OpenStack研发携程私有云,用于管理携程所有的开发、测试、以及生产环境和呼叫中心基础设施;包括VMware/KVM虚拟化管理,物理服务器自动化部署,为超过万人的呼叫中心提供虚拟桌面;毕业于浙江大学,曾在eBay和百度工作。CSDN:您是怎样开始研究并推广OpenStack的? 吴毅挺:2012年7月加入携程后,开始着手私有云平台的建设和团队组建,当时对比了OpenStack/CloudStack/OpenNebula等开源IaaS平台,经过部署测试、源代码阅读、架构调研等,最终选择了OpenStack,因为我们觉得OpenStack才是开源IaaS平台大势所趋的集大成者。 我们基于G版本做二次开发,为Nova增加了基于Razor的BareMetalDriver,已经应用在多个数据中

  • 拉链表实现及使用

    一、概念历史拉链表,就是记录一个事务从开始一直到当前状态的所有变化的信息,拉链表可以避免按每一天存储所有记录造成的海量存储问题,同时也是处理缓慢变化数据的一种常见方式。假设企业拥有1000万的会员信息,每天有20万的会员资料变更,我们需要记录所有会议的历史变化记录,并至少保留两年,该怎么办?储存两年就是2x365x1000万=7300000000(70亿),如果储存更长时间,则无法估算需要的存储。而用拉链表存储,每日只向表中新增和变化的数据量,每日不过20万条,储存2年也只需要2x365*200000=146000000(1.46以)存储空间。二、案例设计–创建用户信息的原始表droptablet_userinfo_src;createtablet_userinfo_src(user_idint,user_namecharactervarying,user_nointeger,phone_nocharactervarying,create_datedate,update_datedate)distributebyhash(user_id);–创建目标拉链表droptablet_user

  • 诡异的bug异常,(__debugbreak()语句或类似调用)

    楔子项目里面出现一种奇怪的Bug,直接Debug的时候能正常运行,编译的可执行文件也完全没有问题。当逐步断点调试到某一行到时候,却出现了错误。这个奇怪的错误,搞笑的吗?异常地方如下堆栈信息如下 KernelBase.dll!wil::details::DebugBreak(void) 未知 > coreclr.dll!CHECK::Setup(constchar*message,constchar*condition,constchar*file,intline)行 C++ coreclr.dll!CLRVectoredExceptionHandlerPhase3(_EXCEPTION_POINTERS*pExceptionInfo)行 C++ coreclr.dll!CLRVectoredExceptionHandlerPhase2(_EXCEPTION_POINTERS*pExceptionInfo)行 C++ coreclr.dll!CLRVectoredExceptionHandler(_EXCEPTION_POINTERS*pExceptionInfo)行 C++

  • http 4中 cache 头

    //head['Cache-Control']='max-age=31536000'; //head['Expires']=newDate((newDate().getTime()+99999999)).toGMTString();//head['Last-Modified']=newDate((newDate().getTime())).toGMTString();//在浏览器第一次请求某一个URL时,服务器端的返回状态会是200,内容是你请求的资源,同时有一个Last-Modified的属性标记(HttpReponseHeader)此文件在服务期端最后被修改的时间,格式类似这样://Last-Modified:Tue,24Feb200908:01:04GMT//客户端第二次请求此URL时,根据HTTP协议的规定,浏览器会向服务器传送If-Modified-Since报头(HttpRequestHeader),询问该时间之后文件是否有被修改过://If-Modified-Since:Tue,24Feb200908:01:04GMT     //head['etag

  • 关于IDE对EventEmitter()没有自动提示这件事

    我原本怀疑是IDEA的问题,但是切换成WebStorm之后仍然也无法自动提示。 我还以为EventEmitter不是angular的core包下,需要我导入其他什么,后来百度了下发现它是在angular的core模块下的。 手动导入模块,发现可以正常使用,只不过编辑的时候没有自动提示补全。 另外,手打newEventEmitter()结束之后,会发现有ts的提示,说可以从angular/core中引入。       写在最后:我之前不知道EventEmitter是angular的core模块下的,我还以为是其他第三方的……如果是angular自身的话,那么肯定可以先手动导入,就好比jdk的java.lang,java.util之类的,不是说IDE没有提示就没有了。有些时候IDE可能会识别不了某些东西,看起来是红色的,但不代表编译不会通过。按照自己的正常理解手写一遍,不要管IDE的提示就好了。

  • 四、适配器(Adapter)

    将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 Spring中在对于AOP的处理中有Adapter模式的例子,见如下图: 由于Advisor链需要的是MethodInterceptor(拦截器)对象,所以每一个Advisor中的Advice都要适配成对应的MethodInterceptor对象。

相关推荐

推荐阅读