Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

代码评审高频 #231

Open
yanyue404 opened this issue Jun 24, 2022 · 0 comments
Open

代码评审高频 #231

yanyue404 opened this issue Jun 24, 2022 · 0 comments

Comments

@yanyue404
Copy link
Owner

常见问题

  1. 建议 v-for 循环不要使用 index 作为 key(老生常谈)
  2. 建议加一个计算属性,模板里不要写复杂逻辑
  3. 建议 v-if 跟 v-else-if、v-else 配合使用
  4. 建议使用 v-bind=item https://cn.vuejs.org/v2/api/#v-bind
  5. 建议使用 ref 代替 id,ref 是引用的方式,比查找效率更高,其他组件可能出现 id 重名的情况
  6. 建议使用 component 分发动态组件
  7. template 中不要直接写 style,postcss 对 template 无效
  8. 建议 p 标签换成 before 或者 after 伪类
  9. 建议滚动事件使用防抖/节流
  10. 建议多次复用的组件封装提取出来
  11. 建议方法中的 Object.keys 换成 Object.entries
  12. 建议弹窗使用 this.$modal(),里面有对滑动穿透的处理
  13. 建议控制弹窗显示隐藏的 data 属性只留一个,可以在 data 里多放一个控制弹窗类型的属性
  14. 赞,海报生成好后放到一个透明 img 上,避免元素替换时出现页面抖动,很巧妙的思路
  15. 赞,页面销毁时注销滚动事件监听,避免内存泄漏

代码评审高频问题

  • template 部分
    • v-for 中建议使用 key,但不建议使用 index 作为 key,可以用 item.id 或者 object-hash 生成 key
    • 出现多个判断分支时,要 v-if 和 v-else 结合起来用
    • v-if 不要写复杂逻辑,如果需要复杂逻辑可以使用计算属性
  • script 部分
    • data 中没有在 template 中出现的字段或者在 data 中初始化之后就不再改变的字段可以不放在 data 中
    • 变量和方法命名要规范、统一、有意义,见 ​ 非车前端编码规范 ​
    • 查找 dom 元素建议使用 ref 代替 getElementById
    • 实现异步方法时使用 promise,调用异步方法时使用 async/await
    • 多封装方法,远离 mixin

扩展

  1. key 不建议用 index 的原因
  • 为啥要用 key
    • 中间插入/删除一项
    • 过渡效果错乱
  • 为啥不建议用 index
    • 中间插入/删除一项
    • 过渡效果错乱
    • select 选项错乱
  1. 如何强制刷新组件
  • 使用 key
  • 使用 this.$forceUpdate
  • 使用 v-if
  • 刷新当前页面
  1. 字符串出现次数最多字符获取

  2. 先递增后递减数组极大值获取

二分查找

//  例:
 [0,1,4,7,5]  => 7
 [1,6,5,3,2] => 6
  1. 实现粘性定位-快滑出屏幕时吸顶或吸底

  2. axios 源码

  • 使用说明 http://www.axios-js.com/
  • 问题
    • 如何兼容浏览器环境和 node 环境
    • 拦截器的触发顺序
      • interceptor 和 transformRequest 触发顺序
      • 各个 interceptor 的触发顺序
  1. ​ 浏览器工作原理 ​
  2. ​ 浏览器缓存机制 ​

补充

// MDN 示例:在文档可见时开始播放音乐曲目,在文档不再可见时暂停音乐
document.addEventListener("visibilitychange", function () {
  if (document.visibilityState === "visible") {
    backgroundMusic.play();
  } else {
    backgroundMusic.pause();
  }
});
  • mask 组件
// 省略若干代码
export default {
  props: {
    show: {
      type: Boolean,
      default: true,
    },
    /**
     * 设置在mask上面滑动能不能滚动页面, 默认不能滚动页面
     */
    noScrollingPage: {
      type: Boolean,
      default: true,
    },
  },
  computed: {
    maskStyle() {
      return {
        position: "fixed",
        backgroundColor: `rgba(0,0,0, ${this.opacity})`,
        height: "100%",
        width: "100%",
        top: 0,
        left: 0,
        zIndex: getZIndex(),
      };
    },
  },
  watch: {
    noScrollingPage(val) {
      val ? this.disableScrollPage() : this.enableScrollpage();
    },
    show(val) {
      val && this.noScrollingPage
        ? this.disableScrollPage()
        : this.enableScrollpage();
    },
  },
  mounted() {
    this.$el.addEventListener("touchmove", this.scrollHander, true);
    this.show && this.noScrollingPage && this.disableScrollPage();
  },
  destroyed() {
    this.enableScrollpage();
    this.$el.removeEventListener("touchmove", this.scrollHander);
  },
  methods: {
    disableScrollPage() {
      document.documentElement.style.overflow = "hidden";
    },
    enableScrollpage() {
      document.documentElement.style.overflow = "";
    },
    scrollHander(e) {
      const getNeed = (el) => {
        if (el == this.$el || !el || !el.parentElement) {
          return false;
        }
        if (el.className.indexOf("mask-content-needscroll") >= 0) {
          return true;
        }
        return getNeed(el.parentElement);
      };
      if (this.noScrollingPage && this.show && !getNeed(e.target)) {
        e.preventDefault();
      }
    },
  },
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant