Skip to main content

写 bug 写不够

· One min read
zhang13pro
非著名前端

Vue.js @2.1.6

input 框将无法被选中,似乎 click 事件传播影响到了 input check

可以使用 .self 修饰符修饰 click 事件

new Vue({  el: "#app",  data: function () {    return { num: 1, checked: false }  },  template: `  <div @click="add">     click {{ num }}     <input type="checkbox" v-model="checked">   </div>`,  methods: {    add: function () {      this.num++    },  },})
  • stopImmediatePropagation 阻止监听同一事件的其他事件监听器被调用。
<!DOCTYPE html><html>  <head>    <style>      p {        height: 30px;        width: 150px;        background-color: #ccf;      }      div {        height: 30px;        width: 150px;        background-color: #cfc;      }    </style>  </head>  <body>    <div>      <p>paragraph</p>    </div>    <script>      const p = document.querySelector("p")      p.addEventListener(        "click",        (event) => {          alert("我是p元素上被绑定的第一个监听函数")        },        false      )
      p.addEventListener(        "click",        (event) => {          alert("我是p元素上被绑定的第二个监听函数")          // 阻止click事件冒泡,并且阻止p元素上绑定的其他click事件的事件监听函数的执行.          event.stopImmediatePropagation()        },        false      )
      p.addEventListener(        "click",        (event) => {          alert("我是p元素上被绑定的第三个监听函数")          // 该监听函数排在上个函数后面,该函数不会被执行        },        false      )
      document.querySelector("div").addEventListener(        "click",        (event) => {          alert("我是div元素,我是p元素的上层元素")          // p元素的click事件没有向上冒泡,该函数不会被执行        },        false      )    </script>  </body></html>

nextTick 原理#

fix#

always use microtasks for nextTick

Vite 的简单实现

· 2 min read
zhang13pro
代码狗

实现一个简易的 Vite 打包 .vue 文件

前端工程化辨析#

webpack 的核心原理就是通过分析 JavaScript 中的 require 语句,分析出当前 JavaScript 文件所有的依赖文件,然后递归分析之后,就得到了整个项目的一个依赖图。对图中不同格式的文件执行不同的 loader,比如会把 CSS 文件解析成加载 CSS 标签的 JavaScript 代码,最后基于这个依赖图获取所有的文件。

代码打包处理之后,放在内存中提供给浏览器使用,然后 dev-server 会启动一个测试服务器打开页面,并且在代码文件修改之后可以通过 WebSocket 通知前端自动更新页面,也就是我们熟悉的热更新功能。

针对 webpack 这种打包 bundle 的思路,社区就诞生了 bundless 的框架,比如 Vite。之所以要使用 webpack 是因为浏览器里的 JavaScript 没有很好的方式去引入其他文件。但是这个世界唯一不变的就是变化本身,属于大人的时代终究会变。

且看 ES6 的 module 功能:

<script type="module" src="/src/main.js"></script>

Vite 原理#

Vite 就是借助了 ESModule 的编译时静态分析,不需要打包所有的依赖,大大减少项目的冷启动时间。

import { createApp } from "vue"import App from "./App.vue"import "./index.css"
const app = createApp(App)app.mount("#app")

TypeError: Failed to resolve module specifier "vue". Relative references must start with either "/", "./", or "../".

剩下来要做的就是

  • 找到 node_modules 下的依赖
  • 加载非 js 文件,如 .css .vue

流程:

  1. 请求 首页http://xxx.xxx.xxx/
  2. 返回 index.html
  3. 请求 /src/main.js
  4. 发现请求 js 文件,替换路径为相对路径后,返回修改后的 js 文件
  5. 请求 @module/vue
  6. 发现请求@module 内的文件,替换文件内为相对路径后,返回 package.json 中 module 定义的入口文件
  7. 请求 ./App.vue
  8. 判断 .vue 的请求后,通过 compilerSFC.parse 解析 Vue 组件,通过返回的 descriptor.script 获取 js 代码
  9. 请求 ./App.vue?type=template
  10. 调用 compilerDom.compile 解析 template 内容,直接返回 render 函数

热更新#

客户端和服务器建立 WebSocket 连接,服务器监听文件变化,通过 WebSocket 去通知浏览器进行相应更新。

小结#

webpack 启动服务器之前需要进行项目的打包,而 Vite 则是可以直接启动服务,通过对浏览器运行时的请求拦截,实现首页文件的按需加载,这样开发服务器启动的时间就和整个项目的复杂度解耦。任何时候我们启动 Vite 的调试服务器,基本都可以在一秒以内响应,这极大地提升了开发者的体验,也是 Vite 的使用率越来越高的原因。

Vite 的主要目的就是提供一个调试服务器。Vite 也可以和 Vue 解耦,实现对任何框架的支持,如果使用 Vite 支持 React,只需要解析 React 中的 JSX 就可以实现。只需要使用框架对应的 Vite 插件就可以支持任意框架。

Vite 能够做到这么快,还有一部分的原因是使用了 esbuild 去解析 JavaScript 文件。esbuild 是一个用 Go 语言实现的 JavaScript 打包器,支持 JavaScript 和 TypeScript 语法,现在前端工程化领域的工具也越来越多地使用 Go 和 Rust 等更高效的语言书写,这也是性能优化的一个方向。

如果一个模块文件是分散的,导致 Vite 首页一下子要加载 1000 个 JavaScript 文件的情况通常需要进行依赖预构建

对现代前端框架的理解

· One min read
zhang13pro
代码狗

我属于后 JQuery 时代的前端开发,但多少了解 JQuery 的开发模式。

命令式与声明式#

显然,JQuery 属于命令式开发模式,改变状态 + 操作 DOM。对应的,Vue、React、Angular 属于声明式,声明式是通过描述状态与视图之间的映射关系,通过改变状态改变视图。这样就从传统的 DOM 操作解放出来,可以说,现代框架是 Web 应用复杂化后必然的产物。

只维护状态而不关注如何操作 DOM 大大降低了代码的维护成本。但随着项目的愈来愈复杂,维护状态也变得艰难起来,所以才出现了 Vuex,Redux 等解决方案。

渲染(render)#

状态改变到视图更新需要渲染,换句话说,将状态生成 DOM 插入到页面展示在用户界面上,这一套流程叫做渲染。可以用一个公式表示:

UI = render(state)

当状态改变需要重新渲染页面,当涉及到的 DOM 标签少时使用innerHTML可以将页面整体刷新,框架如何实现局部刷新呢?

这个问题,现代框架提供了不同的解决方案。如 Vue 和 React 的 VirtualDOM,Angular 的脏检测机制,也可以是 Vue1.0 中的细粒度绑定。

参考#

聊聊我对现代前端框架的认知 —— berwin

每个人都是"文盲"

· One min read
zhang13pro
代码狗

旧时光里和大姐发生争执,因为我不知道阳光房是什么,sister 觉得这很离谱。

此后我想,要是有人问我袁隆平是谁?我不会震惊于他知识的贫瘠程度,每个人都有认知局限。总要允许有人暂时的不知道,即使这听起来很离谱,大人不是生下来就是大人的,不是吗?

对于不感兴趣的领域,绝大多数人都是文盲。

成为 Coder ,英语不好,会显得像个文盲,对此我有话语权。

不喜欢篮球的人,不会知道走步、二运、侵犯圆柱体指什么;

不喜欢编程的人,不会知道 new 一个对象、

talk is cheap,show me the code;

不喜欢摄影的人,不会知道光圈、感光度,更不会知道 J-cut、L-cut

......

好啦,我唯一想说的是,每个人都有认知缺陷。理解人的局限性,才能宽恕他人也放过自己。

开音训练

· One min read
zhang13pro
代码狗
  1. 将嘴完全打开。
  2. 深吸一口气,肚子变大。
  3. 手指感受 👂 旁边的下陷。
  4. a aaa aaaaa~

Windows 配置 oh-my-zsh

· One min read
zhang13pro
代码狗
  1. Windows search Ubuntu 下载子系统
  2. Windows search Windows Terminal
  3. 打开下好的 Ubuntu(设置账户密码) 下载 zhs
sudo apt install zsh
  1. Install oh-my-zsh now
$ sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)"
  1. 配置文件
code ~/.zshrc

司机

· One min read
zhang13pro
代码狗

“9531”,“已接到乘客,请提醒乘客系好安全带。”

大晚上赴朋友约,突然看到师傅后视镜上有一只小黄鸭,头上的“竹蜻蜓”转个不停。我打趣道,这个不会飞了吗?

“不会,底下有个卡扣。像左边直接贴上去的已经飞走了”。师傅被我打开了话匣子,“开夜车就怕遇到喝醉的,吐车上一晚上就不用干了。我之前当过公安,很辛苦,一个月唯一的一天假就只想窝在家里睡觉......”

为人民服务这几个字的分量很重,我不够伟大,选择了更自私的道路——为自己而活。

“里尔登先生,”弗兰西斯科的声音郑重而平静,“假如你看到阿特拉斯神用肩膀扛起了地球,假如你看到他站立着,胸前淌着鲜血,膝盖正在弯曲,双臂颤抖,但还在竭尽最后的气力高举起地球,他越努力,地球就越沉重地向他的肩膀压下来——你会告诉他该怎么办?”

“我……不知道。他……能怎么样?你会告诉他什么?”

“耸耸肩。”

成年第一课

· One min read
zhang13pro
代码狗

第一,设置安全边界。知道什么能做,什么不能做,别陷入灾难决策。

第二,不要轻易被束缚。无论是两性间关系还是像车房这样的债务。

第三,认清人际交往的虚实。别 ™ 什么都信,一定要有自己的判断。