Code Monkey home page Code Monkey logo

kilobyte's Introduction

Hi there 👋

  • 🌱 I’m currently learning Piano & Synthesizer & Arrangement
  • 💬 Ask me Anything
  • 📫 How to reach me: [email protected]
  • 😄 Pronouns: fat nerd, caring
  • 📍 Liaoning Shenyang (Working in Shanghai currently)
  • 💡 MBTI: Assertive Architect(INTJ-A)
  • 🌍 HomePage: iShawn.Wang

Github Stats

kilobyte's People

Contributors

ishawnwang avatar

Stargazers

 avatar

Watchers

 avatar  avatar

kilobyte's Issues

2019.11.24

关于 Typescript 枚举 最近总结出来的最佳实践

interface Enum {
  [id: number]: string
}

const getEnumKeys = (e: Enum) => {
  return Object.keys(e)
    .map(key => e[key])
    .filter(value => typeof value === 'string') as string[]
}

enum TrafficLight {
  red = 1,
  green = 2,
  yellow = 3,
}

namespace TrafficLight {
  export function keys() {
    return getEnumKeys(TrafficLight)
  }

  export function parse(light: Number): TrafficLight {
    return <TrafficLight>light
  }

  export function desc(light: TrafficLight) {
    switch (light) {
      case TrafficLight.green:
        return '绿灯'
      case TrafficLight.red:
        return '红灯'
      case TrafficLight.yellow:
        return '黄灯'

      default:
        return ''
      // 或者 throw new Error("参数错误")
    }
  }
}

console.error('emmmmmm')
console.log(TrafficLight.keys())
console.log(TrafficLight.desc(2))

2019.11.29

interface EnumDataType<ValueType> {
  [k: string]: {
    value: ValueType
    label: string
  }
}

// String
export class EnumString<T extends Readonly<EnumDataType<string>>> {
  data!: T
  constructor(x: T) {
    this.data = x

    const byValue: any = {}
    const byLabel: any = {}

    Object.keys(x).forEach(key => {
      byValue[key] = x[key].value
      byLabel[key] = x[key].label
    })

    this.value = byValue
    this.label = byLabel
    this.options = Object.entries(x).map(entry => {
      const k = entry[0]
      const v = entry[1]
      const option = { ...v, name: k }
      return option
    })
  }

  value: Readonly<
    {
      [k in keyof T]: T[k]['value']
    }
  >

  label: Readonly<
    {
      [k in keyof T]: T[k]['label']
    }
  >

  options: Readonly<{ label: string; value: string; name: string }[]>

  labelFor(e: string) {
    let findLabel = Object.entries(this.data).find(entry => {
      return entry[1].value === e
    })

    const value = Array.isArray(findLabel) && findLabel.length >= 1 && findLabel[1]
    return value ? value.label : ''
  }

  static init<T extends Readonly<EnumDataType<string>>>(e: T) {
    return new EnumString(e)
  }
}

// Number
export class EnumNumber<T extends Readonly<EnumDataType<number>>> {
  data!: T
  constructor(x: T) {
    this.data = x

    const byValue: any = {}
    const byLabel: any = {}

    Object.keys(x).forEach(key => {
      byValue[key] = x[key].value
      byLabel[key] = x[key].label
    })

    this.value = byValue
    this.label = byLabel
    this.options = Object.entries(x).map(entry => {
      const k = entry[0]
      const v = entry[1]
      const option = { ...v, name: k }
      return option
    })
  }

  value: Readonly<
    {
      [k in keyof T]: T[k]['value']
    }
  >

  label: Readonly<
    {
      [k in keyof T]: T[k]['label']
    }
  >

  options: Readonly<{ label: string; value: number; name: string }[]>

  labelFor(e: number) {
    let findLabel = Object.entries(this.data).find(entry => {
      return entry[1].value === e
    })

    const value = Array.isArray(findLabel) && findLabel.length >= 1 && findLabel[1]
    return value ? value.label : ''
  }

  static init<T extends Readonly<EnumDataType<number>>>(e: T) {
    return new EnumNumber(e)
  }
}

// Demo
// let TrafficLight = EnumNumber.init({
//   red: {
//     label: '红灯',
//     value: 1,
//   },
//   green: {
//     label: '绿灯',
//     value: 1,
//   },
// })

// TrafficLight.options
// TrafficLight.labelFor(1)
// if(TrafficLight.value.red === 服务端.some){

// }

2022 0118 B 端组件库最佳实践

很简单 !

