const list: any = [] const obj: any = {} const a: any = 1引入了 ts的项目,由于是在原可运行代码的基础上额外添加了类型注释,所以代码体积毫无疑问会增大,有调查显示,可能会增加 30%的代码量,如果充分发挥 AnyScript 的宗旨,意味着你很轻松地就让代码增加了 30% 毫无用处但也挑不出啥毛病的代码,这些代码甚至还会增加项目的编译时间(毕竟增加了ts校验和移除的成本嘛)。
export default defineComponent({ props: { // 堆代码 duidaima.com // 现在 data 是 any 类型的啦 data: { type: Number as PropType<any>, }, }, setup(_, { emit }) { // 现在 props 是 any 类型的啦 const props: any = _ ... } })当然了,全屏 any可能还是有点明显了,所以你可以适当地给部分变量加上具体类型,但是加上类型不意味着必须要正确使用。
const obj: number[] = [] // ... // 虽然 obj 是个 number[],但为了实现业务,就得塞入一些不是 number 的类型,我也不想的啊是不是 // 至于编辑器会划红线报错?那是小问题,不用管它,别人一打开这个项目就是满屏的红线,想想就激动 obj.push('2') obj.push([3])2.命名应该更自由
const a1 = {} const a2 = {} const a3 = 2 const p = 1我必须强调一点,命名不仅是变量命名,还包含文件名、类名、组件名等,这些都是我们可以发挥的地方,例如类名:
<div class="box"> <div class="box1"></div> <div class="box2"></div> <div> <div class="box3"></div>乍一看似乎没啥毛病,要说有毛病似乎也不值当单独挑出来说,没错,要的就是这个效果,让人单看一段代码不好说什么,但是如果积少成多,整个项目都是 box呢?全局搜索都给你废了!如果你某些组件再一不小心没用 scoped 呢?稍不留意就不知道把什么组件的样式给改了,想想就美得很。关于 css我还想多说一点,鉴于其灵活性,我们还可以做得更多,总有人说什么 BEM 不 BEM的,他们敢用我们就敢写这样的代码。
&-card { &-btn { &_link { &--right { } } &-nodata { &_link { &--replay { &--create {} } } } } &-desc {} }好了,现在请在几百行(关于这一点下一节会说到)这种格式的代码里找出类名 .xxx__item_current.mod-xxx__link 对应的样式吧。
data === 1 ? 'img' : data === 2 ? 'video' : data === 3 ? 'text' : data === 4 ? 'picture' : data === 5 ? 'miniApp'三元表达式可以优雅地表达逻辑,像诗一样,虽然这段代码看起来比较多,但逻辑就是这么多,我还专门用了三元表达式优化,不能怪我是不是?什么map映射枚举优化听都没听过。你也可以选择其他一些比较容易实现的思路,例如,多写一些废话。
if (a > 10) { // 虽然下面几个 if 中对于 a 的判断毫无用处,但不仔细看谁能看出来呢?看出来了也不好说什么,毕竟也没啥错 // 除此之外,多级 if 嵌套也是堆屎山的一个小技巧,什么提前 return 不是太明白 if (a > 5) { if (a > 3 && b) { } } if (a > 4) { } }除此之外,你还可以写一些中规中矩的方法,但重点在于这些方法根本就没用到,这种发挥的地方就更多了,简直就是扩充代码体积的利器,毕竟单看这些方法没啥毛病,但谁能想到根本就用不到呢?就算有人怀疑了,但你猜他敢随便从运行得好好的业务项目里删掉一些没啥错的代码吗?
// 首先这个命名就很契合上面说的自由命名法 function fn1() { // ... // fn1 的逻辑比较长,且解决的是通用问题, // 但 myObj 偏偏是一个外部变量,这下看你怎么复用 window.myObj.name = 'otherName' window.myObj.children.push({ id: window.myObj.children.length }) // ... }5.魔术字符串是个好东西
if (a === 'prepare') { const data = localStorage.getItem('HOME-show_guide') // ... } else if (a === 'head' && b === 'repeating-error') { switch(c) { case 'pic': // ... break case 'inDrawer': // ... break } }基于此,我们还可以做得更多,比如用变量拼接魔术字符串,debug的时候直接废掉全局搜索。
if (a === query.name + '_head') { }大家都是中国人,为什么不试试汉字呢?
if (data === '正常') { } else if (data === '错误') { } else if (data === '通过') { }6.轮子就得自己造才舒心
function format(str1: any, str2: any) { const num1 = new Date(str1).getTime() const num2 = new Date(str2).getTime() return (num2 - num1) / 1000 }多么精简多么优雅,至于你说的什么格式校验什么 safari下日期字符串的特殊处理,等遇到了再说嘛,就算是dayjs不也是经过了多次 fixbug才走到今天的嘛,多一些宽松和耐心好不好啦!
考虑到大家都只是混口饭吃而已,凡事都造轮子未免有些强人所难,所以我们可以尝试走向另外一个极端——凡事都用轮子解决 判断某个变量是字符串还是对象,kind-of拿来吧你;获取某个对象的 key,object-keys拿来吧你;获取屏幕尺寸,vue-screen-size拿来吧你……等等,就不一一列举了,需要大家自己去发现。
import _ from 'lodash'8.多尝试不同的方式来解决相同的问题
mounted() { setTimeout(() => { const width = this.$refs.box.offsetWidth const itemWidth = 50 // ... }, 200) }例如对于上述代码,为什么要在 mounted里写个 setTimeout呢?为什么这个 setTimeout的时间是 200呢?可能是因为 box 这个元素大概会在 mounted之后的 200ms左右接口返回数据就有内容了,就可以测量其宽度进行其他一系列的逻辑了,至于有没有可能因为网络等原因超过 200ms还是没有内容呢?这些不需要关心,你只要保证在你开发的时候 200ms这个时间是没问题的就行了。
// 计算 data 是否可用 //(实际上,这个方法的作用是计算 data 是否 不可用) function isDisabledData(data: any) { // ... }上述这个例子只能说是小试牛刀,毕竟多调试一下很容易被发现的,但就算被发现了,大家也只会觉得你只是个小粗心鬼罢了,怎么好责怪你呢,这也算是给其他人的一个小惊喜了,况且,万一真有人不管不顾就信了,那你就赚大了。