源码分析axios拦截器实现思路

一、前言

为什么要看这个呢,因为前段时间有人提了个问题,axios的 拦截器如果想取消是否还需要return以及return什么值的问题,带着这个问题,看了axios的源码

说是源码分析,其实就是我看代码以及梳理思路的过程,哈哈哈

个人感觉axios的代码规范做的很好,命名规范,注释简洁,建议亲自品尝!

阅读全文

java爬虫爬公众号系列文章

一、前言

最近迷上了历史,茶饭不思,在公众号看连载历史小说,却发现不能像小说阅读器一样保存记录,每天看的时候都得想一想昨天看到哪了,这对于懒人,尤其是像我这样记性不是特别好的我是一场灾难。

要是能用手机看就好了,由于是连更,网上也没有下载资源,既然如此,只好亲自上了,用爬虫搞定吧,前后大概花了一天时间

阅读全文

从Snabbdom了解Diff算法

一、前言

闲着没事逛B站,发现了尚硅谷推出的关于Diff的课程,正好面试种也常问到,就学习了一下。这个课程主要围绕Snabbdom这个库,贴一下视频地址【Vue源码解析之虚拟DOM和diff算法】

这篇文章我会根据视频结合自己的理解对Diff过程进行讲解

关于代码还是建议看Snabbdomtypescript版本的源码,地址

首先要明确,Diff过程就是对新旧两个虚拟节点(VNode)进行比较,从而最小代价对DOM进行修补(patch)和更新

阅读全文

vue+render实现el-table多表头

一、前言

又好久没更新文章了。。补一篇,主要分享封装多表头表格render函数实现多表头表格

在公司维护低代码平台,有个需求需要通过拖拽配置一个多表头的表格(element的el-table),但是发现网上好像没什么资料,特别是平台是通过render函数实现的,对这个还不是很熟悉,摸索着写出来了,分享一下

阅读全文

VUE组件间通信方式总结

一、面试题

不用多说,参加过前端面试的小伙伴应该都遇到过,很经典的面试题。下面这些组件间的通信方式不但要会代码实现,还要知道每种方式的优缺点以及适用场景,学会灵活运用。

听别人说过一句话,原文忘记了,只记得大概是说:架构师在技术选型时不是选择最好最前沿的技术,而是选择项目最适合的方案。可能vuereact很好,但是有些项目可能更适合jsp,这是业务场景决定的。因此我们需要熟悉各个技术的特点,灵活的选用最合适的。

关于每一种通信方式的优缺点总结,是自己平时开发和工作中总结出来的,并没有参考其余博客,可能不是特别全面,大家做个参考,可以结合自己的经验进行思考,也欢迎大家提出自己的意见

阅读全文

记录项目配置图标的过程

一、前言

之前做过svg图标的批量引入,现在要在新的项目中用到,一时头绪有点乱。证明之前并没有自己的思考,就像听课只是听懂了,并没有消化

借一个新项目搭建过程重新梳理这一过程,并完善之前没有解决的问题(使用image-loader的问题)

环境:vue-cli3,不同于之前webpack搭建的应用【优雅的使用svg图标

二、正文

搭建过程也就是我的思考过程,由简入繁,最后做简单的优化

这部分会写的比较基础,也就是从一个初学者的角度来思考整个过程

2.1 初步使用svg

我们的目的就是使用svg文件作为项目的图标,所以入手肯定是从项目引入svg文件,然后再页面引用

所以我们在src下面建一个icon文件夹,在里面建一个svg文件夹用来放所有的图标

我们放一个svg图标,命名为affix.svg,PS:SVG图标可以去iconfont下载

随便写个测试页面,在模板中写下如下内容

1
2
3
<templte>
<img src="./icon/svg/affix.svg" alt="">
</templte>

然后运行项目,然后就能看到项目了,这就是最简单的使用办法,如果你是vue-cli3创建的项目,默认会有处理svg文件的loader,如果启动报错应该是缺少svg的loader,可以在webpack的配置文件中加上相关配置

1
2
3
4
5
6
7
8
module: {
rules:[
{
test: /\.svg$/,
use: ['file-loader']
}
]
}

重启后应该就能看到svg图标了

这样存在一个问题,图标是不可编辑的,除了宽高,其余颜色都无法调整,失去了svg的意义

2.2 引入svg-sprite-loader

那有什么好的方案呢,前人已经提出了SVG-SPrite的方案,也就是和CSS雪碧图差不多的方案,将svg图标统一注册,然后调用时只需要通过图标的唯一标识符(id)即可

