Tailwind介绍 前言 众所周知,CSS是一个相对简单且语法宽松的语言,虽然对开发者友好,但因为它过于“随意”且耦合性强(如height和line-height都会对元素的高度造成影响),如果开发时不做限制,对后续维护的人员来说将会造成“毁灭性打击”。 故为了样式代码的可读性,也为了减少维护人员受到的心理创伤,我们需要对CSS的编写做出限制 BEM命名规范 😀 一般来说,我们编写CSS时类名会遵循BEM命名规范,这种规范的特点是语义化、结构化、遵循开闭原则。参考知乎——CSS之BEM命名规范 “开闭原则”指对修改封闭、对扩展开放,是面向对象思想的重要基本原则 BEM规范存在的问题 😐 语义化的CSS类看似与HTML无关,但在嵌套的CSS选择器(如使用less时)中却反映出了具体的HTML结构。除此以外,CSS里还有很多会被父元素或子元素影响的属性,故将CSS与HTML解耦实际上是很困难甚至无法达成的 在处理两个外表相似的内容时(如下图的作者简介和文章预览),即使样式决策有99%是一致的,我们也很可能需要编写两个语义不同的类来赋予它们样式(如.author-bio和.article-preview),并且这两个类是几乎不可复用的 实际上,可以通过一些CSS预处理器的如 @extend 等功能实现复用,但会对后续维护造成很大的困扰 即便将类拆分到每个组件,使其不基于内容(如.card .button)虽然可以在一定程度上复用这些类,但当组件功能越具体,复用就会越困难(如.dialog-header__button) 给CSS类命名是令人费神的 原子类 原子类,指具有“原子性”的CSS类 在化学反应中“原子”是最小的单位,故“原子性”指具有不可拆解、不可更改的性质 示例: .flex { display: flex; } 上面的.flex就是一个原子类,它的特点就是一个类名对应一个CSS规则,并且类名应该是和规则有关系的 原子类的思想可以说与我们常用的BEM规范“背道而驰”,BEM强调的是语义化与将CSS从HTML的关注点分离(实际上很可能没有分离),而原子类几乎摒弃了语义化,通过使用提供的大量工具类使页面符合最终的设计决策 Tailwind基本概念 Tailwind就是一个采用了CSS原子类和“All in JS”思想的框架 “All in JS”指“HTML in JS”和“CSS in JS”,其中“HTML in JS”就是Vue、React等框架在做的事 框架特点 Tailwind 提供了一组可重用的 CSS 类,可用于几乎任何类型的 UI 组件和布局。 Tailwind… Continue Reading Tailwind 入门

