2022-06-30

pinia 使用上到底和 vuex 有什么区别

pinia 没有 mutation,数据更简洁,可直接更改,也可以 action,action 既可以是同步,也可以是异步
没有复杂的 module,composition api 天然的模块独立,想使用其他模块直接 useXXX 即可
等等…

2022-06-24

url 变化监听

  1. function urlChange(routeModel: string) {
  2. // 如果是 hash 路由模式
  3. if (routeModel === 'hash') {
  4. window.addEventListener('hashchange', console.log)
  5. return
  6. }
  7. // history 路由模式
  8. // history.back()、history.forward()、history.go() 监听
  9. window.addEventListener('popstate', console.log)
  10. // 重写 history.pushState()、history.replaceState()
  11. // 触发 window 对应 pushState, repalceState 事件,再监听
  12. const _historyWrap = function (type: string) {
  13. const orig: (window.history as Record<string, any>)[type];
  14. const e: any = new Event(type)
  15. return function () {
  16. // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  17. // @ts-ignore
  18. const rv = orig.apply(this, arguments)
  19. e.arguments = arguments
  20. window.dispatchEvent(e)
  21. return rv
  22. }
  23. }
  24. history.pushState = _historyWrap('pushState')
  25. history.replaceState = _historyWrap('replaceState')
  26. window.addEventListener('pushState', console.log)
  27. window.addEventListener('replaceState', console.log)
  28. }

2022-06-13

普通 for 循环里面 await 可以,forEach 和 map 中 await 不行,为什么

forEach 回调函数内容没有 return Promise,普通 for 循环可以

2022-06-08

nvm use 失败,提示乱码,需要使用管理员权限

windows 下, nvm use 需要管理员权限,下载前,建议将之前安装的 node 卸载
nvm list
nvm use

2022-06-01

Module 类型绑定到 data, 数据改变后不及时更新页面的问题

image.png

import * as constants from './constants'
data: {
  constants,
  // 改为下面的,将 Module {} 对象转成普通对象
  constants: { ...constants }
}

2022-05-30

Vue3 composition 封装复用问题

一个例子,一个页面分三个区域

  • 查询模块
  • echarts 图
  • 表格模块

假设查询模块用 useSearchForm 封装。表格区域用 useTable 封装。查询模块、表格模块都需要使用查询数据
table 里使用的 useSearchForm 数据可能是重新初始化的数据。但如果把数据初始化放到外面,那可能存在页面切换后,再次进来还有缓存的问题。这种情况有三种方法处理

  • 用一个 useXXX,不拆分
  • 保持拆分,将公共数据放到他们的父级,使用时通过 props 传给子组件
  • 保持拆分,数据存状态管理

    net:ERR_CONTENT_LENGTH_MISMATCH 200 磁盘空间不足导致 nginx 转发接口异常

    接口状态:200,但返回数据有问题,接口提示 net::ERR_CONTENT_LENGTH_MISMATCH 200,涉及转发,真实接口用 postman 正常。
    注意:只要是状态码 200,但报很奇怪的错误,真实接口又正常的,多半是 nginx 转发问题,可能超过最大转发 size 限制。
    比如:

    injected stylesheet 广告屏蔽插件注入样式

    广告屏蔽插件:Adblock plus .advert-title 有被强制加 display: none important, 覆盖了原有样式

Vue3 watch Uncaught(in promise) TypeError: Object(…) is not a function

vue3 watch 可能会自动补全从 fs 引入,会导致该错误

2022-05-04

Vue.config.errorHandler 怎么将错误暴露到 window.error 事件

addEventListener 第三参数,必须使用 true,监听捕获阶段事件场景

错误上报 img, link, script src load error 默认冒泡阶段无法触发,需要在捕获阶段收集该错误

2022-04-27

document.referrer 与接口请求头 Referer 区别

