一个模拟的数字和指针时钟的视觉效果。通过以下方式实现:
表盘和刻度:使用#watch .frame-face和#watch .minute-marks li定义了时钟的表盘和分钟刻度。
指针:通过#watch .hours-hand、#watch .minutes-hand和#watch .seconds-hand定义了时钟的时针、分针和秒针。这些指针使用CSS的transform属性来设置初始位置,并使用@keyframes动画使它们随时间旋转。
数字显示:#watch .digits li定义了数字时钟的样式,而#watch .digital-wrap定义了数字显示区域的样式。
动画:使用@keyframes定义了三个动画:hours、minutes和seconds,分别用于驱动时针、分针和秒针的旋转。还有一个dsm动画用于数字时钟的显示。
视觉效果:通过渐变背景、阴影和边框等CSS属性,增强了时钟的视觉层次感和真实感。
响应时间变化:时钟的指针和数字会根据当前时间动态更新,以反映准确的时间。
通过纯CSS创建了一个视觉上吸引人的时钟,它不仅显示时间,还通过动 ...
本章目标:
计算属性的实现原理,如何实现 lazy ,缓存,解决嵌套问题?
watch 是如何实现监听对象变化,并调用回调函数的?监听对象和监听getter函数的区别?
立即执行的 watch 是如何实现的?如何决定回调执行时机?
……
4.8 计算属性 computed 与 lazy上面实现的 effect 会立即执行传入的副作用函数,有时候我们并不希望立即执行,而是需要的时候才执行。例如计算属性。可以通过在 options 中配置 lazy 属性达到目的。
effect(() => {
console.log(obj.foo)
}, {
lazy: true
})
在 effect 函数中就可以根据 lazy 属性确定是否执行副作用函数:
function effect(fn, options={}) {
const effectFn = () => {
// 调用 cleanup 完成清除工作
cleanup(effectFn)
// 当前激活 ...
本章目标
本章目标:
讨论什么是响应式数据和副作用函数,实现一个相对完善的响应式系统
如何避免无限递归?
为什么需要嵌套副作用函数?
两个副作用函数之间会产生哪些影响?
……
4.1 响应式数据和副作用函数
副作用函数:是指执行会直接或间接影响其他函数执行的函数。例如,一个函数内修改全局变量的值,函数就是一个副作用。
响应式数据:在一个副作用 effect 函数中读取对象 obj 的 text 属性值,在对象 obj.text 值发生变化后,副作用 effect 函数自动执行。那个这个对象 obj 就是响应式数据。
4.2 响应式数据的基本实现如果要实现 obj 成为响应式数据,需要拦截对象的读取和设置操作。
在读取字段 obj.text 时,把副作用函数 effect 存储“桶”中。
在设置字段 obj.text 时,把副作用 effect 从 “桶”中取出并执行即可。
在 Vue2 中使用 Object.defineProperty 函数实现。在 Vue3 使用代理对象 Proxy 实现。
123456789101112131415161718192021222324 ...
前言SQLite 是一种嵌入式数据库,它的数据库就是一个文件。
Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server. 它具有强大的事务支持, 关联关系, 预读和延迟加载,读取复制等功能.
基于 Sqlite3 的项目,直接是用 Sequelize 进行对象和表的映射。
环境配置12// 安装npm i sequelize sqlite3 -S
项目结构
配置文件夹 config123456789101112// config/config.jsconst path = require('path')const sqlite3 = require('sqlite3').verbose()module.exports = { test: { storage: path.join(__dirname, '../db/db_test.sqlite'), // ...
写在前面的话项目结构
1、配置 Server 打包位置12345678910// vue.config.jspluginOptions: { electronBuilder: { builderOptions: { //... // 匹配server中的所有文件夹和文件 extraResources: ['server/**/**'] // 指定打包 Server 到 Resource 文件夹中。 } }}
会将 server 文件夹打包到 Resources 文件夹中。为什么不打包大 app.asar 中呢?因为.asar 文件是只读的,无法进行数据库的写入。
2、配置webpack1234// vue.config.jsconfigureWebpack: { externals: ['pg', 'sqlite3', 'tedious', 'pg-h ...
写在前面的话在做前端项目时,需要将 Web 项目打包成 Win 应用,使用 Electron 相关技术。这个系列是整理 Electron 学习中遇到的问题和常见知识点,留做记录方便后续复习。
本篇介绍:
Electron 系统托盘实现
Electron 开机自动启动
系统托盘 && 开机自启在 Electron 中提供了系统托盘的 API - [Tray],参考后面的链接。所有需要引入Tray 和 Menu。
1234// main.jsimport { Menu, Tray } from 'electron'// 定义全局托盘let tray = null // 局部的会销毁。《=== 如果不定义成全局的,应用启动后托盘一闪就没了,^_^
目标系统是 win ,其他的平台限制请参考文档。 通过 process.platform 限制系统。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 ...
前言
本文作为学习笔记,文中内容大多来自官方文档和一些资料,摘抄的部分会在文中标注出原文地址,可以直接参考原文。
前两篇学习了 TS 中基本类型、函数、类、接口、泛型以及高级类型概念和使用方法。这些是基础知识点,虽然简单但是很重要。本文将复习 JS 中的模块对比不同方式模块的区别;如何使用命名空间隔离代码;声明合并的规则等。
模块在 ES6 之前采用的模块加载方案,主要有 CommonJS 和 AMD 两种。前者用于服务器,后者用于浏览器。ES6 在此基础上实现了模块的功能,使用简单可以完全取代之前的方案,成为浏览器和服务器通用的模块解决方案。
下面学习 ES6 中模块的导出和导入。
导出ES6 提供了多种导出方式,例如:单独导出,批量导出、导出接口/函数、导出起别名、默认导出以及复合导出等。
导出使用 export命令,举个例子:
123456789101112131415161718192021222324252627282930313233// a.js// 单独导出export const a = 'a'// 批量导出const b = ...
前言
本文作为学习笔记,文中内容大多来自官方文档和一些资料,摘抄的部分会在文中标注出原文地址,可以直接参考原文。
上一篇学习了 TS 的基本数据类型、接口、函数和类等基本用法。接下来继续深入学习一些相对 JS 来说 TS 中新增的内容。
泛型
泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
下面通过一个例子来了解泛型,如何实现一个打印函数呢?
1234function log (value: string): string { console.log(value) return value}
上面的这个 log 方法,只能接收和返回 string 类型数据。如何才能让该方法接收和返回 string[] 类型的数据呢?
第一种方法:函数重载,通过重载可以动态的匹配符合的类型。
123456function log (value: string): string;function log (value: string[]): string[]function log (value: any): ...
前言
声明:本文中大量的来自 《TypeScript 文档》。
TypeScript 是 JavaScript 的一个超集,主要提供了类型系统和对 ES6 的支持,它由 Microsoft 开发,代码开源于 GitHub 上。随着 TypeScript 的发展,很多的库都在使用它进行开发和重写,如Vue3.0就是通过TS进行开发的。如果不会 TypeScript 根本就读不懂源码。所以说目前来学习TypeScript正是时候 ,让我们一起入门 TypeScript吧!
PS: 为了方便书写下面行文 TypeScript 简写为 TS,JavaScript 简写为 JS。
更新:2020-7-31
类型系统原始类型众所周知 JS 分为原始数据类型和对象类型。原始数据类型:boolean, number, string, null, undefined 以及 Symbol。另外,TS 中还提供了 any,never, tuple,void,enum 等。
在 TS 中使用了类型注解方式声明变量。如强类型语言中的变量类型一样,用于约束变量类型。
布尔值12345678let isDon ...
异步JS 是单线程的,对于耗时任务如果按照顺序执行,就会导致浏览器假死卡住。所以需要异步来处理耗时任务,当任务完成后才去处理。
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;
异步任务:不进入主线程,而进入任务队列中的任务,主线程完成一个事件循环空闲后,会从任务队列中读取新的任务进入主线程执行。
事件循环(Event Loop):只有执行栈中的所有同步任务都执行完毕,系统才会读取任务队列,看看里面的异步任务哪些可以执行,然后那些对应的异步任务,结束等待状态,进入执行栈,开始执行。
为什么JS要设计成单线程呢?
异步的解决方案回调函数早期常用的异步操作方式,有个致命的缺点,极容易写出回调地狱。
123456789ajax(url, ()=>{ // xxx ajax(url,()=>{ // xxx ajax(url, () => { // xxx }) })})
不利于代码阅读和维护,毕竟 ...