原题:给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1) 的算法解决此问题。 示例 : 输入:nums = [2,2,1,1,1,2,2] 输出:2 思路一 首先想到用哈希表记录每个元素出现的次数,然后遍历哈希表,次数最多的值即为答案,比较简单,在此就不放代码了 复杂度:需要遍历一次数组,一次哈希表,且需要哈希表存储最多 n/2 + 1 个元素,故时间复杂度O(n),空间复杂度O(n) 思路二 上面的思路不满足题目进阶要求中的空间复杂度O(1),仔细想想自己忽略了一个条件——多数元素出现次数大于 n/2。 要利用这个条件需要一个数学公式,令数组总长度为a,多数元素个数为b,在题目所给条件下有(证明在下方): \frac{b}{a} > \frac{1}{2},\frac{b – 1}{a – 2} > \frac{1}{2} 考虑每次从数组中取出两个不同的元素,由于多数元素出现次数大于 n/2,由上面的公式可知,在最坏情况,即每次都取出多数元素的情况下,取出两个不同元素后,数组的多数元素仍然不变 故可将上述思路转换为:将第一个元素设为候选多数元素,遍历数组并计数,若遇到不同元素,则将当前元素的计数减一(相当于取出两个不同元素),反之加一,元素的计数为0时将候选元素替换为下一个元素,最终剩下的候选元素即为我们需要的结果 代码: var majorityElement = function(nums) { let… Continue Reading 算法题记录——多数元素

原题:给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。返回容器可以储存的最大水量。 示例: 输入:[1,8,6,2,5,4,8,3,7] 输出:49 解释:图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 思路 看到示例第一时间想到用双指针解决,关键在于何时移动左指针或右指针,并更新结果的最大值 记左指针为lp,右指针rp,记[lp, rp]区间能盛水的值为 y,由短板效应易知 *y = min(height[lp], height[rp]) (rp – lp)** 初始时令lp = 0,rp = n – 1,假设某状态下height[lp] < height[rp],考虑此时如何移动指针 若将lp右移,则当 height[lp + 1] > height[lp]… Continue Reading 算法题记录——盛最多水的容器

一、JDK版本问题 由于之前开MC服务器时安装过Java1.20.x版本,后面在装Android SDK时就没注意安装相应的JDK版本,导致用yarn android启动时报错 错误信息: BUG! exception in phase ‘semantic analysis’ in source unit ‘BuildScript’ Unsupported class file major version 64 查了一会发现是JAVA版本过高导致的,降级成1.17.8后重新配置环境变量即可 二、Andriod SDK环境变量配置问题 一个低级错误= =,官方文档中已经写了要配置这些变量: %ANDROID_HOME%\platform-tools %ANDROID_HOME%\emulator %ANDROID_HOME%\tools %ANDROID_HOME%\tools\bin 自己配置时漏了一个%ANDROID_HOME%\emulator,导致启动时无法找到安卓模拟器,又报错,加上后解决 三、Andriod Studio下载速度过慢 虽然一开始就知道Android开发需要合理上网,虽然下SDK速度挺快的,但下依赖的速度还是很慢,导致等了两个小时快下载完依赖的时候网络超时,又得重新下,因为不愿意再等两个小时,遂查找解决方法,发现gradle仓库源可以在项目里配置 将/android/build.gradle中的 repositories { google() mavenCentral() } 加上两行替换为阿里云源 repositories { maven{url 'https://maven.aliyun.com/repository/google'} maven{url 'https://maven.aliyun.com/repository/public'} google() mavenCentral() }… Continue Reading 记录搭建React Native环境时遇到的几个坑

原题:实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。 初步解决 思路:由于题目中的链表节点有一个随机指针,所以从头节点按顺序复制的话,可能出现指向的随机节点还没有被复制的问题,故考虑先按顺序复制,并将指针都设为null,用哈希表保存每个节点对应的副本,再将节点的指针连起来 代码(js): const copyRandomList = function(head) { if(!head) { return null } let curr = head const nodeMap = new Map() while(curr) { nodeMap.set(curr, {val:curr.val, next:null, random:null}) curr = curr.next } curr = head while(curr) { nodeMap.get(curr).next = nodeMap.get(curr.next) || null… Continue Reading 算法题记录——复杂链表的复制

问题来源 在实现某具有多级表头格的需求时,发现默认的单元格合并跟UI设计的不同,遂在网上寻找解决方法,于是发现了一个坑 网上的代码: <template> <el-table … :header-cell-style="setStyle" … > … </el-table> </template> <script> export default { … method: { setStyle({row, column, rowIndex, columnIndex}) { if (rowIndex === 0 && columnIndex === 0) { column.rowSpan = 2 } } } … } </script> 此时设置的rowSpan是不生效的 解决思路 因为网上搜到的代码基本都是这么写,故去看了下el-table的源码 table-header.js的render函数中相关源码如下 <th /* 此处设置了colSpan, rowSpan… Continue Reading 解决方案——el-table用header-cell-style回调设置rowSpan不生效

问题来源 由于查询条件改变频率高,或者后端数据处理逻辑复杂,导致接口返回的顺序跟实际请求的顺序不一致。 如:同一接口,先用复杂度高的查询条件发A请求,然后在A还没返回时发简单的B请求,且B返回数据后A才返回,此时若是用 *.then(res => …) 来处理的话,会出现最终使用的是A的返回数据的情况。 解决思路 由于涉及的场景不算复杂,故不打算使用类,个人选择了工厂函数的模式,考虑用两个变量分别保存当前已发送的请求数量,及当前请求的索引,分别记为A,B A初始为0,每次请求时加一,并将A赋值给该请求的索引B,请求返回时对比A和B,则: 若 A > B,说明不是我们期望的请求,在返回的数据中作标记,并在请求返回的回调函数中进一步处理 若 A = B,说明是我们应该处理的请求,将A置为0并返回原数据即可 正确的实现不应该出现 A < B 的情况 代码 /** 例如: * const fetchOptions = limitRequest() * fetchOptions({ url: 'http://www.baidu.com' }).then(res => { console.log(res) }) **/ const limitRequest = function() { const num = new… Continue Reading 解决方案——多次发送同一请求,仅响应最后一次

引入某文件夹下的所有vue组件 const requireComps = require.context('文件夹路径', true, /\.vue$/); const comps = {} requireComps.keys().forEach(name => { const comp = requireComps(name).default // 要求vue组件的$option有name属性 comps[comp.name] = comp // 注意此处comps和comp差别 }) export default { … components: { …comps } … }