"image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20250107/25f9a2da2dd37457a0b8916a20ff6516.png) 1. 我想问下 tailwind.config.js 在vite的整个构建过程中是如何被使用的。 2.我了解到vite 是使用Es6 ,所以vite.config.js中是es6的语法。 tailwind.config.js 是 作为 npx tailwind 命令的配置文件, tailwind 是执行 tailwindcss模块下的 lib/cli.js ,这个cli.js是commonjs规范。所以tailwin.config.js应该使用commonjs规范吧? 为什么可以使用es6? 有什么参考么?
公告公告 这个代码是"index.html" 的代码,其中引入了"header.html" 文件,这个"header.html" 里面也是包含"tailwindcss" 的类名,但是使用"webpack" 打包的时候,是不会被打包进去的,这里应该是被当做 字符串处理了。 webpack config配置 const path = require("path"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { entry: { index: "./src/ts/index.ts", }, output: { path: path.resolve(__dirname, "dist"), filename: "./js/[name].js", assetModuleFilename: "./imgs/[name][ext][query]", }, plugins: [ new MiniCssExtractPlugin({ filename: "./css/style.css", }), new HtmlWebpackPlugin({ filename: "index.html", template: "./src/index.html", chunks: ["index"], }), ], module: { rules: [ { test: /\.scss$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: "../", }, }, { loader: "css-loader", options: { importLoaders: 1 }, }, "sass-loader", "postcss-loader", ], }, { test: /\.(png|svg|jpg|gif|webp)$/, type: "asset/resource", }, { test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/, }, ], }, resolve: { extensions: [".tsx", ".ts", ".js"], }, mode: "production", devServer: { client: { overlay: false, logging: "none", }, open: true, hot: true, port: 9000, }, }; 请问: webpack 如何将"raw-loader" 引入的文件里面的tailwindscss 也一起打包到新的css文件中!
如何优雅地实现图片局部预览组件? 下面是"bilibili用户头像上传" (https://link.segmentfault.com/?enc=cILJdevgB%2Ba74Eb%2FpXXOww%3D%3D.2ZtA42N7SwiXfvc3VGpBKuALaguBU4%2Bt%2ByQClylY4tF3JN3FyaC%2BP1TmBUiiSKtFKCSelalRQ9OIEva%2Fj3Ikyw%3D%3D)的界面,左侧我们可以通过移动选择框和缩放选择框来选择图片的某一部分,右侧是头像预览。 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240930/f1a895ce7a04bcfd84380447d9c376f5.png) 我自己尝试使用"react+tailwindcss"来实现了一下,但是实现的并不太理想。 * 通过四个角来缩放的效果并不好。有时候没有反应,有时候又突然之间变换很大。 * 应该是当我按下鼠标之后,抬起鼠标之前,才能移动和缩放选择框。但是有时候,抬起了依然可以移动选择框。 * 鼠标移动操作的速度一快,就会出现一些意料之外的效果(如前两条所示)。 * 性能也不太好,处理了太多的"mousemove"事件了(可以考虑加上防抖?)。 可以在我实现的基础上给出一些改进建议或者直接重新给出一个新的方案。希望可以尽可能详细,有完整的代码,最终的效果可以交互。 简要说明一下我的实现思路: HTML结构 * "image"和"选择框"为兄弟元素。它们的父元素为"相对定位",选择框为"绝对定位"。父元素的宽度固定,"image"的最大宽度为"100%",父元素的高度由"image"的大小决定。 * "选择框"中有四个元素,分别表示四个角上的小方框,采用的也是"绝对定位" setPress({ ...press, topLeft: true })} > setPress({ ...press, topRight: true })} > setPress({ ...press, bottomLeft: true })} > setPress({ ...press, bottomRight: true })} > 状态 * 鼠标是否在选择框中按下。用一个对象来记录,并设置了5个属性,以区分按下的位置。根据按下的位置不同,鼠标移动操作时的行为也不同,是移动选择框还是缩放选择框,缩放的话该怎么缩放。 * 鼠标的位置。通过记录相邻两次鼠标的位置并计算其差值来决定选择框应移动多远的距离。 * "imagRef"用来获取图片渲染之后的"width"、"height"、"naturalWdith"、"naturalHeight",在计算图片缩放比例、选择框越界判断的时候有用。 * "selectorRef"获取选择框的"width"和"height"。const [press, setPress] = React.useState({ topLeft: false, topRight: false, bottomLeft: false, bottomRight: false, other: false, }); const [mousPosition, setMousePosition] = React.useState(null); const [selector, setSelector] = React.useState({ x: 0, y: 0, width: null, height: null, }); const imgRef = React.useRef(); const selectorRef = React.useRef(); 事件处理函数 * "mouseDownUp"重置"press"状态。 * "mouseDownKey"设置对应的"press"状态,设置鼠标的位置。 * 主要逻辑在"mouseMove"上。 * 根据按下位置的不同,更新选择框的位置和大小。 * 防止选择框越界。 * 这里的"onChange"函数主要用来设置一些用于在canvas上绘制图片时所需的信息("drawImage(img, x, y, sw, sh, dx, dy, dw, dh")。 * 设置鼠标的位置。 function handleMouseMove(event) { if (Object.values(press).every((e) => !e)) return;const { clientX, clientY } = event;const offsetX = clientX - mousPosition.x; const offsetY = clientY - mousPosition.y;let newX; let newY; let newWidth; let newHeight;if (press.topLeft) { console.log('press top left'); // bottom right don't change newX = selector.x + offsetX; newY = selector.y + offsetY; newWidth = selector.width - offsetX; newHeight = selector.height - offsetY; if (newWidth imgRef.current.width) newX = imgRef.current.width - selector.width; if (newX imgRef.current.height) newY = imgRef.current.height - selector.height; if (newY < 0) newY = 0;if (newHeight < 0) newHeight = 0; if (newWidth < 0) newWidth = 0; setSelector({ ...selector, x: newX, y: newY, width: newWidth, height: newHeight, }); onChange( imgRef.current, newX * imgRef.current.xScale, newY * imgRef.current.yScale, selector.width * imgRef.current.xScale, selector.height * imgRef.current.yScale ); setMousePosition({ x: clientX, y: clientY }); } * "stackblitz" (https://link.segmentfault.com/?enc=R7XEe8zJEdeF%2BZnUbB0leA%3D%3D.Wi1%2Be3fmEHg49jMNetZaHPWrTRoNOCc5j17U3iyThTHz5G036rIWFJHfr03H0DPULDRHmxSr%2BkQZYdL4BuWGNQ%3D%3D) * "github" (https://link.segmentfault.com/?enc=YacX4EMYJcpguUIsQ5N6vg%3D%3D.HyXu1ALUJHUBFmt76oPZTJ8f0QD5GMHDtxPzFtB9GPcEa1UJddTaLM6lkF8PieeU)
如何优雅地实现文件上传+文件夹上传+拖拽上传+进度追踪+...? 需求分析: 基础功能 * 显示 * 上传文件或文件夹的"名字"、"类型"、"大小"、"状态"。 * 类型 * 文件夹的类型可以"文件夹"或或者没有 * 文件的类型范围"MIME"。 * 大小 * 文件夹的大小为该文件夹及其子文件夹下所有文件的大小总和 * 状态 * 最少应该有的状态(假设上传一定成功,不会出现错误) * 未上传 * 上传中(当处于此状态的时候要实时显示上传进度) * 上传完成 * 其他扩展状态 * 暂停 * ... * 文件夹显示可以展开和折叠 * 上传按钮在上传中是"disabled",并且在没有文件上传的时候点击是不会触发上传的(可以在此时给出一个提醒) * 多个文件或文件夹上传 * 文件选中方式 * 通过"input[type="file"]"来选中 * 拖拽 * 进度追踪 * 一个文件的上传进度为"loaded/total"。 * 一个文件夹的上传进度为该文件夹下(包括子文件夹)的所有文件的"loaded"之和除以所有文件的"total"之和。 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240930/322e5850e479cd1272a4c9017c50d788.png) 扩展功能 * 取消某些选中的将要上传文件 * 暂停 * 可以暂停上传的文件,之后再继续上传的时候不重新开始上传而是从上传完成的部分之后上传。 * 中断重试 * 和暂停功能类似,只是这里的中断是不是人主动要求的,而是外部的一些不可预料的事件(网络中断、服务器故障..)造成的。 * 文件上传性能优化 * 大文件分片上传 * 并发上传 * .... 我自己用"react+tailwindcss"尝试勉强实现了基础功能。 维护了一个树结构来记录文件上传的状态。 其中每个节点的字段含义 * "type" * "0"表示文件, "1"表示文件夹 * "file" * "File": 对于文件来说是"File对象",记录了文件的一些信息。 * "{ name: , size: , type: "文件夹"}": 对于文件夹来说只是记录了文件夹的名字、大小和类型。 * "children": * 对于文件来说该字段是没有的。 * 对于文件夹来说它是一个数组,包含一些节点,表示该文件夹下的所有文件和文件夹。 * "parent" * "[node, idx]": "node"表示该节点的父节点,"idx"表示该节点在其父节点的"children"中位于第几个。 * 问题: 如果我们想要删除某一个节点(相当于取消某个文件的上传) * 方案1 "splice" * 其后面的兄弟节点的"parent"也要改变,所有依赖"idx"的数据也改变。 * 当我们需要恢复该节点的时候,还需要回退我们的修改(需要记住之前的"idx",否则渲染的顺序就发生变化了。) * 实现起来还是比较麻烦,但没有占据不必要的空间。 * 方案2 "假的删除" * 在其父元素的"children数组"的对应位置("idx")设置为"null",表示该节点已经被删除。 * * 恢复的时候也容易。 * 实现起来简单,但是可能浪费了一些空间,特别是当一层中文件条目比较多的时候。 * 你有什么更好的方案吗?也可以重新设计这个node,使得删除、恢复更容易,且占据的空间少。 * "null": 表明该节点为根节点。 * "progress": * "num": 对于文件来说,它就是一个数值。由"XMLHttpRequest"实例的中的"upload"对象上"progress"事件中得到的"event.target"和"event.loaded"计算而来得到。("loaded * 100 /tatoal")。 * "{loaded: [...], total: [....]}": 对于文件夹来说,我们需要统计其子节点的"loaded"和"toatal"之后再计算得到其最终的进度。 * 当一个子节点的的进度发生改变的时候,它会顺着"parent",去修改其祖先节点中"progress.loaded"和"progress.total"。(这就是我们需要"parent"字段的原因) 问题:这棵树在该"react"项目中为一个状态,应该保持它的不可变性。对于这种复杂的数据结构该怎么保持它的不可变性呢?借助"immer"? 下面为更新进度的过程,该怎么修改保持不可变性呢? // src/utils.js export function uploadProcess(uploadFileList, setUploadFileList, setStatus) { // TopNode用作哨兵,让边界条件处理更容易。 for (let i = 0; i { setUploadFileList([...uploadFileList]); }, setStatus ); } function uploadFileOrDirectory(entry, update, setStatus) { if (entry === null) return; if (entry.type === 0) { const xhr = new XMLHttpRequest(); const data = new FormData(); data.append("file", entry.file); xhr.open("POST", UPLOAD_URL); xhr.upload.addEventListener("progress", (e) => { const percent = Number(((e.loaded * 100) / e.total).toFixed(0)); entry.progress = percent; propagateProcessUpward(entry, e.loaded, e.total, setStatus); update(); }); xhr.send(data); } else { for (const e of entry.children) { uploadFileOrDirectory(e, update, setStatus); } } } function propagateProcessUpward(entry, loaded, total, setStatus) { if (entry.parent) { const [parent, idx] = entry.parent; parent.progress.loaded[idx] = loaded; parent.progress.total[idx] = total; propagateProcessUpward( parent, parent.progress.loaded.reduce((acc, cur) => acc + cur, 0), parent.progress.total.reduce((acc, cur) => acc + cur, 0), setStatus ); } else { // topNode if ( entry.progress.loaded.every( (item, idx) => entry.progress.total[idx] === item ) ) setStatus(2); } } * 我的实现一点也不优雅而且应该还有很多问题,欢迎指正。 * 如果你有更好的的方案,欢迎在解答区分享。最好有完整的代码和较为详细的思路讲解。 附: * "codesandbox" (https://link.segmentfault.com/?enc=y8sR4UCUkxcM%2FaynFrYBGw%3D%3D.JrviR7EriTZERW%2FjGEoZsAyZJuU3hmxwyq%2FRSXlX3kjmxVS86QKamOFfpYzDX%2BGtZ5PcyaEykVokJs7gykuOLiOPEi4s%2FfeZY7snYWvnf54%3D) * "github" (https://link.segmentfault.com/?enc=do3fysL86mHU98QMdfIs9w%3D%3D.VkgPCk16nxDcspwmHC1Qfyd%2FkX3eburupeH8E4EI0DUoobLYyoaGmt7%2FoNcBw2Kj)(问题可以直接在"issue"里提) * "做的一些笔记" (https://link.segmentfault.com/?enc=jxECAEYPBVRluBdlep6Lpg%3D%3D.6OFsTae%2BotLr4XKBD3pJ5TfvCvfHXg3JT%2Bx9hOM5G9YRGpNBIsyON1hsg2XPgkqZpnQsTZeX8IfZlZk6Xof587f97KUxomXw6jN%2BZbixfzR38HrdqSfidcR43RZuJKJK)
"@tailwindcss base"导入了哪些基础样式?从哪里(代码库中的哪个或哪些文件)可以获知?还是说它并没有导入任何样式,但是我们可以通过以下方式声明一些样式,然后这些样式按照"@tailwindcss"的声明顺序来应用。 @tailwindcss base; @tailwindcss components; @tailwindcss utilities; @layer base{ ... } @layer component { .... }
"https://play.tailwindcss.com/sNnjkZnGWF?file=config" (https://link.segmentfault.com/?enc=fZE3Ikf4frtIfcMLHR%2BZdQ%3D%3D.PgKFKYDpJTtvrmhURmlI0rKXlvkn6Qld0%2FQmG5wukK6Mo9kv4eIen9h3DrFGtUrO%2FWdra3NyqA8hGGmFL8H7eA%3D%3D) 项目里配置了变体 @layer utilities { .border_always { @apply border-2 border-solid border-red-500; } } addVariant('hocus', ['&:focus', '&:hover']) 确定 为什么 当button 通过tab 获取焦点的时候 红色边框border_always样式没有生效?
tailwindcss中如何自定义类名使得我们可以使用":not()"选择器? 尝试这样写"[:not(:disabled)]:hover:text-gray-400"好像没有用。
element-plus如何兼容第三方样式库tailwindcss? 我希望"tailwindcss"的样式尽可能的覆盖"element-plus"中的样式。 但事实上相同特殊度下,"element-plus"的样式覆盖了"tailwindcss"中的样式 "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/c/user/20240925/874e3f7574b0f4fef0bdb90508b386af.png) 注:在"ant design"中有专门的章节讲"样式兼容问题" (https://link.segmentfault.com/?enc=wURuicxpRW%2FRNzIFjdr5mA%3D%3D.eq4j5btdcX3AcdR7P1rR5CZLiURaMjxYoe%2Fq82QUZVuHpLXIb9tbWll2QYDW2IZzlKtUG3tgxU6P%2BMTnBpMxqH3qqVY0x4DA%2BWvcDGx1QQaGxUDqAE5W510FdNBSthrrLR6%2FrepwrZ%2Fgv2oUwscmuw%3D%3D),而"element-plus"中没有。
如题,我在 "tailwindcss" 官网中并没有找到相关解决方案。 现在的情况是我在项目根目录安装了 "tailwindcss", "postcss", "autoprefixer",并对 "tailwind.config.js" 中的 "content" 进行了修改,变成这样: export default { ..., content: ['./**/*.{vue,js,ts,jsx,tsx}'] } 这个改动在普通的 "vue" 项目中是正常生效的,因为根据文档生成了一个 "css" 文件并在 "main.ts" 引入。 *** 但是在 "workspace" 项目中,我要求在该项目的任一文件中都生效,而这个改动没有效果的原因是生成的 "tailwind css" 文件不知道放在哪里。 我尝试了在非 "packages/*" 项目中引入,正常生成了一大堆 "css" 变量,但类名不生效。 我尝试了在 "packages/*" 项目中引入,正常开发无效,而打包后则全部 "css" 都打包了,没有实现按需加载。 大佬们有没有时间指导指导?
"image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/83bbae4274c1caec8260b44148e4a0a3.png) "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/f0cafed982be25058a48d47195d85de4.png) 如图,在 monorepo 中使用了 "tailwindcss" 后作为一个案例打包,并且按需生成了 "dist/style.css" 文件,但在演示项目中引入 "css" 文件时并没有生效也没有报错。 button "image.png" (https://wmprod.oss-cn-shanghai.aliyuncs.com/images/20241126/fbce7336d035b77b48b936ec48c792d1.png) 而后在演示项目也引用 "tailwindcss" 才得以生效,但显然这并不符合需求。 希望得到的结果是演示项目不需要使用 "tailwindcss" 就能让组件库的样式生效。 问题应该如何解决? 是否是我代码或配置有问题?请求大佬支援 "Pavilion UI 项目地址" (https://link.segmentfault.com/?enc=7b4uPUV0vUUKvbcSP2iJmg%3D%3D.1Kgc42lyUSUQiDsqXe2WYMfikV0%2FzecGiZDEYDKRUDYz4Jk6EOdu92V%2BNBgrCl8c)