使用tailwindcss来构建以及引入外部组件

Image

使用tailwindcss来构建以及引入外部组件

  • 使用tailwindcss来构建以及引入外部组件
    • 前言
    • 构建组件
      • 核心思想
      • 可行方案
      • 不可行方案
    • 可行方案详解
      • custom css selector + Functions & Directives
      • add prefix
      • add scoped
      • 不打包
    • 构建demo链接
    • 相关issues

前言

我们在日常的开发中,经常会去使用和封装各种各样的组件库。有些是开源的,第三方开发的UI库,有些是我们开发人员给自己的特定的业务封装的UI库。其中很多情况其实是以流行的 开源UI库(或者fork的改版) + 自己封装的业务组件为主的

开源UI库 它们的样式相对来说是独立于整套系统的,比如它们的样式都是 ant-el- 开头的,一般引入之后不会和原先系统里的样式产生冲突。而 自己封装的业务组件,由于往往和系统高度绑定也没有这样的问题。

那么如何用 tailwindcss 来构建/发布和引入自己封装的业务组件呢?

构建组件

核心思想

首先我必须重点把本篇文章的核心思想预先抛出:

tailwindcss 只是一个css生成器,它只是帮你按照一定的规则,从你的源代码中匹配字符串去生成css。所以在用它去构建组件的时候,一定要去思考你用 tailwindcss 生成的 css 的影响范围,因为大部分用 tailwindcss 都是默认全局应用的。但是你在组件里面的自定义样式很多情况下,是没有必要的。

根据这个核心思想,我们就可以知道在封装组件时可行和不可行的方式了,大致如下:

可行方案

  1. custom css selector + Functions & Directives
  2. add prefix (添加前缀)
  3. add scoped (像 vuescoped 一样添加 data-v-[hash] 类似的自定义属性,然后去修改css选择器)
  4. 不打包方案 (不构建产物,直接发布,然后在项目里安装,再提取 node_modules 里制定的文本重新生成。)

不可行方案

  1. module css 这会去修改 css 选择器。

可行方案详解

这里我写了2个demo分别是 reactvue,其中下方代码以 vue 为示例,react示例见下方的 构建demo链接

custom css selector + Functions & Directives

这种方案其实非常的传统,仅仅使用到了 tailwindcss@applytheme 等等指令的功能。

比如我们有个组件 ApplyButton.vue,它的模板,样式和独立的 tailwind.config.js 分别如下所示:

<script setup lang="ts">
</script><template><button class="apply-button">ApplyButton</button>
</template><style src="./index.css"></style>
@config 'tailwind.config.js';
@tailwind utilities;.apply-button {@apply text-white p-4 rounded;background-color: theme("colors.sky.600")
}
const path = require('node:path')/** @type {import('tailwindcss').Config} */
export default {content: [path.resolve(__dirname, './index.vue')],// ...
}

然后在打包的时候,以这个文件或者导出文件(index.ts) 为打包入口即可。

这样它的产物css中,选择器由于是你自己定义的,就能尽可能保证它是独一无二的。

它对应的css产物为:

.apply-button {border-radius: 0.25rem;--tw-bg-opacity: 1;background-color: rgb(2 132 199 / var(--tw-bg-opacity));padding: 1rem;--tw-text-opacity: 1;color: rgb(255 255 255 / var(--tw-text-opacity));
}

add prefix

这个也很好理解,前缀嘛,各个UI库都是这样搞的,我们就可以创建出以下的代码:

<script setup lang="ts">
</script><template><button class="ice-bg-sky-600 ice-text-white ice-p-4 ice-rounded">PrefixButton</button>
</template><style>
@config 'tailwind.config.js';
@tailwind utilities;
</style>
const path = require('node:path')/** @type {import('tailwindcss').Config} */
export default {prefix: 'ice-',content: [path.resolve(__dirname, './index.vue')],
}

它对应的css产物为:

.ice-rounded {border-radius: 0.25rem;
}
.ice-bg-sky-600 {--tw-bg-opacity: 1;background-color: rgb(2 132 199 / var(--tw-bg-opacity));
}
.ice-p-4 {padding: 1rem;
}
.ice-text-white {--tw-text-opacity: 1;color: rgb(255 255 255 / var(--tw-text-opacity));
}

add scoped

这个就是通过同时添加html标签属性和修改css选择器来做的了:

<script setup lang="ts">
</script><template><button class="bg-sky-600 text-white p-4 rounded">ScopedButton</button>
</template><style scoped>
@config 'tailwind.config.js';
@tailwind utilities;
</style>

这里仅仅给 style 加了一个 scoped 属性

const path = require('node:path')/** @type {import('tailwindcss').Config} */
export default {content: [path.resolve(__dirname, './index.vue')],
}

css 生成结果为:

.rounded[data-v-10205a53] {border-radius: 0.25rem;
}
.bg-sky-600[data-v-10205a53] {--tw-bg-opacity: 1;background-color: rgb(2 132 199 / var(--tw-bg-opacity));
}
.p-4[data-v-10205a53] {padding: 1rem;
}
.text-white[data-v-10205a53] {--tw-text-opacity: 1;color: rgb(255 255 255 / var(--tw-text-opacity));
}

不打包

以上三种方式总结一下,都是通过在选择器上下功夫来制作组件库的,而且它们都有一个打包的过程,即 src->dist 然后发布 dist

可是这第四种方案就不怎么一样了: 核心就是 不打包

即我们写好组件之后,直接把 npm的入口文件,指向 src ,然后直接把里面的组件发布(比如直接发布 vue组件)

这种情况下,你需要让你在 node_modules 里的组件再次经受一遍 js 的处理,比如 vue sfc compiler,babel,swc等等。

同时你也需要配置你项目里的 tailwind.config.js 去提取你 node_modules 里的组件源代码内容:

module.exports = {content: ['./index.html','./src/**/*.{html,js,ts,jsx,tsx,vue}',
+   './node_modules/mypkg/src/components/**/*.{html,js,ts,jsx,tsx,vue}']
}

这样才能重新提取生成 css 在项目主css chunk里。

构建demo链接

https://github.com/sonofmagic/weapp-tailwindcss/tree/main/how-to-build-components-by-tailwindcss

相关issues

https://github.com/sonofmagic/weapp-tailwindcss/issues/247

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/101603.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1、AM64xx的SDK重新编译lib文件

当需要修改AM64XX的SDK提供的源文件时&#xff0c;如果要在自己的工程使用&#xff0c;需要重新编译出lib&#xff0c;下面是编译lib的具体方法&#xff1a; 因为没有ccs编译出lib的工程&#xff0c;所以需要再命令行模式下生成lib文件 1、配置好gmake环境 如果安装了ccs&am…

隔离上网,安全上网

SDC沙盒数据防泄密系统&#xff08;安全上网&#xff0c;隔离上网&#xff09; •深信达SDC沙盒数据防泄密系统&#xff0c;是专门针对敏感数据进行防泄密保护的系统&#xff0c;根据隔离上网和安全上网的原则实现数据的代码级保护&#xff0c;不会影响工作效率&#xff0c;不…

SP605官方开发板不能扫到链的问题

很早之前的板子&#xff0c;近些天需要重新搞FPGA&#xff0c;所以又拿出来&#xff0c;应该以前都是在win7下开发&#xff0c;现在都win10了&#xff0c;vivado都不支持sp6&#xff0c;所以先得下载一个14.7版本&#xff0c;但是出现了新的问题&#xff0c;就是不能扫到链。 …

本文整理了Debian 11在国内的几个软件源。

1&#xff0e;使用说明 一般情况下&#xff0c;将/etc/apt/sources.list文件中Debian默认的软件仓库地址和安全更新仓库地址修改为国内的镜像地址即可&#xff0c;比如将deb.debian.org和security.debian.org改为mirrors.xxx.com&#xff0c;并使用https访问&#xff0c;可使用…

sqli-lab靶场通关

文章目录 less-1less-2less-3less-4less-5less-6less-7less-8less-9less-10 less-1 1、提示输入参数id&#xff0c;且值为数字&#xff1b; 2、判断是否存在注入点 id1报错&#xff0c;说明存在 SQL注入漏洞。 3、判断字符型还是数字型 id1 and 11 --id1 and 12 --id1&quo…

智能工业通信解决方案!钡铼BL124实现Modbus转Ethernet/IP互联!

钡铼技术BL124 Modbus转Ethernet/IP协议网关是一款专为工业自动化领域而设计的先进设备。它提供了可靠的通信解决方案&#xff0c;能够将Modbus通信协议与Ethernet/IP通信协议进行高效转换&#xff0c;实现不同类型设备之间的无缝集成和通信。 添加图片注释&#xff0c;不超过 …

【AI】深度学习——前馈神经网络——全连接前馈神经网络