用这个 document.referrer 获取的,表示来源,如果是直接访问(新窗口打开,直接输入 url)。这个值为空 https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Referer
Chrome Network 面板中接口的 referer 是当前接口请求时所在的页面,location.href

2022-04-19

vue3 firefox 页面空白 SyntaxError: invalid property id

firefox 浏览器版本过低问题,升级浏览器版本即可
image.png

2022-04-14

iconfont svg fill 与 stroke 问题

iconfont 需要是 fill 填充的颜色,但这种图标是 stroke 描边的
https://iconly.io/tools/svg-convert-stroke-to-fill 这个可以转,stroke to fill

2022-04-02

vue3 defineExpose 暴露的变量不能用 useXXX 包裹

defineExpose 暴露的变量,位置会影响编译结果

const useXXX = () => {
  // const selectList = ref([]) // error
  return { selectList }
}

const { selectList } = useXXX()

// 需要放到外面才不会报错
const selectList = ref([])
defineExpose({
  selectList
})

2022-03-31

vue3 dev 没问题,build 分布后报错 TypeError: Cannot read properties of null (reading ‘insertBefore’)

npm run dev:test 开发环境没问题, build 后部署到测试环境就有问题
TypeError: Cannot read properties of null (reading ‘insertBefore’)
虽然 el-table data 数组为空数组 ([]) 时,下面的 el-table-column 不会执行,但 vue3 + element-plus build 后会走这里的逻辑,需要加 ?. 防止 undefined 后取值的场景
scope.row.memberList.map(item => item.name).join(‘,’)
改为 scope.row.memberList?.map(item => item.name).join(‘,’)

2022-03-22

为什么 () => {a:2} 没问题,但 () => ({a: 2, c: 3}) 要用 () 包裹

image.png
转 AST 时,a: 1 被解析为一个块语句,而 a:1, b: 2 直接 parse error, ast 直接解析错误
let test = () => { a: 1} 相当于 function test() { a: 1 }
let test = () => { a: 1, b: 2} 相当于 function test() { a: 1, b: 2}
https://esprima.org/demo/parse.html AST 在线解析
参考:

ESLint 和 TSLint 的区别?

.eslintrc.js 中有 ts 相关

module.exports = {
  root: true,
  env: {
    node: true,
  },
  extends: [
    "plugin:vue/vue3-essential",
    "eslint:recommended",
    "@vue/typescript/recommended",
    "plugin:prettier/recommended"
  ],
  overrides: [
    {
      files: [
        "**/__tests__/*.{j,t}s?(x)",
        "**/tests/unit/**/*.spec.{j,t}s?(x)"
      ],
      env: { jest: true }
    }
  ]
}

eslint、tslint、babel 都是先转成 AST,再分析判断
tslint 团队弃坑了,也转向使用 eslint,将 ts 作为一个选项集成到 eslint 中
eslint 虽然自己实现的 parser,但它毕竟主要是来做代码的逻辑和格式的静态检查的,在新语法的实现进度上比不上 babel parser。因此 eslint 支持了 parser 的切换,也就是可以配置不同的 parser 来解析代码。配置文件里可配置不同的 parser,并通过 parserOptions 来配置解析项

  • 可通过 @babel/eslint-parser 来切换 babel 的 AST,它也是 estree 系列,但是支持的语法更多,在 babel7 之后,支持 typescript、jsx、flow 等语法的解析

    {
    parser: "@babel/eslint-parser",
    parserOptions: {
      sourceType: 'module',
      plugins: []
    }
    }
    
  • 可通过 @typescript-eslint/parser 来切换到 typescript 的 parser,它可以 parse 类型的信息

    {
    "parser": "@typescript-eslint/parser",
    "parserOptions": {
      "project": "./tsconfig.json"
    }
    }
    

    egg.js 和 nest.js 的区别

    egg.js 基于 koa,js 为主, nest.js 基于 express,ts 为主

    nprogress 进度条是用来干啥的?

    https://madewith.cn/23 顶部进度条 ```javascript import NProgress from ‘nprogress’ import type { UserModule } from ‘~/types’