工作原理是这样,我们通过这段代码来注册图标

1
2
3
4
5
<svg>
<symbol id="icon1"></symbol>
<symbol id="icon2"></symbol>
<symbol id="icon3"></symbol>
</svg>

引用时这样

1
2
3
<svg>
<use xlink:href="icon1"></use>
</svg>

可能有人会有疑问,为了可编辑多写这么多代码,性价比不高,确实如此,但是我们有偷懒的工具,让webpack去帮我们做这些重复工作

所以就有了svg-sprite-loader,它的主要功能就是将多个svg图标注册到一起

之前的测试代码可以删掉,保留项目结构,在icon文件夹下建一个index.js作为图标的出口

icon/index.js写入以下内容

1
import './svg/affix.svg'

然后在main.js中引入这个index.js文件

Q:有人可能有疑问,为什么不直接在main.js引入图标

A:这样会导致main.js庞大难以维护,而通过唯一的出口可以让项目更容易维护,加入图标只需要在index.jsimport一下即可

写一个测试文件

1
2
3
<svg>
<use xlink:href="affix.svg"></use>
</svg>

满心欢喜去查看效果

发现没有效果!!!揭晓答案

因为我们说到了svg-sprite-loader却没有用到,问题就出在这里, 2.3中去配置这个地方

2.3 引入svg-sprite-loader

修改vue.config.js

1
2
3
4
5
6
7
8
9
10
11
12
function resolve(dir) {
return path.join(__dirname, dir);
}

module.exports = {

// webpack相关配置
chainWebpack: config => {
config.module.rule('image').test(/\.cur$/).use('url-loader').loader('url-loader').end();
},
};

在配置文件中,看到两个可能是webpack的配置,分别是chainWebpack和configureWebpack,但是是函数形式,于是去vue-cli的官方看看相关内容,了解到vue-cli应该是引用了chain-webpack这个库,于是去项目package.json找相关内容,没找到,于是去版本锁定package.lock.json中查找,发现了这个依赖,好吧,那就去看chain-webpack这个库怎么配置

根据上面的配置,结合文档我们很容易仿写一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function resolve(dir) {
return path.join(__dirname, dir);
}

module.exports = {

// webpack相关配置
chainWebpack: config => {
config.module.rule('svg').test(/\.svg$/).include.add(resolve('src/icon/svg')).end().use('svg-sprite-loader').loader(
'svg-sprite-loader').options({
symbolId: 'icon-[name]'
});
},
};

这段配置的意思是注册一个svg的loader,并将打包的文件以icon-[文件名].svg命名

这下应该可以了吧,于是我们重启项目,重新查看效果,发现图标还是没有加载出来

思考原因:svg-sprite-loader会帮我们自动注册图标,但是审查元素没有发现,难道是没有生效?

于是打包看输出内容,文件名是affix.54214863.svg,不应该啊,根据配置,生成的文件名应该是icon-affix.svg

查看svg文件内容

image-20211224132728871

像是CommonJS的模块,不应该啊。

猜测是用了其他loader处理了,于是在控制台输出config.module.rule('svg'),发现确实svg的loader注册了两个,一个是我们注册的,另一个是默认的file-loader

经过验证,通过chain-webpack修改loader只能添加loader,相当于数组中的push操作

在群里提出了这个问题,有人发了vue-cli的指南,正文我没感觉有帮助,但是在截图最底下有个替换loader的标题,于是我去vue-cli官网查看了这块内容,发现一行注释

// 清除已有的所有 loader。
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。

好吧,印证了我的猜想,我们需要先清除,在设置单独的loader

代码改成这样

1
2
3
4
5
6
7
8
9
10
chainWebpack: config => {

// use clear to reset svg default file-loader
config.module.rule('svg').uses.clear();

config.module.rule('svg').include.add(resolve('src/icon/svg')).end().use('svg-sprite-loader').loader(
'svg-sprite-loader').options({
symbolId: 'icon-[name]'
});
},

启动项目,图标正常加载

审查元素也能看到以下内容

1
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0" aria-hidden="true" id="__SVG_SPRITE_NODE__"><symbol xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="icon" viewBox="0 0 1024 1024" id="icon-affix"><defs><style type="text/css"></style></defs>.....</symbol></svg>

撒花~~~

2.4 偷个懒

说明这条路可行,接下来是第二步,投入生产,部门其他人肯定不能每次导入图标都需要在icon/index下注册吧

既然是import那webpack肯定会提供相关方法批量扫描导入,碰巧前两天看webpack5的指南看到了require.context

于是改造icon/index.js

1
2
let req = require.context('./svg', true, /\.svg$/);
req.keys().forEach(req);

具体参见webpack文档【webpack require.context

然后在导入几个svg图标进行测试

image-20211224162256853

测试通过,可以批量注册

2.5 进一步偷懒

每次引用都要写<svg><use></user></svg>很麻烦,所以可以简单封装一个组件,然后再main.js中通过Vue.component全局注册

在icon下新建一个Icon.vue,写入以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<template>
<svg class="rambler-icon" aria-hidden="true"><use :xlink:href="icon"></use></svg>
</template>

<script>
export default {
name: 'Icon',
props: {
name: {
type: String,
required: true
}
},
computed: {
icon: function() {
return '#icon-' + this.name;
}
}
};
</script>

<style>
.rambler-icon {
width: 1em;
height: 1em;
overflow: hidden;
}
</style>

然后在修改icon/index.js,将这个组件导出

1
2
3
4
5
6
7
import Icon from './Icon'

// 批量注册
let req = require.context('./svg', true, /\.svg$/);
req.keys().forEach(req);

export default Icon

修改main.js

1
2
3
4
import Icon from '@/icon'

// 组件名称随便
Vue.component('RamblerIcon', Icon);

然后引用就变成了这样

1
<rambler-icon name="affix"></rambler-icon>

是不是方便了很多,哈哈哈哈

2.6 优化

我司UI做出来的图标有很多无关信息,比如文档声明等等

这时候可以用到第二个loader,image-webpack-loader

修改vue.config.js配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
chainWebpack: config => {
config.module.rule('image').test(/\.cur$/).use('url-loader').loader('url-loader').end()

// use clear to reset svg default file-loader
config.module.rule('svg').uses.clear();

config.module.rule('svg').include.add(resolve('src/icon/svg')).end().
use('svg-sprite-loader').loader(
'svg-sprite-loader').options({
symbolId: 'icon-[name]'
}).end()
.use('image-webpack-loader').loader('image-webpack-loader').options({
svg: {
removeDoctype: true
}
});
},

可以看一下html中body里面的svg图标,注册的图标已经没有了无关信息,可以优雅的使用图标了

配置后,只需要复制svg到svg文件夹下,然后直接通过rambler-icon使用了

三、总结

之前写过一篇类似的文章,不过问题也很明显,因为没怎么看过webpack中的loader,所以配置完以后不生效不好排查原因,正好最近在看webpack,知道了loader是右下向上执行,有种豁然开朗的感觉,哈哈

刘邦的一生

一、引言

感觉记忆力越来越差,看过的历史人物、事件、地点就在嘴边,可就是说不出来。从秦灭亡到西汉建立,也算是看完了刘邦的一生,就着百度百科总结一下刘邦的一生吧。

阅读全文

优雅的使用svg图标

一、前言

很久没更新文章了,正好前两天有人问到svg图标的问题,于是便有了此文

为了节省大家的时间,不卖关子,本文主要讲述项目中如何更优雅的使用svg图标,经过配置后支持自动化导入图标,自动化压缩、剔除无关信息

使用方法:

  • 下载svg图标(iconfont或者来自UI的svg图标)
  • 复制到项目路径下
  • 通过svg名称调用

这篇文章主要参考

阅读全文

box-sizing详解

一、前言

实现一个很常规的功能, 鼠标停留出现3个像素的上边框,然而鼠标停留后出现了抖动,审查元素后发现是三个像素撑起了这个元素, 将其余元素向下挤, 才出现了这个抖动,一个比较常用的解决办法是先给元素一个3像素transparent背景的上边框,鼠标停留在将背景色改为其他颜色。这样就不会撑大元素

后来又想起来有个box-sizing, 好像也可以做到,于是尝试了一下确实可以,看了一下mdn文档中对于box-sizing的描述, 做一个记录1

阅读全文

聊聊圣杯布局和双飞翼布局

一、前言

圣杯布局和双飞翼布局这道面试题我看过很多次了,每一次都以为自己看明白了, 结果一段时间不看还是忘记了,可能是我经历的面试层次太低,没有考到吧。。再就是平时开发中一般没有这种优化要求,用的比较少,今天就再次好好看看并总结如下:

阅读全文