文章目录 1.1 全连接前馈神经网络1.1.1 符号说明超参数参数活性值 1.1.2 信息传播公式通用近似定理 1.1.3 神经网络与机器学习结合二分类问题多分类问题 1.1.4 参数学习矩阵求导链式法则更为高效的参数学习反向传播算法目标计算 ∂ z ( l ) ∂ w i j ( l ) \frac{\partial z^{…

前端预览、下载二进制文件流(png、pdf)

前端请求设置 responseType: “blob” 后台接口返回的文件流如下&#xff1a; 拿到后端返回的文件流后&#xff1a; 预览 <iframe :src"previewUrl" frameborder"0" style"width: 500px; height: 500px;"></iframe>1、预览 v…

理解http中cookie!C/C++实现网络的HTTP cookie

HTTP嗅探&#xff08;HTTP Sniffing&#xff09;是一种网络监控技术&#xff0c;通过截获并分析网络上传输的HTTP数据包来获取敏感信息或进行攻击。其中&#xff0c;嗅探器&#xff08;Sniffer&#xff09;是一种用于嗅探HTTP流量的工具。 在HTTP嗅探中&#xff0c;cookie是一…

【Redis】Redis性能优化:理解与使用Redis Pipeline

原创不易&#xff0c;注重版权。转载请注明原作者和原文链接 文章目录 Pipeline介绍原生批命令(MSET, MGET) VS PipelinePipeline的优缺点一些疑问Pipeline代码实现 当我们谈论Redis数据处理和存储的优化方法时&#xff0c;「 Redis Pipeline」无疑是一个不能忽视的重要技术。…

Transformer预测 | Pytorch实现基于Transformer的时间序列预测(含单步与多步实验)

文章目录 效果一览文章概述模型描述程序设计单步实验多步实验参考资料效果一览 文章概述 Transformer预测 | Pytorch实现基于Transformer的时间序列预测(含单步与多步实验) Transformer-singlestep.py 包含单步预测模型 Transformer-multistep.py 包含多步预测模型 这是单步预…

基于ChatGPT+词向量/词嵌入实现相似商品推荐系统

最近一个项目有个业务场景是相似商品推荐&#xff0c;给一个商品描述(比如 WIENER A/B 7IN 5/LB FZN )&#xff0c;系统给出商品库中最相似的TOP 5种商品&#xff0c;这种单纯的推荐系统用词向量就可以实现&#xff0c;不过&#xff0c;这个项目特点是商品库巨大&#xff0c;有…

Python爬虫(二十二)_selenium案例:模拟登陆豆瓣

本篇博客主要用于介绍如何使用seleniumphantomJS模拟登陆豆瓣&#xff0c;没有考虑验证码的问题&#xff0c;更多内容&#xff0c;请参考&#xff1a;Python学习指南 #-*- coding:utf-8 -*-from selenium import webdriver from selenium.webdriver.common.keys import Keysimp…

材质、纹理、贴图的区别和关联

1、材质、纹理、贴图的概念 材质&#xff08;Material&#xff09;、纹理&#xff08;Texture&#xff09;、贴图&#xff08;Texture Map&#xff09;是计算机图形学中的三个概念&#xff0c;它们之间存在关系但也有一些区别。 材质&#xff08;Material&#xff09;是描述物…

算法进阶——字符串的排列

题目 输入一个长度为 n 字符串&#xff0c;打印出该字符串中字符的所有排列&#xff0c;你可以以任意顺序返回这个字符串数组。 例如输入字符串ABC,则输出由字符A,B,C所能排列出来的所有字符串ABC,ACB,BAC,BCA,CBA和CAB。 数据范围&#xff1a;n<10 要求&#xff1a;空间复…

设计模式 - 中介者模式

目录 一. 前言 二. 实现 三. 优缺点 一. 前言 中介者模式又叫调停模式&#xff0c;定义一个中介角色来封装一系列对象之间的交互&#xff0c;使原有对象之间的耦合松散&#xff0c;且可以独立地改变它们之间的交互。 中介者模式可以使对象之间的关系数量急剧减少&#xff0…

nginx开启https配置之后网页无法访问问题处理

背景说明 最近新购服务器部署nginx之后按照之前的方式部署前端项目并配置https之后访问页面显示:无法访问.新的服务器ECS系统和之前相同,nginx安装方式也相同,nginx配置方式也是相同.但是访问还是显示无法访问.下面简单记录一下问题处理过程. 处理过程 1.https访问之后无法访问…

php+html+js+ajax实现文件上传

phphtmljsajax实现文件上传 目录 一、表单单文件上传 1、上传页面 2、接受文件上传php 二、表单多文件上传 1、上传页面 2、接受文件上传php 三、表单异步xhr文件上传 1、上传页面 2、接受文件上传php 四、表单异步ajax文件上传 1、上传页面 2、接受文件上传ph…

Day-08 基于 Docker安装 Nginx 镜像-负载均衡

1、反向代理后&#xff0c;自然而然就引出了负载均衡,下面简单实现负载均衡的效果; 2、实现该效果需要再添加一个 Nginx &#xff0c;所以要增加一个文件夹。 /home|---mutou|----nginx|----conf.d|----html|----conf.d2|----html3 1.创建 html3 文件夹&#xff0c; 新建 index…

CART 算法——决策树

目录 1.CART的生成&#xff1a; &#xff08;1&#xff09;回归树的生成 &#xff08;2&#xff09;分类树的生成 ①基尼指数 ②算法步骤 2.CART剪枝&#xff1a; &#xff08;1&#xff09;损失函数 &#xff08;2&#xff09;算法步骤&#xff1a; CART是英文“class…