export const install: UserModule = ({isClient, router}) => { if (isClient) { router.beforeEach(() => { NProgress.start() }) router.afterEach(() => { NProgress.done() }) } }

<a name="APRou"></a>
### 淘宝 npm 镜像地址变更,为啥?github clone 加速 cnpmjs.org 为什么失效了?
参考:<br />http://npm.taobao.org 和 http://registry.npm.taobao.org 将在 2022.06.30 号正式下线和停止 DNS 解析。<br />域名切换规则:

- [http://npm.taobao.org](https://link.zhihu.com/?target=http%3A//npm.taobao.org) => [http://npmmirror.com](https://link.zhihu.com/?target=http%3A//npmmirror.com)
- [http://registry.npm.taobao.org](https://link.zhihu.com/?target=http%3A//registry.npm.taobao.org) => [http://registry.npmmirror.com](https://link.zhihu.com/?target=http%3A//registry.npmmirror.com)

原因:taobao.org 的域名备案信息跟 npm 镜像的网络经营许可范围不一致,不能继续使用。from 苏千<br />查看配置<br />npm config list<br />registry="https://registry.npm.tabobao.org"

![image.png](https://cdn.nlark.com/yuque/0/2022/png/220475/1656691234357-f2772015-00fe-4011-b600-465ed781ffb1.png#clientId=u12a98b57-753c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=306&id=u9eca22d5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=306&originWidth=688&originalType=binary&ratio=1&rotation=0&showTitle=false&size=48821&status=done&style=none&taskId=u25ceb7b1-368f-48c3-8ddd-d045416c87f&title=&width=688)
<a name="n5rnF"></a>
### vueuse 是干啥的?

VueUse is a collection of utility functions based on [Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html). We assume you are already familiar with the basic ideas of [Composition API](https://v3.vuejs.org/guide/composition-api-introduction.html) before you continue.<br />主要是 composition api 工具库,收集常用的共性功能,但个人感觉不是刚需,但可以去看看,会发现一些有趣实用的功能,比如:

- 操作 css 变量 useCssVar
- useEyeDropper EyeDropper API 吸管工具 api,比如 chrome 内置的 color 还 6
- 是否是长按 onLongPress
- 反馈,区域选中,可以参考: useelementbypoint
- 视觉差 useParallax
- 拖拽 useDraggable
<a name="vy06z"></a>
### vite 支持的框架 vanilla、preact、lit、svelte 是啥?
npm init vite@latest<br />select a framework<br />vanilla<br />vue<br />react<br />preact<br />lit<br />svelte
<a name="L2sWE"></a>
### vite 自带 vue-ts 脚手架,默认仅只是 ts+vite+vue,没有可选的 vue-router/vuex 等,为什么?
相比 vue/cli 创建的项目来讲,vite cli 可选项少了很多。官方推荐使用社区的脚手架(社区模版)来创建依赖 <br />比如:

- Vitesse - Opinionated starter template 夹带私货较多,很多不需要的
   - unplugin-vue-components  components auto import 组件自动导入,不需要手动 import,命名冲突需要考虑
   - unplugin-auto-import  Directly use Vue Composition API  and others without import 有点像 mixin,可能会导致不好维护。增加维护成本,都不知道这个方法、组件从哪来的
   - 如果想看 e2e test 示例,可以看看这个仓库
- Vitalis - Vue 、Vue Router 4、TypeScript、Tailwind CSS、ESLint、Prettier 看起来可以,不过可以参照这个,弄一个自己的脚手架
<a name="dQcwF"></a>
## 2022-03-21
<a name="iEXJQ"></a>
### git 提交代码分支提错了,并 push 了,怎么回退并还原远程分支代码
<a name="jUGBU"></a>
### git 怎么删除远程分支
删除本地分支:git branch -d 分支名<br />删除远程分支: git push origin -d 分支名<br />其中 -d 是 '--delete' 的缩写<br />参考:
<a name="Pw2bF"></a>
## 2022-03-11
<a name="CWbs9"></a>
### ElementPlusError: [ElPagination] 你使用了一些已被废弃的用法,请参考 el-pagination 的官方文档
total、page-count 传参为 undefined 这里提示有问题,如果是 "" 字符串也会提示:<br />ElementPlusError: [ElPagination] 你使用了一些已被废弃的用法,请参考 el-pagination 的官方文档<br />[Vue warn]: Invalid prop: type check failed for prop "pageCount". Expected Number with value 0, got String with value "".
<a name="myTGX"></a>
## 2022-03-10
<a name="AFGS5"></a>
### `/deep/`实现原理,scoped 原理?
<a name="y22nS"></a>
## 2022-03-04
<a name="nIjb4"></a>
### svg-icon 组件封装时为什么以 i 为父元素,为什么还需要单独 svg 内容组件
i 标签支持 font-size 调节大小,只需设置如下样式即可。参考 element-plus 组件 svg-icon 封装<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/220475/1656687911652-9ae6a95b-b745-4a03-bc3d-0202a1b7bf26.png#clientId=u12a98b57-753c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=292&id=u7202769b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=238&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25528&status=done&style=none&taskId=u9349a03a-2040-4175-ad2f-9ae4682db9e&title=&width=238)<br />为什么还需要单独给出 svg?<br />如果不单独给出 svg,都用 i 包裹,<svg-icon> 组件上直接加 `@click`事件需要加 .native,另外 v-popover: popover 这种指令也不会生效。
<a name="C4qu1"></a>
## 2022-02-17
.npmrc 配置某个 npm 包安装使用 xnpm 私服<br />`npm install @someName/util@latest --registry=http://npm.xxx.com --save` <br />.npmrc
```javascript
@someName:registry=http://npm.xxx.com

/deep/ Syntax Error: SassError: expected selector.

使用 /deep/ 报错,使用 ::v-deep 替换 /deep/ 成功解决

2022-02-16

Eror: EPERM: operation not permitted, unlink ‘.node-sass.DELETE\vendor\win32-x64-83\binding.node’

windows 系统 npm install 错误
关掉正在运行的 npm run dev 服务,再次安装就好了

2022-02-15

版本更新工具 select-version-cli

基于 package.json 版本号,自动选择版本

export * from ‘./xxx’

会把 xx 中所有的非 default 导出

UMD 打包方式,全局变量的暴露方式

看 root 或 global 下绑定的变量名

 1 (function (root, factory) {
 2     if (typeof define === 'function' && define.amd) {
 3         // AMD
 4         define(['jquery', 'underscore'], factory);
 5     } else if (typeof exports === 'object') {
 6         // Node, CommonJS之类的
 7         module.exports = factory(require('jquery'), require('underscore'));
 8     } else {
 9         // 浏览器全局变量(root 即 window)
10         root.returnExports = factory(root.jQuery, root._);
11     }
12 }(this, function ($, _) {
13     //    方法
14     function a(){};    //    私有方法,因为它没被返回 (见下面)
15     function b(){};    //    公共方法,因为被返回了
16     function c(){};    //    公共方法,因为被返回了
17  
18     //    暴露公共方法
19     return {
20         b: b,
21         c: c
22     }
23 }));

2022-02-10

moment 文件过大,使用更轻量的 day.js 代替

day.js 与 moment API 使用方法基本一致,但体积要小很多,如下图
image.png
Lighthouse in chromeDevTools now recommends smaller libraries that import bundle size.
会体检使用 dayjs 来减少包体积
moment.js 已停止维护,为什么同样的实现,体积差距这么大。

git 新建远程分支命令

切换到 master 分支 git checkout master,拉取最新代码 git pull
基于当前分支,创建新分支,并切该分支:git checkout -b v1.x.x
推送到远程 git push,这时会提示一个命令,运行该命令即可

2022-01-26

input radio 确认后才能选中功能实现,怎么改变 radio checked 状态

radio checked 状态仅在首次渲染时才渲染,不能通过给 checked 实时赋值来实现状态切换

  1. 实时 v-if,confirm 取消时,重新渲染 radio(vue 设置为 false,nextTick 再设置为 true)改动较大,比较麻烦
  2. 更好的方法:阻止 radio click 的默认行为 v-on:click.native.prevent

额外加一个样式处理
.el-radio-button:focus:not(.is-focus):not(:active):not(.is-disabled) {
box-shadow: none;
}

在 vue 项目中,怎么调试 element 源码

修改 element 引入方式,在 node_modules 中修改 element diamante,加 log 下断点即可
// import ElementUI from ‘element-ui’
import ElementUI from ‘../../node_modules/elment-ui/src/index.js’

2022-01-21

下载 vue 3 源码后,npm install 提示异常,要使用 pnpm,什么是 pnpm,为什么用它替代 npm

This repository requires using pnpm as the package manager for scripts to work properly
image.png
什么是 pnpm?他比 npm 好在哪里
PnPM - Fast, disk space efficient package manager 快速的,节省磁盘空间的包管理工具
Motivation 初衷:节约磁盘空间并提升安装速度
Vue3 仓库是怎么实现当你使用 npm 时,提升使用 pnpm 的?
https://github.com/vuejs/core/blob/main/scripts/preinstall.js

if (!/pnpm/.test(process.env.npm_execpath || '')) {
  console.warn(
    `\u001b[33mThis repository requires using pnpm as the package manager ` +
      ` for scripts to work properly.\u001b[39m\n`
  )
  process.exit(1)
}

image.png

vue3 框架改进,新增 pinia 提供更简洁的状态管理,和 vuex 有什么区别

vuex 不好吗?为什么要出一个 pinia?
上下图的意思来看,vuex 不够简洁?pinia 做了哪些改进
image.png
官方解释:
pinia 在英语中发音类似 /peenya/ 是和 pina(西班牙语的 pineapple 菠萝)最接近的词。
油管发音: /‘pi: ni ə/ https://www.youtube.com/watch?v=Ok6vO98RV_Q
Emmanuel John,pinia 是轻量级的,体积很小,适合中小型应用。低复杂度 vue.js 项目
vuex 用于中小型 vuejs 项目是过渡的,太少重量级的,对性能有一定影响。适合大型、复杂度高项目

公共 cdn 隐患,如需使用一定要指定版本号

vue3 版本成为默认版本后,cdn 未指定版本的 vue.min.js 将由原来的 vue2 变为 vue3
应该始终在生产环境指定一个版本范围,以避免意外的加载到未来的大版本。
image.png

2022-01-20

git cz 提交代码偶现 dirname: write error: Bad address /husky.sh: No such file or directory

dirname: write error: Bad address
.git/hooks/commit-msg: line 8 /husky.sh No such file or directory
git exited with error code 1
重复 git cz 再提交一次就好,why

2022-01-18

ResizeObserver loop limit exceeded, el-table 宽度改变时报错

image.png
类似 https://blog.csdn.net/cindy647/article/details/106523180
el-table/src/layout-observer.js
el-table/src/resize-event.js

CI/CD 部署构建时的 terminal log 是怎么做到实时显示在网页里的

node 可执行 shell 脚本,但怎么收集脚本的 log 反馈给前端

CI/CD 服务器构建部署命令理解 /dev/null 2 >&1

构建

export PATH=~/.nvm/versions/node/v14.17.5/:PATH
node -v
npm install
npm run build:test
zip -ry node_modules.zip node_modules > /dev/null 2>&1
zip -ry xxxx.zip * -x "./node_modules/*" > /dev/null 2<&1

部署

启动: unzip node_modules.zip > /dev/null 2>&1 && rm node_modules.zip && npm run start:test
停止:which "npm" > /dev/null 2>&1 && npm run top

地图相关

leafletjs.com
maptalks.org
mapbox.com/maps/

2022-01-17

超精简的编译器实现 - js

https://github.com/jamiebuilds/the-super-tiny-compiler
https://github.com/jamiebuilds/the-super-tiny-compiler/blob/master/the-super-tiny-compiler.js

2022-01-14

为什么要使用 el-scrollbar,虚拟滚动条怎么实现的,有哪些坑

虚拟滚动,长列表分页;el-table 高度滚动时,底部方便操作滚动条

vue component 组件引入时() => import() 写法与常规写法有什么区别

impot xxx from ‘xx’
components: { xxx }
简写
components: {
xxx: () => import(‘xx’)
}

What’s New in DevTools(Chrome 98)

https://developer.chrome.com/blog/new-in-devtools-98/#chrome98
Chrome 59 新增,CSS and JS code coverage
Full-page screen 截长图功能,注意:
1、必须点击模拟器才能看到入口 F12 移动端
2、像 aos 这种下拉动态显示的需要滚动到底部,先让内容完全加载出来再截图
3、不支持 el-scrollbar 这种虚拟滚动条截长图

性能优化相关

,录视频,写总结文章

element 源码相关

  • select 组件 搜索默认值为 ID,研究
  • table 展开、吸顶
  • el-form validate
  • 级联选择器的全选
  • el-draw 打开速度研究
  • el-upload 图片过渡动画逻辑
  • element 多版本共存研究/样式污染研究

2022-01-13

单元测试为什么使用 jest,而不是 mocha

mocha 使用时需要配合多个库使用,比如 istanbul(测试覆盖率) + chai(断言) + sinon(Mock)
Jest 默认支持断言、测试覆盖率、Mock,更简单
image.png

  • Mocha 生态最好,但是需要较多的配置来实现高扩展性
  • Ava轻量、高效且简单,但自身不够稳定,并发运行文件多的时候会撑爆CPU
  • Jest 开箱即用

node 项目引入 jest 注意事项

1、引入 jest

npm install --save-dev jest

在 package.json 里面加入下面的代码,npm run test 可执行测试

"script": {
  "test": "jest --coverage"
}

jest 不需要单独的 test 目录,他会自动匹配目录下的内容 testMatch: **/**test**/*.[tj]s?.(x)
2、运行
npm run test
Syntax Error: Cannot use import statement outside a module
jest 是运行在 node 环境的,所以不支持 es6 语法,我们需要通过配置 babel 来讲 es6 转 es5 语法

npm install --save-dev babel-jest @babel/core @babel/preset-env

babel.config.js:Error while loading config - You appear to be using a native ECMAScript module configuratoin file, which is only supported when runing Babel asynchronously.
默认 type: “module” 后,自动识别为 .mjs 必须是异步,使用 .cjs 后缀即可。
3、初始化配置

npx jest --init

4、eslint: jest test is not defined 配置

// .eslintrc.json
{
  jest: true 
}

参考:

why test file naming spec.js

vue .spec.js,stylelint .test.js

node 项目从 0 到 1 引入 eslint + prettier, 支持 es module

1、初始化 package.json

npm init -y

2、新建 src 目录,添加测试代码,引入 eslint + prettier

npm install eslint --save-dev
# eslint 中引入 prettier
# eslint-plugin-prettier 在 eslint 流中引入 prettier
# eslint-config-prettier 解决 eslint 和 prettier 的冲突配置
npm install prettier eslint-plugin-prettier eslint-config-prettier --save-dev

3、初始化 .eslintrc.js

module.expors = {
  env: {
    node: true,
    es2021: true
  },
  plugins: ['prettier'],
  extends: ['eslint:recommended', 'prettier'],
  parserOptions: {
    ecmaVersion: 13,
    sourceType: 'module'
  },
  rules: {
    'prettier/prettier': 'error'
  },
  jest: true
}

4、.prettierrc.json

{
  "printWidth": 120,
  "tabWidth": 2,
  "semi": true,
  "singleQuote": true,
  "trailingComma": "none",
  "arrowParens": "avoid",
  "bracketSameLine": false
}

注意:echo {} > .prettierrc.jsonwindows 电脑要注意执行后默认的编码是否为 UTF-8,可能是其他编码,导致配置文件 json 解析错误,eslint 不生效。

单元测试学习推荐的项目

lodash、loadsh-es 源码:纯 js、适合入门,碎片化学习
promise 实现 、
vue3 源码,单测+e2e
stylelint 源码,偏 node,有测试覆盖率检查钩子

2022-01-12

qiankun 微服务 vuex devTools 使用问题

2022-01-10

正则相关 match、exec、test、search、matchAll 方法有什么区别?

title.match(/[|]/g).length > 4
exec global 或 sticky 场景下 lastIndex 记录

const pattern = /\{([^}]+)\}/g;
let match = pattern.exec(str);
let arr = []
let copyStr = str
while(match) {
  arr.push(match[1])
  str = str.replace(match[0], '')
  match = pattern.exec(copyStr)
}

new RegExp(‘[^[]+(?=\)]’, ‘g’) 这个正则是什么意思?

‘xx[123]xx[abc]xx’ 匹配括号内容 value: [‘123’, ‘abc’]
可视化正则 https://regexper.com

http2 一定要使用 https 吗?

2022-01-06

对于键值的频繁操作场景,为什么 map 比 object 性能更高?

JS 数组 sort 内部使用算法是什么?快排?

什么情况需要看 v8 源码

js if(true) 代码块中函数变量提升的问题

JS 存键值对可以用对象,为什么还需要使用 Map?

  • object 的 key 只能是 String 和 Symbol,而 map 的 key 可以是任意类型。A Map’s keys can be any value (including functions, objects, or any primitive).
  • object 的 key Value 是无序的,而 map 是有序的(以插入顺序排序)The keys in Map are ordered in a simple, straightforward way:A Map object iterates entries, keys, and values in the order of entry insertion.
  • object 的键值对大小需要手动计算,而 map 有 size 属性直接取
  • object 先要获取 key 数组再进行迭代,而 map 能直接进行迭代
  • object 有原型对象有可能有 keyName 冲突,map 可以是无原型对象
  • 频繁增删 map 更快;performs better in scenarios involving frequent additions and removals of key-value pairs.(MDN)

有了 Map 为什么还要有 WeakMap?
主要是为了性能,没有强引用的键,有利于垃圾回收。由于不可迭代,因此必须知道键才能取到值,类似于私有属性。
为什么 map频繁增删比对象快?
map 属于字典数据类型,数据结构与算法 - 字典, why
参考:

  • Map - MDN

    2022-01-05

    vue 中加 key 在 diff 算法中的具体逻辑

    2022-01-04

    微服务 App.vue 样式污染问题

    子应用 App.vue 需要加 scope 样式,否则会污染,需要特别注意

    element rules 中,validate 对应的 callback 机制分析

    why not need use vuex in vue3?

    element plus button size 为 normal 时 warning 文档更新

    为什么 vue3 中 vuex useStore() 要放到 computed 中调用?

    vite 为什么 import { store } from ‘vuex’ 后出现 default is not defined

    vite 遍历文件

    import.meta.globEager()
    let routeRequires = import.meta.globEager('./modules/*/route.ts');
    let moduleRoutes = []
    Object.keys(routeRequires).forEach(index => {
      moduleRoutes = moduleRoutes.concat(routeRequires[index].default)
    })