styled-component + Ant D

  1. 和产品拉通产出通用组件的规范
  2. 用 styled-component Override Ant D 的默认样式
  3. 项目所有组件从统一位置导出 `import { Drawer } from '@/components'

2020.6.11 useScript hooks

import { useEffect, useState } from 'react'

const cachedScripts: string[] = []

export default function useScript(src: string) {
  // Keeping track of script loaded and error state
  const [state, setState] = useState({
    loaded: false,
    error: false,
  })

  useEffect(
    () => {
      // If cachedScripts array already includes src that means another instance ...
      // ... of this hook already loaded this script, so no need to load again.
      if (cachedScripts.includes(src)) {
        setState({
          loaded: true,
          error: false,
        })
        return () => {}
      } else {
        cachedScripts.push(src)

        // Create script
        const script = document.createElement('script')
        script.src = src
        script.async = true

        // Script event listener callbacks for load and error
        const onScriptLoad = () => {
          setState({
            loaded: true,
            error: false,
          })
        }

        const onScriptError = () => {
          // Remove from cachedScripts we can try loading again
          const index = cachedScripts.indexOf(src)
          if (index >= 0) cachedScripts.splice(index, 1)
          script.remove()

          setState({
            loaded: true,
            error: true,
          })
        }

        script.addEventListener('load', onScriptLoad)
        script.addEventListener('error', onScriptError)

        // Add script to document body
        document.body.appendChild(script)

        // Remove event listeners on cleanup
        return () => {
          script.removeEventListener('load', onScriptLoad)
          script.removeEventListener('error', onScriptError)
        }
      }
    },
    [src], // Only re-run effect if script src changes
  )

  return [state.loaded, state.error]
}

Usage

const [scriptLoaded] = useScript('https://yourscript.js')

2019.08.17

前后端分离, API 定义问题总结

后端现在使用 Java + Swagger annotation 的方式 先给出接口文档, 前后端分离开发
例子 :

{
  "code": 200,
  "data": {
    "xxxCount": "",
    "xxxCode": 0
  },
  "msg": ""
}

但是某些业务场景下, 没有 xxxCountxxxCode 值,
所以直接返回

{
  "code": 200,
  "data": "",
  "msg": ""
}

data'' 的原因是, 后端 api 层会把所有 null 转成 ''

但是, 从前端的角度来看, 和 API 约定的类型完全不一致, 导致前端取值 data.xxxCode 报错


我的想法是, 首先要符合文档的约定, 后端尽量标明 data 可能为 对象 或者
要求后端提供默认值, 也不是太合适, 而且有些默认值还和业务相关, 后端 API 应该保证抽象程度更高, 偏展示的逻辑尽量放在前端

一些其他的前端解决办法

最好的解决办法

optional-chaining 需要 Babel 7+

ViewModel

类似 移动端 的 Model 层 和 Java Bean
https://github.com/vvpvvp/model/blob/master/README_zh.md

方便读取 JSON 数据的工具函数

facebook/idx
safe-touch
Lodash.get

相关讨论

如何和后端沟通,解决api接口返回多层嵌套的json,在中间的某一层为null的问题?

2020.02.29 从 Umi get 到的点 !

2.29 特殊的日子诶...

终于知道 umi.js 为什么 package.json 锁版本了...

A 包: prettier: "^1.19.0"
B 包: prettier: "1.18.3"

yarn install 后, node_modules 里面会安装为 1.18.3 版本的 prettier !!!

2020.4.11 styled-components 源码

styled-components

  1. 使用 React.forward 实现类似 HOC 的包裹组件效果
  2. 组件创建的时候, 动态创建一个随机的 className
  3. 用 template string 方式传入的 CSS 样式, 作为样式字符串, 包裹在上面创建的 className 中, 放到 动态创建的 style 标签中
  4. 我的问题是 : 组件销毁时, 相关的样式表没有移除 ! styled-components/styled-components#3105

2019.08.23

如何优化旋转的菊花

网络条件特别好的情况下, 经常会出现 loading 快速闪一下的情况, 解决方案 :

  1. 菊花 在 loading == true 之后 延迟 500ms 出现
  2. 菊花 一旦显示出来, 则最少显示 735 ms

如果你的软件特别卡的话, 不要慌, 找 UI 设计师 设计一个 Nice 的 Loading 动画 发上去, 发一版
能极大的缓解用户的焦虑 和 投诉
再慢慢去解决慢 和 卡顿的问题 ~

👍

2019.08.12

Impl

谷粒-Chrome插件英雄榜
android 和 RN 用 Gitlab CI(Mac mini) + fastlane + pgyer 美滋滋

问题

小程序对应的二维码 /pages/productDetail/666, 扫码会直接进入 商品详情页面, 但是 商品详情页面的 onShow 依赖 App.jsonLaunch 异步获取的 globalData 数据 !

可以尝试的解决方案 :

  1. 所有依赖 globalData 的地方, 加判断逻辑, 检查 globalData 是否存在, 如不存在, 用发布订阅模式, 等待 globalData 获取完成
  2. Redux 中间件, 指定 action 执行前, 检查 global Data 是否获取完成, 没有完成, 则放入队列, store.subscribe 监听到数据获取完成后, 顺序取出队列中任务执行
  3. RequestClient, 维护请求队列, 检查方式同上
  4. *操作 : 正常执行, 请求失败, 然后 globalData 获取完成后, getCurrentPages, 获取所有页面, 手动执行所有页面的 page.onShow(), 这样 onShow() 会执行两次
  5. 修改 taro 源码,� onLaunch 添加一个 callback 函数, callback 执行后, 再执行所有页面的 生命周期 ! ,很 hack !!!
  6. 所有二维码都用 /pages/index, 添加 redirect=/pages/productDetail/666 参数, 再 onlanunch 获取玩 globalData 后, 手动执行 push 跳转

综合考量, 方式 4 可行性高, 坑少, 但是由于已经有一波二维码在线上使用, 所有最终使用了 0 方法

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.