0%

公司的一个内部导航网站的标题使用了流光文字的效果,感觉还不错.百度搜了一下大概知道了原理. 具体代码如下:

Read more »

自我介绍

大家好,我是今天的分享者小晨~.我是19年毕业的,考研失败后家里蹲了将近一年,期间在饥人谷跟着方方老师学习前端.目前在深圳工作,刚上班没多久,姿势水平不高,还是要学习一个.所以就不分享太多技术内容了.我的分享主要分为三个部分,可能有些内容前边的同学已经分享过了或者有错误,还请见谅.

编程相关

我个人其实比较喜欢Python,所以给大家推荐下Python的入门教程吧~ 廖雪峰的Python教程

  • 这个教程虽然不是很长,但是基本把Python的重要内容和特性都涉及到了,有的地方比如装饰器,异步,刚开始看可能不明白,学习一段时间后再回过头看可能就能理解了.
  • 另外廖雪峰老师的JS 跟 Git 教程也非常形象和浅显易懂,很适合新手.

日常生活

健康相关

  • 我在上大学期间经常打游戏久坐,有时就会出现腰疼的情况.所以我现在比较注意这件事.大家如果有同样情况的话,建议买一个智能手环或者手表之类的,基本都带有久坐提醒功能.便宜的手环可能就几十块钱,准不准另说,但是最起码确实能在久坐时间过长的时候提醒到你,可以站起来接杯水或者上个厕所.
  • 另外也可以关注下丁香医生这个公众号,或者在知乎上关注 丁香医生 或 叔贵K.这两个账户经常分享一些办公室养生相关内容.

油猴脚本

油猴我看前面已经有同学分享过了,那我这里就分享个自己在用的脚本好了 - CSDN去广告 边栏净化https://xiedaimala.com/short_links/101987

IOS 捷径

IOS的捷径其实就类似于简单的编程,你可以通过一些指令,完成一个脚本.我个人觉得是一个很有意思的工具.大家可以在这个网站上面找到一些别人分享的捷径,然后自己再去模仿学习,DIY出来适合自己用的.

娱乐

分享一下我在 YouTube 上关注的两个博主吧.

  • BigDongDong 主要是数码相关内容,博主本人好像是个演员,有拍过一些电视剧.
    • 罗宾 也是数码博主,我关注他是因为博主本人在武汉,疫情期间每天拍vlog,都是一些生活相关内容,感兴趣可以关注一下. - 他们在国内b站也有账户,不过有些视频没有上传.

其他

  • TLDR的web版本,Linux命令速查 https://tldr.linux.cn/
  • YouTube 视频下载 https://en.savefrom.net/17/
  • 安卓应用下载,上面可以直接下载谷歌和国外的一些应用,如果不想用谷歌商店可以试试这个.不过网站貌似需要代理才可以访问.https://apkpure.com/cn/
  • 大家用安卓手机,如果觉得国内商店下载到的软件很臃肿的话,可以去上面这个网站或者Google Play下载,比如QQ在Google Play上的版本相比国内就少很多广告和无用内容.
  • 少数派 数码科技相关内容,个人感觉文章内容质量很好~ https://sspai.com/

菜鸡个人工作之余的一点感想

这部分内容主要是我自己的一些想法,如果有不对的地方,还请谅解!

  • 我自己从来不用抖音,快手,头条之类的软件.我觉得采用类似推荐算法的软件都很容易让人陷入“信息茧房”.互联网越来越蓬勃发展,但是个人得到的信息却可能越来越封闭.传统的贴吧论坛在衰落,推荐算法越来越智能,我们能看到的却可能只有我们想看到的.我对新闻比较感兴趣,平时工作之余会去纽约时报中文,FT中文,多维新闻等看,也会去国内的微博,百度之类的看.多样的信息渠道我觉得有助于避免我们的观点变得偏激.
  • 在参加工作之后,我发现自己手头正在做的事情经常会被打断,时间变得碎片化.一会领导可能就会在QQ上发信息找你,或者淘宝提醒我该抢啥了. 我感觉自己变得很健忘,刚才还在想的事情一被打断就忘了,搞得我很烦.现在我采用的方法是一有什么想法就在QQ上发给我的电脑或者手机(因为QQ在我的电脑,ipad,手机上都有安装),记录下来.大家如果也有类似情况的话,可以分享下应对方法,这样时间久了,我觉得记性越来越差了…

pointer-events:none 和 cursor:not-allowed 踩坑

最近有一个需求是在卡片不可用时,禁用鼠标点击事件并把鼠标指针设置为禁用状态. 于是我通过在卡片上设置了 CSS 样式

1
2
3
4
.appCard.disable a{
pointer-events:none;
cursor:not-allowed;
}

结果鼠标指针的禁用样式一直无法生效,我在 a 标签的父元素上设置了 cursor:not-allowed 才有效果.

1
2
3
4
5
6
7
.appCard.disabled{
cursor:not-allowed;
}
.appCard.disabled a{
pointer-events:none;
}

我看了下 MDN 上 cursor:not-allowed 和 pointer-events:none 的说明,也没看明白什么原因. 后来在博客上看到了产生这个问题的原因.在 a 标签上设置了 pointer-events:none 后,a 标签就无法再响应鼠标事件了,所以设置的指针样式也不会生效.因此把这两个属性放在一个元素上,是不能达到我们所需要的效果的.

pointer-events:none

MDN 文档的说法是元素设置 pointer-events:none 后将永远不会成为鼠标事件的 target,可以理解为你能看到这个元素,但却摸不到. 如下图所示,用一个 div 元素 把 a 标签挡住后,在 div 上设置 pointer-events:none 是可以点击到下面的 a 标签的:pointer-events-none 如果为 a 标签设置了 “pointer-events:none”,点击 a 标签,不会跳转到链接地址,而且也没有悬浮样式,但是通过 tab 键可以选中连接进行跳转,可以把 href 去掉,这样就无法选中了.


参考链接

  1. MDN 文档 - https://developer.mozilla.org/zh-CN/docs/Web/CSS/pointer-events
  2. pointer-events: none - https://www.cnblogs.com/xiaonangua/p/10734573.html
  3. 浅谈 css3 有意思的属性 pointer-events: none - https://www.cnblogs.com/teamemory/p/9889008.html
  4. 测试HTML - https://github.com/lichen404/FuckCSS/blob/master/fuckCSS.html

执行*.sh 文件的几种方式

1
2
sh filename.sh
./filename.sh(需要文件有执行权限)

上面的方法是通过建立子 shell 执行脚本中的语句,而以下方法是在当前 shell 中执行脚本内容.

1
2
. filename
source filename

source 命令

source 命令也称为“点命令”,也就是一个点符号(.),是 bash 的内部命令.

功能

使 Shell 读入指定的 Shell 程序文件并依次执行文件中的所有语句

usage
1
source filename

1
. filename
source filename 与 sh filename 及 ./filename 执行脚本的区别
  1. 当 shell 脚本具有可执行权限时,用 sh filename 与 ./filename 执行脚本是没有区别的. ./filename 是因为当前目录没有在 PATH 中,”.”是用来表示当前目录的.
  2. sh filename 重新建立了一个子 shell,在子 shell 中执行脚本里面的语句,该子 shell 继承父 shell 的环境变量,但子 shell 新建的,改变的变量不会被带回父 shell.
  3. source filename 或 . filename 只是简单地读取脚本里的语句依次在当前 shell 里面执行,并没有建立新的子 shell.那么脚本里面所有新建,改变变量的语句都会保存在当前 shell 里面.
Example
  1. 新建 test.sh 脚本,内容为:A=1
  2. 然后使其可执行 chmod +x test.sh
  3. 运行 sh test.sh,然后 echo $A,显示为空,因为 A=1 并没有传给当前的 shell
  4. 运行 ./test.sh 效果是一样的
  5. 运行 source test.sh 或者 . test.sh,然后 echo $A,则会显示 1,说明 A=1 的变量在当前 shell 中

参考链接

map()

创建一个新数组,其中每一个元素由调用数组中的每一个元素执行的函数得来

1
2
3
let arr = [1, 2, 3]
let newArr = arr.map((value, index, array) => value * 2)
console.log(newArr) //[2,4,6]

forEach 和 map 的不同

forEach 不会返回新的数组,但 forEach()也不会改变原有的数组,但 callback 函数可能会改变原有的数组.

1
2
3
let arr = [1,2,3]
let newArr = arr.forEach((value,index,array) => value * 2)
console.log(newArr) //undefined

forEach 中的 callback 函数改变原数组

1
2
3
let arr = [1,2,3]
arr.forEach((item,index)=>a[index]=0)
console.log(arr) //[0,0,0]

filter()

filter 接受一个函数,把传入的函数依次作用于每个元素,然后根据返回值是 true 还是 false 决定保留还是丢弃该元素

1
2
let arr = [1, 2, 3, 4, 5]
let newArr = arr.filter((value, index, array) => value % 2 !== 0) //[1,3,5]

sort()

sort 接收一个比较函数来实现自定义的排序

1
2
3
4
5
6
7
8
9
10
11
let arr = [10, 20, 1, 2]
arr.sort((x, y) => {
if (x < y) {
return -1
}
if (x > y) {
return 1
}
return 0
})
console.log(arr) // [1,2,10,20]

这里多说一下,JS 的默认排序规则是根据字符的 ascii 码进行的。

1
[10, 20, 1, 2].sort(); // [1, 10, 2, 20]

sort 方法默认把所有元素转成String 再排序,结果 ‘10’ 排在 ‘2’ 前面,因为字符 ‘1’ 比 字符 ‘2’ 的 ASCII 码小。

reduce()

reduce 把一个函数作用在 Array 的[x1,x2,x3 …]上,这个函数必须接收两个参数,reduce 把结果继续和序列的下一个元素做累积计算,相当于:

1
[x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)

reduce 实现求和:

1
2
let arr = [1, 3, 5, 7, 9]
arr.reduce((x, y) => x + y) //25

也可以设置初始值:

1
2
let arr = [1, 3, 5, 7, 9]
arr.reduce((sum, x) => (sum += x), 0) //25

every()

every()方法可以判断数组的所有元素是否满足测试条件

1
2
let arr = [1, 2, 3, 4, 5]
console.log(arr.every((item) => item > 3)) //false

find()

find()方法用于查找符合条件的第一个元素,如果找到了,就返回这个元素,否则,返回 undefined

1
2
let arr = [1, 2, 3]
console.log(arr.find((item) => item === 3)) //3

findIndex()

findIndex()和 find()类似,也是查找符合条件的第一个元素,不同之处在于 findIndex()会返回这个元素的索引,如果没有找到,返回 -1

1
2
let arr = [1, 2, 3]
console.log(arr.findIndex((item) => item === 3)) //2

includes()

includes() 方法用来判断一个数组是否包含一个指定的值,如果是则返回 true,否则 false

1
2
3
let site = ['runoob','google','taobao']
site.includes('runoob') //true
site.includes('baidu') //false

indexOf()

indexOf() 方法可返回数组中某个指定的元素位置,如果在数组中没有找到指定的元素则返回 -1

1
2
let fruits = ["Banana","Orange","Apple","Mango"]
console.log(fruits.indexOf("Apple")) // 2

JS 中 typeof 和 instanceof 的区别

typeof

typeof 的返回值是一个字符串,一般是 “number”,”string”,”boolean”,”object”,”function” 和 “undefined”

1
2
console.log(typeof 123); //"number"
console.log(typeof "123"); //"string"

instanceof

instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性

1
2
3
4
let list = [1, 2, 3];
console.log(list instanceof Array); //true
console.log(list instanceof Object); //true
//因为 Array 是 Object 的子类

具体说就是可以从来判断一个变量是否是某个类的实例,也可以用来判断在继承关系中某个类是否是一个实例的父类.

git 使用总结

git 用户配置

