Vue.js系列:nexttick原理
本文尝试梳理在vue中,nextTick方法的实现原理使用:在下次dom更新结束之后,执行nextTick中的回调,这样我们就能拿到dom。
谈到nextTick就不得不说一说js执行环境的事件循环机制。js引擎首先会执行全局代码,并将其中的同步任务放入执行栈中执行。当遇到异步任务时,会将该根据任务类型放入不同的事件队列。比如settimeout、settimeinterval就放入宏任务队列。微任务塞入微任务队列。主执行栈执行完毕后,会按照微任务事件队列优先原则,取出任务执行。微任务空再去宏任务队列中拿。直到最后清空。
具体来说,当我们调用Vue的nextTick方法时,Vue会将回调函数放入一个回调队列中。在当前执行栈执行完毕后,Vue会检查是否存在微任务队列,如果存在,则将回调函数放入微任务队列中。
Vue.nextTick = function (callback) {
if (typeof Promise !== 'undefined') {
// 使用Promise的then方法作为微任务
Promise.resolve().then ...
electron系列:第一回
本系列开始,将逐步介绍前端的客户端经典框架–electron(系列文章)本文主要讲解electron的通信机制
首先祭出一张经典的图:
electron有且只有一个主进程,由package.json中的main字段定义,Electron 使用 Chromium 来展示 web 页面,每个页面运行在自己的渲染进程中。
一. 为什么这么划分根本逻辑:主进程拥有服务器端的能力,例如读写文件资源,渲染进程负责页面呈现。
二. 基本配置1. 创建app,主进程设置ipcMain,用来监听渲染进程事件
import { app, BrowserWindow, ipcMain } from 'electron'
import { handleGetAllCates, handleGetAllItems, handleGetVideo, getVideoContentVersionTwo } from '../src/utils/videoApi'
const fs = require('fs')
let mainWindow: BrowserWindow | ...
js的奇奇怪怪那些事儿
本文主要是记录一些关于js的奇奇怪怪的特性,题目为主
原型链 function F() {}
Object.prototype.a = function() {
console.log('a')
}
Function.prototype.b = function() {
console.log('b')
}
const f = new F()
f.a()
f.b()
// 输出
// a
// Uncaught TypeError: f.b is not a function
解答:
因为f首先是一个对象,通过原型链找到a方法输出a
通过new方法出来的f,本质上是基于F构造函数的原型对象{}生成,所以无b方法
js中的代码,是按顺序执行的吗先说结论:作为单线程的语言,当然是一行行按顺序执行,但也并不完全是,为什么?因为有个叫变量提升的骚操作。
// 事例1
showName()
console.log(myname)
var myname = '极客时间'
function showName() ...
性能的考量:第五回(长任务)
关于性能问题,我们前文介绍过了八股文篇、实战版本以及canvas性能相关的实操。今天,我们结合前文介绍过的google的performance工具,来更加深入的聊一聊。在web性能领域,有一个单独的单词long task,就是所谓的长任务。一般来讲,耗时超过50ms即可被认为长任务。这种长任务会导致什么结果呢?大佬解答:
If the user is attempting to interact with the page while a long task runs—or if an important rendering update needs to happen—the browser will be delayed in handling that work.
简言之:卡死你。
以目下的一个业务场景为例。该项目的某个页面加载耗时,长达6s。打开performance工具分析发现,符合长任务定义的操作,存在还不止一个,且单个耗时远超50ms,如下图所示:
针对上述的“long task”,我们怎么优化呢?
异步化任务
依据向主线程妥协的原则,有些场景下的一些任务,不 ...
Threejs系列:第三回
本文讲解纹理相关内容首先推荐个老外的站点,上面的各种纹理资源应有尽有,拿走不谢。https://ambientcg.com/list
所谓纹理,实质就是我们游戏制作过程中的贴图。比如通过下方代码,我们写了一个圆球体:
// 物体
const geometry = new THREE.SphereGeometry( 1);
const mesh = new THREE.MeshBasicMaterial({
color: 'green',
map: pi
})
const cube = new THREE.Mesh(geometry, mesh)
scene.add(cube)
效果如下:
是不是感觉很僵硬?不着急,我们在他的表面贴一张图片看看:
// 纹理
const texttureLoader = new THREE.TextureLoader()
// const pi = texttureLoader.load('./OutdoorHDRI078_1K-HDR.exr')
const pi = texttureLoader.load('./doo ...
Threejs系列:第二回
本文继续探索threejs,简单介绍几个基础组件,及如何将第三方软件绘制的模型导入。1. 我们希望他能够跟随鼠标的方向进行转动,如何实现?
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
...
...
// 设置轨道,实现鼠标拖动效果
setOrbit() {
this.orbit = new OrbitControls(this.camera, this.renderer.domElement)
// 搭配阻尼,效果更佳
this.orbit.enableDamping = true
},
2. 为了直观的研究坐标体系,我们就得先直观的看到。如何实现?代码如下:
// 添加坐标轴
setAxes() {
this.axesHelper = new Three.AxesHelper(500)
this.axesHelper.setColors('red','green','ora ...
Threejs系列:第一回
本文简单介绍threejs的基本内容。three.js官方定义的三大要素:场景(scene)、相机(camera)、渲染器(render)。我觉得还得加上一个物体(内容)。本文以一个简单的球形案例带大家一起入个门。(基于vue2)
首先html骨架代码,很简单:
<template>
<div class="circleEarth-container flex-cc">
<div id="container" ref="container" class="container"></div>
</div>
</template>
JS完整代码
const container = this.$refs['container']
let scene = new Three.Scene()
const geometry = new Three.SphereBufferGeometry(60, 40, 40)
const material = new Three.MeshStandardMa ...
webgl系列:第一回
本文简单介绍webgl基础什么是webgl
WebGL可以直接与HTML5标签Canvas进行集成,并且可以通过GPU来执行高性能图形计算。总结一下,WebGL的本质 —— JavaScript操作OpenGL接口。
那么什么是OpenGL?
OpenGL 通过为 3D 图形渲染的基本操作提供简单、直接的接口来满足这些标准。它支持点、线段、多边形和图像等基本图形基元,以及仿射和投影变换和光照计算等基本渲染操作 。它还支持高级渲染功能,例如纹理映射和抗锯齿。
看我专栏的因该都知道paperjs, 所以OpenGL基本可以理解为三维层面的paperjs。
Webpack系列:第六回
本文浅谈webpack的热更新机制啥是热更新?当我们对已经在运行的程序代码做些许修改时,页面能够自动的局部刷新,这就是热更新机制
如何实现的?
初次打包: 编译打包,生成bundle.js,然后开启一个静态资源服务器,根据对应的地址打开页面
开启热更新时改动代码:webpack重新编译 > 根据变化的内容生成俩文件:manifest.js及chunk.js,通过HMRserver主动推送给浏览器(本质一个websocket通信),浏览器根据manifest.js文件获取变化的内容,重新render。
注: bundlejs中除了自己写的模块代码,还包含了HMR-runtime
坦克大战:第二回
本文介绍第一回中主要功能的具体实现坦克类坦克实例对象初始化时,会绘制自身躯体,由三部分组成:坦克底座(Path.Rectangle)、炮塔(Path.Circle)及炮管(Path),具体代码如下:
init() {
this.path = new paper.Group({
children: [
// 炮身
new paper.Path.Rectangle({
name: 'base',
center: this.position,
size: new paper.Size(SIZE),
strokeColor: this.color
}),
// 炮管
new paper.Path({
name: 'turret',
segments: [this.position, this.position.add(this.direction)],
strok ...
