本文参加了 SegmentFault 思否年度征文「一名技术人的 2022」,欢送正在浏览的你也退出。

前言

时光如梭,岁月匆匆而过,2022年一转眼就曾经到了开端,往年的环境异常艰巨,可是想想本人这一年来的付出,也还是值得做一个复盘总结的,正所谓有得必有失,在这一年我失去了太多,不过却也让我成长了不少,当然这些都是题外话,我次要还是来复盘一下往年我所学习的成绩。

文章总结

往年一共写了11篇文章,加上本次年终总结,一共12篇,数量也并不多,别离如下:

  • 应用React手写一个手风琴组件
  • 手写一个有点意思的电梯小程序
  • 手写一个有点意思的电梯小程序(React版本)
  • 实现《羊了个羊》的小游戏
  • 50天用vue3实现了50个web我的项目,我学到了什么?
  • 手写一个mini版本的React状态管理工具
  • 实现《羊了个羊-美女版》小游戏(低配版)
  • 一个乏味的交互成果的实现
  • vue3实现一个思否猫连连看小游戏
  • 原生javascript手写一个丝滑的轮播图
  • 三分钟学会go语言的变量定义

其中尤其是50天用vue3实现了50个web我的项目,我学到了什么?实现《羊了个羊》的小游戏我最为称心,毕竟这两篇文章是我用心总结出每一个知识点,并且让本人死记硬背学到的知识点,同时也帮忙别人学到知识点那就足够了。

其实往年我次要重心放在了React技术栈上,所以我也用React写了不少货色,对于vue框架,尤其是vue3,最次要的输入就是50天用vue3实现了50个web我的项目,我学到了什么?,对于这50个我的项目其实尽管外表上写的是50天,但实际上我花了不止50天,当然这都不重要了,最重要的是我从这50个我的项目外面深刻去理解了一下less和sass这两门css预处理语言的语法。例如混入mixin,函数,循环,条件判断等,两种预处理语言之间也有很多雷同的中央,当然也有不同的中央。比方循环,咱们在sass当中会有@for关键字,而在less当中,咱们须要写选择器 + when(这种更像是在写递归调用本身)。

同时对于vue3的外围语法,我也有了肯定的认知,至多在理论做vue3的我的项目当中,我认为我还是没有多大的问题的,这些都是通过理论动手做这50个web我的项目让我学到的,为了不便我还特意用vue3写了一个对于这50个web我的项目的网站,地址在这里。

PS: 如果以上地址拜访不到,能够拜访这里。

这个网站是我本人设计并实现的,尽管布局看起来有些简略,然而我认为其中的逻辑性能和款式代码还是有点点难度的,在这里我能够总结一下有哪些知识点值得学习:

  • 实现一个clickOutside指令
  • 实现一个下拉框组件
  • 实现一个图片预加载组件
  • 实现classnames工具函数(不是复制的classnames源码,是参考实现的)
  • 实现文本超出省略的判断
  • 实现回到顶部的性能
  • 卡片组件以及图标组件的实现
  • less外围语法

以上是我往年在文章上所做的总结,除此之外我还在github上新增奉献并逐步完善了3个仓库,让咱们一起来看看吧。

3个我的项目

算法

对于剑指offer算法,我基本上曾经将剑指offer的官网算法题刷完了,并且解题思路,我也曾经记下来建了一个我的项目,地址在这里。

尽管在工作当中我仿佛并没有用到太多算法,可事实上做了一下算法题的确是关上了我的眼界,更何况,我也曾经将算法给加到了我所做的我的项目当中,比方那个用vue3实现连连看的小游戏外面就有这样一个算法。

const findRepeatItem = function (arr: GlobalModule.MaterialData[]) {    const unique = new Set();    for (const item of arr) {        if (unique.has(item.src)) {            return true;        }        unique.add(item.src);    }      return false;};

这个函数顾名思义,就是从数组当中查找反复项,思路就是利用set数据结构存储每一个数组项,而后当数据外面存在要查找的项的时候,就代表反复了,间接返回即可,这个函数的思路就来源于算法当中。也就是这个算法数组中反复的数字的思路二--哈希表解法。

这只是其中一个小小的利用而已,如果在理论我的项目当中碰到相应的需要,我或者也会再次回头来翻看这些笔记,已达到坚固并且触类旁通的目标,这个我的项目也就是我往年欠缺的3个我的项目之一。

js和css代码段

css代码段

这可能是我往年付出精力最多的一个我的项目了吧,简直每天都要奉献一段代码段,不信看下图:

每天学习一段javascript或者是css代码段,不至于让本人遗记css和js根底,而且很多代码段都会用到理论业务当中,比方应用css实现自定义的单选框和复选框,咱们以单选框作为示例讲一下实现思路如下。

css实现单选框

思路就是如下列出的几点,咱们就能够创立一个带有状态更改动画的款式单选按钮。

  • 创立一个 .radio-container 并应用 flexbox 为单选按钮创立适当的布局。
  • 重置 <input> 上的款式并应用它来创立单选按钮的轮廓和背景。
  • 应用 ::before 元素创立单选按钮的内圈。
  • 应用 transform: scale(1) 和 CSS transition 在状态变动时创立动画成果。

代码量也不算多,咱们来看html和css代码别离如下:

<div class="radio-container">    <input type="radio" class="radio-input" id="male" name="sex"/>    <label for="male" class="radio">男</label>    <input type="radio" class="radio-input" id="female" name="sex"/>    <label for="female" class="radio">女</label></div>
.radio-container {    box-sizing: border-box;    background-color: #fff;    color: #545355;    height: 64px;    display: flex;    justify-content: center;    align-items: center;    flex-flow: row wrap;}.radio-container * {    box-sizing: border-box;}.radio-input {    appearance: none;    background-color: #fff;    width: 16px;    height: 16px;    border: 1px solid #cccfdb;    margin: 0;    border-radius: 50%;    display: grid;    align-items: center;    justify-content: center;    transition: all .3s ease-in;}.radio-input::before {    content: "";    width: 6px;    height: 6px;    border-radius: 50%;    transform: scale(0);    transition: .3s transform ease-in-out;    box-shadow: inset 6px 6px #fff;}.radio-input:checked {    background-color: #2396ef;    border-color: #2396ef;}.radio-input:checked::before {    transform: scale(1);}.radio {    cursor: pointer;    padding: 6px 8px;}.radio:not(:last-child){    margin-right: 6px;}

都是惯例的布局,其中咱们次要利用了label的for属性和input的id属性绑定在一起,而后通过款式将input框给暗藏,批改label的款式去模拟出单选框,从而达到如下的成果:

同理,复选框也是这样的思路去实现的,事实上还有很多小技巧,比方暗藏一个元素,咱们通常可能会应用display和visibility又或者是opacity属性来达到暗藏,可事实上这三个属性暗藏元素或多或少都会有肯定的问题,比方display无奈增加过渡成果,而visibility又占用元素自身的空间,opacity只是单纯的设置透明度,元素仍然能够被点击等等,而这里咱们能够利用clip和定位来达到暗藏元素的目标,从而解决后面三个属性所带来的问题。代码如下:

.offscreen {    border: 0;    clip: rect(0,0,0,0);    height: 1px;    margin: -1px;    overflow: hidden;    padding: 0;    position: absolute;    width: 1px;}

而后咱们给要暗藏的元素增加一个offscreen类名即可达到暗藏元素,这不失为一种暗藏元素的方法,当然还有很多的css代码段值得学习的,例如border实现等高布局,css实现加载中成果,开关组件,高度过渡成果等等示例。

js代码段

除了css代码段,js代码段也有许多值得学习的知识点,比方冒泡排序算法.

冒泡排序算法

咱们来看这个算法的实现思路如下:

  • 申明一个变量,swapped,批示在以后迭代期间是否替换了任何值。
  • 应用扩大运算符 (...) 克隆原始数组 arr。
  • 应用 for 循环遍历克隆数组的元素,在最初一个元素之前终止。
  • 应用嵌套的 for 循环遍历 0 和 i 之间的数组段,替换任何相邻的乱序元素并将 swapped 设置为 true。
  • 如果在迭代后 swapped 为 false,则不须要更多更改,因而返回克隆的数组。

代码如下:

const bubbleSort = arr => {    let swapped = false;    let a = [...arr];    for(let i = 0;i < a.length;i++){        swapped = false;        for(let j = 0;j < a.length - i;j++){            if(a[j + 1] < a[j]){                //数组解构的形式                [a[j],a[j + 1]] = [a[j + 1],a[j]];                swapped = true;            }        }        if(!swapped) {             return a;        }    }    return a;}

再比方数组分块,这个也会用到理论业务当中。

数组分块

咱们来看实现数组分块的思路如下:

  • 应用 Array.from() 创立一个新数组,该数组适宜将要生成的块数。
  • 应用 Array.prototype.slice() 将新数组的每个元素映射到长度为 size 的块。
  • 如果原始数组不能被均匀宰割,最终的块将蕴含残余的元素。

js代码如下:

const chunk = (arr,size) => Array.from({ length:Math.ceil(arr.length / size)},(v,i) => arr.slice(i* size,i * size + size));   

当然还有更多的css和js代码段,我就不一一举例了,我只是想阐明这样每天学习一段代码段让本人学到了很多,更多的代码段请看网站。

如果拜访不了,可拜访这个网站。

react代码段

往年还新开了一个我的项目,记录react的学习代码段,蕴含根底组件和hook函数两个局部,除此之外,还有在应用antd design组件库的组件根底上额定封装的组件。比方实现一个弹出框组件,一个倒计时组件一个手风琴组件等等,像hooks函数就更多了,比方useTimeout函数,useInterval等等,useBodyScrollLock函数等等。我还是举其中2个示例来阐明吧。

受控的input组件

次要是款式去丑化input组件,同时将input组件的value值和onchange事件裸露进来,在这里我应用的是css in js来丑化输入框的,代码如下:

import styled from '@emotion/styled';import React from 'react';import type { SyntheticEvent } from 'react';const StyleInput = styled.input`  box-sizing: border-box;  margin: 0;  font-variant: tabular-nums;  list-style: none;  font-feature-settings: 'tnum';  position: relative;  display: inline-block;  width: 100%;  min-width: 0;  padding: 4px 11px;  color: #000000d9;  font-size: 14px;  line-height: 1.5715;  background-color: #fff;  background-image: none;  border: 1px solid #d9d9d9;  border-radius: 2px;  transition: all 0.3s;  &:focus {    border-color: #40a9ff;    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);    border-right-width: 1px;    outline: 0;  }`;type LiteralUnion<T extends U, U> = T & (U & {});interface ControlledInputProps {  type: LiteralUnion<    | 'button'    | 'checkbox'    | 'color'    | 'date'    | 'datetime-local'    | 'email'    | 'file'    | 'hidden'    | 'image'    | 'month'    | 'number'    | 'password'    | 'radio'    | 'range'    | 'reset'    | 'search'    | 'submit'    | 'tel'    | 'text'    | 'time'    | 'url'    | 'week',    string  >;  value: string;  onChange(v: string): void;  placeholder: string;}const ControlledInput = (props: Partial<ControlledInputProps>) => {  const { value, onChange, ...rest } = props;  const onChangeHandler = (e: SyntheticEvent) => {    if (onChange) {      onChange((e.target as HTMLInputElement).value);    }  };  return (    <StyleInput value={value} onChange={onChangeHandler} {...rest}></StyleInput>  );};

并且每一个组件都有对应的tsx和jsx版本,也有相应的接口,也不便学习如何去实现封装组件,组件的实现集体认为封装的最简单的是弹出框组件,因为我须要思考2种形式应用,第一种是通过组件形式应用,第二种则是通过调用办法的形式来应用。

而后就是咱们的hooks函数了,比方咱们来看useBodyScrollLock函数的实现。

useBodyScrollLock函数的实现

在这个函数中,咱们通过在useLayoutEffect生命周期钩子函数中获取到body元素,而后给body元素设置一个overflow为hidden的款式,就达到了滚动的锁定,顾名思义这个函数就是用来禁止页面的滚动的。咱们来看残缺代码如下:

import { useLayoutEffect } from 'react';const useBodyScrollLock = () => {  useLayoutEffect(() => {    const container = document.body;    const originOverflowStyle = window.getComputedStyle(container!).overflow;    container!.style.overflow = 'hidden';    return () => {      container!.style.overflow = originOverflowStyle;    };  }, []);};export default useBodyScrollLock;

当然这只是一个简略的hook函数,很好了解,也还有更简单的hook函数,比方useCopyToClipboard函数的实现,这里也不须要一一叙述了,想要查看更多实现思路,请看这个网站。

如果拜访不了,请看这个网站

以上就是我往年的输入了,当然除了这之外,我还在保持写一部小说,不过这就不须要走漏了,哈哈哈,因为我感觉我写的也不怎么样。

最初

总而言之,我往年的学习成绩不算好也不算坏,然而去年立下的flag并没有实现,只能瞻望于2023年了,感激浏览到这里,本文就到此为止了,与君共勉。