Category Archives: javascript

在 js 中使用 ts 的 module alias 功能

介绍

js 代码中引用依赖的时候默认是使用相对路径,项目复杂后相对路径可能会用到非常多的相对层级,非常不方便,在 typescript 中可以在 tsconfig.json 配置的 compilerOptions 中配置 paths,实现别名功能:

{
    "compilerOptions": {
        paths: {
            "@app/*": ["./src/*"]
        }
    }
}

在 js 中默认是没有这样的功能,但是可以通过第三方的包实现一样的绝对引用。
这里用到名为 module-alias 的包。

使用

首先在项目里安装这个依赖。

npm i --save module-alias

然后在 package.json 中进行配置

"_moduleAliases": {
  "@app"      : "./src", // Application's root
}

最后在代码头部引入依赖

require('module-alias/register')

原理

这个原理也比较简单,就是劫持 nodejs 原生的 module 模块。在模块初始化的时候,根据 package.json 中的配置将别名路径转换成相对路径存在数组中,然后通过改写内部的 _nodeModulePaths _resolveFilename 两个方法,判断如果是别名开头的,就在前面的数组中找到别名对应的路径,再将路径进行拼合,还原出真实的引用路径。

参考

next-route-visualizer 包介绍

今天 github 上看到一个 next-route-visualizer 的包,可以用来绘制 next 站点路由图表。看了下代码,核心方法有三个。

  • getRoutes 获取所有路由节点信息
  • positionTree 确定路由节点的显示位置
  • createNodesAndEdges 绘制节点和边的信息

将计算号的节点和边信息传递给 reactflow,用 reactflow 包来绘制图表。

通过这个图表可以可视化的查看站点的结构,便于分析和构建出合理的网站信息架构,可以作为开发时候一个辅助决策的功能集成到系统中。

有兴趣的朋友可以学习了解一下。

参考

position sticky 失效问题

写了个图墙组件,其中用到了 sticky 做滚动固定。测试发现部分使用情况下会失效。搜了下,看到下面情况会导致 sticky 失效:
1、具有 sticky 属性的元素,其父级高度必须大于sticky元素的高度。
2、sticky 元素的底部,不能和父级底部重叠。
3、sticky 元素的父级不能含有 overflow:hidden 和 overflow:auto 属性。
4、必须具有 top,或 bottom 属性。
对应排查后,发现父元素上使用了 overflow:hidden,去除后问题修复了。

vue for 循环中使用 input 无法连续输入问题

vue 的 for 循环中如果使用了 input,input 的值又为循环对象中的值,那么修改 input 的值的时候,会重新刷新 for 循环节点,导致 input 输入框失去焦点。处理方法也比较简单,在 input 的 change 事件里,添加 vue.$nextTick 注册下次刷新的时候重新获取 input 焦点即可。

Base64转Blob格式

  • 将Base64转为Blob类型
parseFileType: function(basestr, type) {
  var text = window.atob(basestr.split(',')[1]);
  var buffer = new Uint8Array(text.length);
  for (var i = 0; i < text.length; i++) {
    buffer[i] = text.charCodeAt(i);
  }
  var blob = self.getBlob([buffer], type);
  return blob;
}
  • 获取Blob对象的兼容性写法
getBlob: function(buffer, format) {
  try {
    return new Blob(buffer, {
      type: format
    });
  } catch (e) {
    var bb = new(window.BlobBuilder || window.WebKitBlobBuilder || window.MSBlobBuilder);
    buffer.forEach(function(buf) {
      bb.append(buf);
    });
    return bb.getBlob(format);
  }
}

获取到 blob 后可以做图片上传。

vuejs 异步渲染问题

Vue 异步执行 DOM 更新。只要观察到数据变化,Vue 将开启一个队列,改变缓冲在同一事件循环中发生的所有数据。如果同一个 watcher 被多次触发,只会一次推入到队列中。这个思想类似于 react, 用来减少 重绘性能消耗,譬如 :

<div v-if="data">
  <com ref="com"></com>
</div>

data 最初为null,那么当我们在一个method 中调用

this.data ={};
console.log(this.$refs.com)

时因为 vue 异步更新dom 的关系,data 并没有马上生效到dom 的渲染上,com 组件未完成渲染,所以 this.$refs.com 会为 undefined,此时需要使用 this.$nextTick 解决问题