先设置好用户名和邮箱,这些信息会在 commit 记录中出现.之后再添加其他配置,方便使用.详细命令如下:

1
2
3
4
5
git config --global user.name "lichen404"     #填写用户名
git config --global user.email "f360family@gmail.com" #填写用户邮箱
git config --global push.default simple
git config --global core.quotepath false #避免中文乱码
git config --global core.editor "vim" #使用vim编辑提交信息

配置 github

生成 SSH key 并把它添加到 Github

  1. 进入 https://github.com/settings/keys
  2. 点击 New SSH key,你需要输入 Title 和 Key,但是你现在没有 key,往下看
  3. 打开 Git Bash
  4. 复制并运行 rm -rf ~/.ssh/*把现有的 ssh key 都删掉.
  5. 运行 ssh-keygen -t rsa -b 4096 -C "f360family@gmail.com".
  6. 按回车三次,运行cat ~/.ssh/id_rsa.pub,得到一串东西,完整的复制这串东西.
  7. 回到上面第 2 步的页面.
  8. 在 Key 里粘贴刚刚你你复制的那串东西.
  9. 点击 Add SSH key
  10. 回到 Git Bash
  11. 运行ssh -T git@github.com

git 的一些概念

  • 工作区:就是你在电脑里能看到的目录.
  • 版本库: 工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库.

git add 就是把文件添加进版本库,实际上是把文件修改添加到暂存区;

0-300x153

而git commit 实际上就是把暂存区的所有内容提交到当前分支.

1-300x152

常用 git 操作

命令 说明
git init 初始化当前目录为 git 仓库
git status 查看显示当前仓库文件状态,-s (summary) -b (branch),-sb 就是显示当前所有文件的状态
git add 将文件添加到「暂存区」,表示要加到仓库里,git add .意思是把当前目录(.表示当前目录)里面的变动都加到「暂存区」
git commit -m “message” 将你 add 过的内容提交到仓库里,并添加注释信息,方便日后查阅. - v verbose 显示更多信息
git merge 合并分支 Ex: git merge test
git switch(git checkout) 切换分支
git branch 创建分支 Ex:git branch x 参数 - D 删除分支
git log 查看版本提交历史
git rm 从版本库和工作区中删除该文件,作用和git add 相反。当只是需要从版本控制中移除本地还需要使用时可以使用 git rm --cached file_path
git reset --hard 版本号 版本回退,注意这个操作会使没有 commit 过的变动消失
git reflog 查看所有版本提交历史,包含已经“删除”的版本
git diff 用于比较当前文件和暂存区文件的差异,暂存区文件就是你add过的文件
git restore git restore 用来取代 git checkout 来实现撤销对工作区文件的修改,让文件回到最近一次git commit 或 git add 时的状态 Ex:git restore readme.txt.git restore --staged取代了 git reset HEAD ,可以把暂存区的修改撤销掉,重新放回工作区 Ex:git restore readme.txt –staged

git fetch 和 git pull

git fetch 是将远程主机的最新内容拉到本地但并不进行 merge,用户可以自行决定是否 merge。在取回更新后,会返回一个 FETCH_HEAD,指的是某个 branch 在服务器上的最新状态,我们可以在本地通过它查看刚取回的更新信息:

1
git log -p FETCH_HEAD

可以通过这些信息来判断是否产生冲突,已确定是否将更新 merge 到当前分支。

git pull 是将远程主机的最新内容拉到本地并直接合并,即 git pull = git fetch + git merge,这样可能会产生冲突,需要手动解决。

git rebase

git rebase 可以把本地未 push 的分叉提交历史整理成直线

使用 Github

  • 关联远程仓库: Ex: git remote add origin git@github.com:lichen404/jirengu.git origin 为远程仓库的名称,可以修改,但通常使用这个

  • 提交代码: Ex: git push origin master //提交本地 master 分支到远程仓库master分支 git push origin master:test //提交本地 master 分支到远程仓库的test分支 参数 -f 为强制提交,会覆盖远程仓库的版本 参数 -u 记住上次push的分支,下次避免重新输入,直接git push即可

  • 抓取远程仓库代码: Ex: git pull origin master

  • 克隆仓库: Ex:git clone git@github.com:lichen404/blog-test.git test 克隆到 test 文件夹,为空则文件夹名称与 repo 名称相同

Github 文件说明

  • .gitingore 标识哪些文件应该被 git 忽略,注意 .gitignore 只能修改那些没有被 track 的文件,如果某些文件已经被纳入版本管理中,则修改.gitignore 是无效的
  • README.md 代码说明
  • License 代码开源协议

解决冲突

fix-conflict-300x192

当两条分支各自都有新的提交时,Git 无法执行”快速合并”(git merge),只能试图把各自的修改合并起来,但这种合并就可能会有冲突. 当 Git 无法自动合并分支时,就必须首先解决冲突.解决冲突后,再提交,合并完成. 解决冲突就是把 Git 合并失败的文件手动编辑为我们希望的内容,再提交.

git stash

注意:工作区和暂存区是公共的.未 add 的内容不属于任何一个分支, 未 commit 的内容也不属于任何一个分支.当执行命令 git checkout develop 切换到 develop 分支时,如果之前的分支对文件有修改,也会将修改的文件信息带到 develop 分支上来. git stash 可以将你的修改临时储存起来,保证你的工作区是干净的,避免切换分支时你的修改被带到其他分支. git stash list //查看被临时储存的修改

如何恢复:

1
2
3
git stash pop //恢复后,stash内容并不删除,你需要用git stash drop来删除
git stash apply //恢复的同时把stash内容也删了
git stash apply stash@{0} //恢复指定的stash

####cherry-pick cherry-pick 命令让我们能复制一个特定的 commit 到当前分支

1
2
3
4
5
6
$ git branch
* dev
master
$ git cherry-pick 4c805e2
[master 1d4b803] fix bug 101
1 file changed, 1 insertion(+), 1 deletion(-)

配置别名

可以将 git 命令缩写,减少工作量

1
2
3
4
5
$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch
$ git config --global alias.unstage 'reset HEAD' //撤销add
$ git config --global alias.last 'log -1' //显示最近一次提交

配置文件

配置Git的时候,加上--global是针对当前用户起作用的,如果不加,那只针对当前的仓库起作用. 每个仓库的Git配置文件都放在.git/config文件中. 当前用户的 Git 配置文件放在用户主目录下的一个隐藏文件.gitconfig 配置别名也可以直接修改这个文件,如果改错了,可以删掉文件重新通过命令配置.

更多内容

廖雪峰的 Git 教程

你们仍未掌握那天所学的 git 知识

生命周期钩子

每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等.同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会.

lifecycle-404x1024

验证四个生命周期钩子

通过具体的测试,证明四个生命周期钩子过程中,Vue都做了什么. created 实例出现在内存中

1
2
3
4
5
created(){
store.commit('fetchRecords');
console.log('实例出现在内存中');
debugger;
}

页面中未渲染出任何元素

created-1-1024x702

mounted 实例出现在页面中

1
2
3
4
5
mounted(){
console.log('实例出现在页面中');
debugger;
}

页面中元素已经被渲染出来了

mounted-1-1024x621

updated 实例更新了

1
2
3
updated(){
console.log('实例更新了');
}

当我点击切换收入和支出时触发了data的更新,因此实例被重新局部渲染。

updated-1-1024x529

destroyed 实例从页面和内存中消亡了

1
2
3
destroyed(){
console.log('实例从页面和内存中消亡了')
}

刷新页面,实例重新生成和挂载

destroyed-1-1024x590

怎么证明Money实例在内存中也被销毁了

当我从 /money切换到 /label 时,Money 实例 destroyed ,从页面中消失了

destroyed-2-1024x581

而当我返回 /money ,Money实例重新生成和挂载了一遍,说明当 Money实例 destroyed 时,原来的 Money 实例在内存中也消失了.

destroyed-3-1024x582


参考: Vue官方文档:实例生命周期钩子