Appearance
开发小知识分享
分享一些我所知道的容易踩坑的小知识点。
CSS
flex 布局下的弹性宽度处理
flex 布局是现在开发中使用的最多也是最主流的一个布局方式了,非常的好用,但是在一些特殊场景下,flex 布局会影响一些子元素的宽度,这时候就需要特殊的设置一些 API。
涉及的 API
flex
width
max-width
、min-width
背后的小故事
有一天我在开发的时候,一个同事看我写了以下一段代码:
css
// ... 省略以上的代码
.coupon {
max-width: 100px;
min-width: 100px;
}
// ... 省略以上的代码
.coupon {
max-width: 100px;
min-width: 100px;
}
同事发表评论:为什么要写max-width
和min-width
,你这样和直接写width
又有什么区别呢?
我:在flex
布局下特殊情况直接写width
是会有问题的。
同事:能有什么问题?
我:吧啦吧啦
之后同事是比较应付的说了哦,显然他不太愿意听我继续往下说,应付的回了一下我。之后也就没有再提这个了。
到底直接写 width 会有什么问题呢?
直接上一个案例吧~,一个很常见的一个布局,使用 flex 实现,效果大致如下(简单的画一下,大致意思应该能够表达到位了)
我们给立即使用的按钮设置了宽度为 80px,在左边的内容不是特别多的时候是能够正常的显示的,按钮也是 80px,没有一点儿问题~
但是当左侧的内容一多起来,由于 flex 布局的”弹性“的原因,就会去挤压左侧立即使用按钮的宽度,就会造成页面的形变,如果线上这样展示,无疑就是一个 bug!如下:
这种情况,我的解决方案就是,不再使用width
来限定宽度,而是使用max-width
和min-width
一起限制宽度,这时候即使左侧文案再长,也不会去挤压到右侧的宽度,或者说,挤压不动右侧的宽度!
这个就是我解决flex
布局宽度被挤压的问题的解决方式啦,就是使用max-width
和min-width
一起配合使用,替换width
。
相信这个场景下应该还有其他的解决方案,如果有更好的解决方案的小伙伴们可以私信告诉我呀,或者直接分享出来,咱们大家一起学习一下~😋
小案例源码:传送门
感谢大家的观看,希望我的分享能够对你们有帮助!
最新解决方案
感谢一位老铁特地加我微信告诉了我一个更加优雅的实现方案:
右侧按钮设置:flex-shrink:0 或者左侧文案区域设置: flex:1
亲测有效,而且更加的优雅,今后都会使用这个方式来解决这个问题了!
JS
优雅的处理浮点数的加减法
今天看到一个非常惊艳到我的一段代码,足足惊艳了半个多小时!代码如下:
js
export function formatFloat(num: number, accuracy = 2) {
return +num.toFixed(accuracy)
}
export function formatFloat(num: number, accuracy = 2) {
return +num.toFixed(accuracy)
}
这代码使用公司前辈写在公用工具库里的方法,第一眼看上去感觉也没什么了不起的,不就是toFixed
方法可以四舍五入截取小数点位数嘛,但是我用了之后发现并没有那么简单:
大家可以先思考一下,大家可以想一下,这两种情况,返回值分别是什么:
formatFloat(1.333334)
是1.33吗?🤔
formatFloat(1.2)
1.20 ?🤔
formatFloat(0)
0.00 ? 🤔
以上我想的结果,实际情况下它的结果分别是:1.33、1.2、0。😱
奇怪了,它的accuracy
不是默认是2吗,肯定会有2位小数点截取的呀,为什么传0的时候它返回的不是0.00?🤔
我开始怀疑我对toFixed
的理解,然后开始在控制台写了一些测试代码。
发现确实是会有2位小数,研究了好一会儿也没有发现到底是为什么,于是我问了一下框架的作者。才知道原因...:😯
+num.toFixed()
前面加了一个+
,toFixed
的返回值是一个string
类型,因为+
的原因,会自动的将返回值转成一个number类型,'0.00'转正number类型就是0。
所以破案了🎉🎉,这段代码涉及隐式转换和执行顺序的知识。我理解的执行顺序是:(+num).toFixed(2)
,可真正的执行顺序是:+(num.toFixed(2))
。
现在回想起来我会认为执行顺序是(+num).toFixed(2)
是因为只有数值类型才会有toFixed
方法,这样理解是能兼容一些字符串的数字,当num是字符串的'1.23'时,页面就不会报错了,可是确忽略了,这是TS
,num已经给了是一个number
类型。🧐
总结
被这段代码经验到之后,知道了其实涉及隐式转换和执行顺序的基础知识还是很重要的,还有就是TS的重要性,这就是一个TS非常给力的场景!💪🏻💪🏻
我终于搞懂了weakMap与Map💪🏻
二者对标的数据类型都是对象类型 => 存储的键值对
我们要理解,为什么Vue3响应式系统使用的是weakMap而不是Map!
优势
有更加优雅&灵活的api用于增删改查
不会触发原型链的查找
过去其实一直不知道map与weakMap的区别,或者说看过书面的官方解释,也背过面试题,知道weakMap存储的是弱类型的key,那么到底什么是弱类型(引用类型)的key呢?
什么是弱类型
我们都知道的字符串,数字这种属于值类型,弱类型我的简单理解就是、对象、函数。
所以基于这一点,我们就知道,weakMap的key只能是存弱类型,就不能存储字符串或者数字之类的作为key,而这个map可以
不会发生内存溢出
一个简单的例子过一下就能完全理解了!
js
const map = new Map()
const wMap = new WeakMap()
(() => {
const foo = { foo: 1 }
const bar = { bar: 2 }
map.set(foo, 1)
map.set(2, 1)
wMap.set(bar, 1)
// wMap.set(3, 1) // 报错,key必须是弱类型
/**
* WeakMap 是弱引用, 一旦表达式执行结束,垃圾回收就会把 bar 从内存中移除,所以无法从 weakMap中取到bar
* 一旦被垃圾回收机制回收了,就无法获取到对应的 键和值了
*/
})()
console.log(map, map.keys()) // 依旧有办法获取 键和值
console.log(wMap) // 已经无法获取键和值了,因为是弱引用,已经被垃圾回收机制所回收了
const map = new Map()
const wMap = new WeakMap()
(() => {
const foo = { foo: 1 }
const bar = { bar: 2 }
map.set(foo, 1)
map.set(2, 1)
wMap.set(bar, 1)
// wMap.set(3, 1) // 报错,key必须是弱类型
/**
* WeakMap 是弱引用, 一旦表达式执行结束,垃圾回收就会把 bar 从内存中移除,所以无法从 weakMap中取到bar
* 一旦被垃圾回收机制回收了,就无法获取到对应的 键和值了
*/
})()
console.log(map, map.keys()) // 依旧有办法获取 键和值
console.log(wMap) // 已经无法获取键和值了,因为是弱引用,已经被垃圾回收机制所回收了
总结
通过这个例子我算是比较清晰的理解了二者的区别了,已经在什么场景下对应应该使用哪种map来存储,比之前光看书去强行理解文字好多了。
知道了这个之后,set和weakSet也是一样的方式取理解即可!
最后应该可以很好回答上面的那个问题了,当一个响应式对象已经被垃圾回收机制所回收时,我们就不需要继续存储这个key-value了,这是一个性能优化的点,同时也能避免内存溢出!☀️