十月学习记录

青柚前端的开源和迁移

A creative team. --GreenPomelo

开源仓库地址

严格的WorkFlow

  • eslint + husky + prettier 代码风格的统一
  • 标准的commit message: feat,refactor,fix,style,docs…
  • Pull Request
  • Reviewer
  • Merge

本科生小程序的代码优化和用户体验优化

  • wx-axios模块的再次封装,错误处理…
  • 图书馆模块的优化:
    • 之前学长写的代码…嗯…吐槽一下,其实this都指向的是一个实例,不应该用that = this的
    • 然后的话,分页面请求: 历史借书,查询书籍,座位查询,全部放在首页请求性能肯定会下降,而且more.wpy页面:图书馆也是有4个图标的,做对应的请求显得更有必要
    • 代码方便做的一些调整,比如API比for loop可读性更高,想起来之前暑假在JSperf上测试,forEach比for现在性能也更高的

不过改进的时候,我们其实也显得有些激进了,直接改进线上版本,也带来了一些不好的地方


React重构新生杯平台

项目地址

函数式思想的一些实践

  1. React的每个组件都是一个function或者写成es6的class,函数是最小单元.

  2. 函数抽离

      isUsernameAndPasswordNotEmpty = () =>
        this.state.studentId && this.state.passWord;
    

    比如上面👆就是一个判断用户名和密码是否为空的函数

  3. 不过其实就像胡子大哈说的,FP的真正用途体现在无副作用组件和共享数据上,不过这次也没有使用redux的数据管理,所以,组件的props和state写起来还挺乱的…


开发中的一些东西

  1. 保存登录状态,其实前端本地存了约定好的那个**“token”**字段就好了,主要还是后端做
  2. api的抽离,在每个页面中其实代码量也相对减少了
  3. 跨域,直接proxy代理到后端服务器那边就好了,也不用等后端再配置跨域了
  4. 添加debounce:减少请求的次数,不过delay不能设置太长,不然会降低用户体验的

关于React的

  1. 因为React是向下传递的,所以没有回溯的能力,写一些callback再去改变父组件,然后props也是不可变的…没有使用状态管理处理起来也有点麻烦

    写出来的样子大概是在子组件的render里,写了一堆三元操作符…

  2. componentDidUpdate用来比对props的更新来改变子组件的state也挺方便的

    之前不会用的时候,直接setState是不行的,因为导致了循环更新

      componentDidUpdate(prevProps) {
        if (this.props.questionInfo !== prevProps.questionInfo) {
          this.setState({ textAreaAnswer: null });
        }
      }
    

@vue-cli重构了一下院科协主页的代码

主要就是习惯了框架,感觉离开node包的HTML5写起来好累(虽然暑假里是用Vue单文件写的),然后主要工作就是抽离出一些组件,比如导航,第一页的canvas…


遇到的Vue的一个问题:

写一个项目的时候,需要走马灯,element-ui给的一个属性是可以获取到activeIndex,可是没有提供一个方法去修改activeIndex,所以在做走马灯的索引定制化的时候,自己写的索引就只能获取到而不能修改.

解决方案:

<el-carousel ref="carousel">
changeDotIndex(index) {
  this.$refs.carousel.setActiveItem(index);
  this.activeIndex = index
}

Refs provide a way to access DOM nodes or React elements created in the render method.

其实Vue和React里面的refs效果差不多,可以访问到DOM的属性


“糊糊的面试题”

写一个类似于RxJS的流和订阅,当时写的代码,我贴在下面吧,应该用闭包写的唉,用class写就不能接方法了,有时间的话,努力重新写一下吧~

/** 定义的一些实例函数 */
const doublePrint = x => x.repeat(2);
/** 测试字符 */
const demoString = `abc`;
String.prototype.replaceAt = (index, ch) => {
  let newStr = "";
  for (let i in this) {
    if (i === index) {
      newStr += ch;
    } else {
      if (typeof this[i] === "string") {
        newStr += this[i];
      }
    }
  }
  return newStr;
};
class typingStream {
  constructor(timer, typeFont) {
    this.timer = timer;
    this.typeFont = typeFont;
    this.typeFontCopy = typeFont;
    this.root = document.querySelector(`.font-container`);
    this.status = 0;
  }
  timeDelayHandle(action) {
    const loop = setInterval(() => {
      action();
      this.status++;
      if (this.status === this.typeFont.length) {
        clearInterval(loop);
      }
    }, this.timer);
  }
  pipe(...funcs) {
    let x = [];
    for (let i = 0; i < this.typeFontCopy.length; i++) {
      funcs.map(func => {
        x.push(func(this.typeFont.charAt(i)));
      });
    }
    for (let i = 0; i < this.typeFontCopy.length; i++) {
      this.typeFont = this.typeFont.replaceAt(i, x[i]);
    }
    this.render();
  }
  // subscribe() {
  //   this.render();
  // }
  render() {
    const createDiv = () => {
      const font = document.createElement(`div`);
      font.style = `display:inline-block`;
      font.className = `animated jackInTheBox font`;
      font.innerText = this.typeFont.charAt(this.status);
      this.root.appendChild(font);
    };
    this.timeDelayHandle(createDiv);
  }
}
const instance = new typingStream(1000, demoString);
instance.pipe(doublePrint);

GDG

最感兴趣的一场分享肯定是组件,接口与应用了.人家说的一些东西,现在能力还不够去理解,比如怎么去优化React代码的,shouldCompontUpdate之类的,以及组件的分类加载.人家说的繁琐的dispatch,我还没用过redux啊!哭!

还问了人家的小问题

  1. 你们在做应用前选择框架的时候要考虑哪些方面?
    社区生态…
  2. 如何选择组件库,比如我用element-ui,material-ui的时候,感觉定制性不怎么好唉?
    原子组件根据业务封装成分子组件…

GDG


总之加油吧~

Happy Halloween~

halloween