海阔天空的云

我们在自己的世界里独自狂欢

0%


写在前面

这篇仍然并不会也不打算去介绍或者科普React框架的基本知识点,但是会在行文中有很多涉及。

怎样实现的思路

一个电商APP, 要想让他的web HTML5 体验更接近客户端本身还是有很大的挑战的。怎样做出一些更符合客户端用户操作习惯的交互来,是前端开发中很重要的一个点。

我想要做的是一个类似客户端的商品轮播图阅览交互,总体来说,他的主要逻辑是:

  1. 在商品详情页显示商品轮播图
  2. 点击任意一张商品轮播图,能够全局浏览商品轮播图
  3. 通过左划右滑手势可是在全屏状态下阅览商品轮播图
  4. 点击返回键,退出全屏,回到商品详情页

有赖于react-photoswipe 这个库的支持,它已经将前三项做得很好了。我希望做的其实是第四项。细化需求,它不仅仅要求能够回到商品详情页,还希望能够最大限度地优化性能,最好的体验就是像客户端那样。

这里,我采取的措施是,将我集成了react-photoswipe 这个库的组件放到</ProductDetail /> 组件之中。

1
<ProductCarousel images={product.images} alt = {product.name} />

接下来,我的想法是这样的:

当用户在商品详情页点击任意一张商品轮播图时,页面上全屏显示那张商品轮播图,同时,当前的路由发生改变,由/products/:productId/products/:productId/showpic,这样,当用户点击返回的时候,就能够实现从当前路由/products/:productId/showpic返回到了/products/:productId

但是,这个时候,我遇到了很多与React-router有关的坑,其实与其说是坑,倒不如说是知识上的不足。当我把这些知识补足之后,再来看,其实并不难了。

React-router

第一个问题: exact

很明显,第一个问题是关于React-routerapp.js 中的配置的。前面介绍了我的总体思路,这个思路的一个关键点是当路由发生改变的时候,</ProductDetail />组件不应该unmount 或者重新didmount, 这样才能够让这种轮播图阅览交互更像是客户端的体验。

这时候,用到的第一个知识点是React-router的exact 配置。这本身并不是什么难点,我在这里只是想说明它的这一妙用。

由于我们大部分的React-router的匹配都采用了exact的匹配,在这个时候,我把原来对商品详情页的exact匹配去掉了,使得能够实现前述我的思路。

第二个问题: </ProductDetail />组件的生命周期

前面说了,我们在这个项目中,为了优化前端性能,使用了动态加载,来进行split coding。这个时候,我发现,如果使用了动态加载,我的</ProductDetail />组件每次进入轮播图全屏页面时,都会因为进入到了下一个生命周期,而不能进入轮播图全屏页。

这个问题出在哪里呢?原来这个问题是由于React-router以及它所关联的React生命周期造成的。

我以前有个误区,不知道各位读者是否也会存在这样的误区。就是React简单地认为它是单向数据流,除非父组件传递給子组件能够改变父组件本身的属性,否则,子组件的更新,不会引起父组件的更新甚至进入下一个生命周期。

但是,当然没有那么简单。

还是以我上面的问题为例,为什么会出现那样的问题呢?原因是:当一开始进入轮播图详情页面时,在我的<ProductCarousel />这个子组件发生了变化,他引起了路由的变化。由于我的路由管理由React-router完成,实际上顶部的<Switch>也相应地发生了更新,甚至可以这么说, <Switch>组件也必须发生更新,只有这样,他才有存在的意义。而紧接着,由于我们对动态引入的错误使用,造成了</ProductDetail />组件被迫重新装载,而他的重新装载又直接造成了他进入下一个生命周期。

关于我们是怎样错误使用动态引入的,以后会详细来解释。

这里,还是针对我刚刚提到的误区来谈一谈。所以,还是说回来,这当然不能算是坑,这是对知识理解的不深刻。

看到这个问题之后,我最初想到的是: 如果路由改变了,而加载的组件(import)并没有改变,就不更新这个组件的状态

但是,马上就发现了问题,还是这个例子:路由从/products/:productId/products/:productId/showpic发生了改变,这个时候我们没有改变</ProductDetail />组件的状态,则他的属性(location,props)较之前并没有发生改变。这本身就不是正常的,也就会从根本上造成虽然一个问题解决了,但是总还有新的问题产生。为什么呢?因为你没有按照规律办事啊!

React-router的思想是什么呢?其中一个思想就是组件上的React-router赋予的属性(location,history )是与实际相一致的。但是刚才,我试图通过调用 componentWillReceiveProps方法,来实现阻止组件更新的目的。

结果造成什么问题了呢?

一开始,我点击轮播图,路由切换,打开轮播图,没有问题。可是当我点击返回键的时候,由于我前面的判断:如果路由改变了,而加载的组件(import)并没有改变,就不更新这个组件的状态,导致没有退回到商品详情浏览页。这当然是不正常的了。

我们应该顺应React-router的设计思想,最后采取的办法是:如果路由改变了,而加载的组件(import)并没有改变,这个装载的组件不变,但他的属性(location,history)要相应地发生改变,他必须仍然在原有的生命周期中

可能听起来,还是有点抽象,还是直接上代码:

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import React from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import {BrowserRouter, Route, Switch, Redirect} from 'react-router-dom';
import BaseLayout from './BaseLayout';
import Loading from 'react-loading';
import Loadable from 'react-loadable';


const LoadingComponent = props => {
// something
};


class RouteWithLayout extends React.Component {
state = {
loader: () => {},
exportName: null,
LoadableComponent: null
}

static getDerivedStateFromProps(nextProps, prevState) {

if (nextProps.loader.toString() === prevState.loader.toString() && nextProps.exportName === prevState.exportName) return null;
const { loader, exportName } = nextProps;
const loadableOpts = {
loader,
loading: LoadingComponent
};

if (exportName) {
loadableOpts.render = (loaded, props) => {
const Component = loaded[exportName];
return <Component {...props} />;
};
}
return {
loader,
exportName,
LoadableComponent: Loadable(loadableOpts)
};
}

render() {
const { hideFooter, hideReturnTop, ...rest} = this.props;
return (
<Route {...rest} render={matchProps => (
<BaseLayout hideFooter={hideFooter} hideReturnTop={hideReturnTop} {...matchProps}>
<this.state.LoadableComponent {...matchProps} />
</BaseLayout>
)}
/>
);
}
}

第三个问题: 匹配不匹配

我们知道,在客户端的图片阅览里,实际上,是不能直接通过访问地址的方式,来全屏浏览商品轮播图的,这是一个更深层次的交互设计,因此我在</ProductDetail />组件的componentDidMount 方法中写下了这样的代码

1
2
3
if (!this.props.match.isExact) {
this.props.history.replace(this.props.match.url);
}

如此依赖,当初次载入</ProductDetail />组件时,一律显示商品详情页面。

最后

最终的实现效果,前面提到的指标都已经完成了。也能够比较完美地使用动态加载来加载组件了。


写在前面

最近,在实际项目中,遇到了一个坑。正好,借由这个坑,来多聊一聊前端的东西。

需求

背景知识

  • 我们的技术栈是React + React-Router+webpack4 的结构
  • 我们的应用是电商网站,所有页面会有一些公共的部分。因此,我们需要在实际用到的组件外面,再包裹一层组件,我们叫做

知识点1 动态加载

在 webpack 2或 webpack 3的时代,我们自己写了一个动态加载的实现。
这里的核心,大概就是下面这一行代码了。

1
loader={() => System.import('./ProductDetail').then(c =>  c.default)}

Module 的加载实现

https://github.com/systemjs/systemjs

包括我们当时,还自己实现了一个组件。嗯,他其实也是一个高阶组件。

到后来,我们引入了React-loadable 这个组件,同时由于能够使用babel-plugin-syntax-dynamic-import这个babel 插件,我们直接在引入组件方式上发生了改变。原来,我们的引入方式是System.import,现在我们则可以将import去掉,直接用来自未来的JavaScript语法规则来实现我们的需求了。

后来,阅读源代码我发现,我们自己实现的那个动态加载的高阶组件(),基础逻辑是相同的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
return class LoadableComponent extends React.Component {
constructor(props) {
super(props);
init();
}

render() {
if (this.state.loading || this.state.error) {
return React.createElement(opts.loading, {
isLoading: this.state.loading,
pastDelay: this.state.pastDelay,
timedOut: this.state.timedOut,
error: this.state.error,
retry: this.retry
});
} else if (this.state.loaded) {
return opts.render(this.state.loaded, this.props);
} else {
return null;
}
}
}

在这里,只截取了部分代码。

我在这里,就不展示我们以前的组件实现了。我们只实现了React-loadable最基础的功能,事实上它还能够有以下几点优势:

  • 当加载组件的过程中,给出过渡效果
  • 当加载失败、加载错误后,给出一个类似404的页面,不致于白屏
  • 能够进行retry 等行为

正是因为它有这些好处,并且有很多人的实践,我们才用到了它。

但是,无论是在引入React-loadable 之前还是之后,都有一个坑,我试图搞定它,却一直没有搞定,直到最近,才终于把这个坑填上。

下回《2-实现一个类似客户端的商品轮播图阅览交互》


1 html-webpack-plugin 已支持webpack 4
2 inline-manifest-webpack-plugin 的升级替换

inline-manifest-webpack-plugin 插件本身已支持webpack 4, 但从测试看有bug,不能将生成的manifest.js 插入到frontend-js.html 文件中。

解决方案,使用webpack-inline-manifest-plugin
https://github.com/szrenwei/inline-manifest-webpack-plugin/issues/10

3 extract-text-webpack-plugin 的升级替换

项目主页:https://github.com/webpack-contrib/extract-text-webpack-plugin

Since webpack v4 the extract-text-webpack-plugin should not be used for css. Use mini-css-extract-plugin instead.

官方推荐使用 mini-css-extract-plugin 代替

因此根据mini-css-extract-plugin(https://github.com/webpack-contrib/mini-css-extract-plugin) 项目介绍 ,添加了一些mini-css-extract-plugin 的高级配置

4 CommonsChunkPlugin 废弃

https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366

提取common vendor。

5 不再使用 inline-chunk-manifest-html-webpack-plugin

项目没有更新,插件不支持webpack 4,考虑到本插件优化作用不大,可以先不用。

6 统一使用url-loader 处理非js,css(scss)等资源
webpack在处理非js和css(scss)时,统一使用url-loader 。url-loader 本身是对file-loader 的扩展,当文件大小超过规定的限制时(目前limit为3kb),则将文件资源输出到指定文件夹中。

7 优化首屏,减少网络条件差时的白屏时间

head 里面的css 阻塞进程,使用webpack 3 时的CSS文件637kb。使用webpack 4 后,将url-loader limit 限制在3kb,使转base64 的资源越少越好,尽量不占用css的的空间。目前生产环境CSS 文件大小474kb。

8 升级后变化

升级前 build Done in 34.25s.
升级后build Done in 22.72s.


我在去年这个时候,写了 《博客三周年小记》 ,时隔一年,这个博客,终于又更新了。(我太懒了,连头图都用的去年的)

我自己其实也没有料到会是这么长的更新周期,但是正如看官老爷们所看到的,的确如此。在这里我就不再废话,找寻其他不更新的理由了。

因为有了一年的更新周期,我甚至觉得这篇博客可以作为我这过去一年的回顾来看。

1.工作

过去的一年,在同一家公司完整地工作了一年。对我来讲,过去的一年,还是有很大的成长。

都在哪里有提升

经验积累

我刚刚找工作那会儿,因为跨专业,因为没有工作经验,找工作并不容易。我自己也曾经想,究竟工作经验这种事情重不重要?如今,我已经正式工作快两年了,如果再问我工作经验重不重要,我可能会回答确实很重要。

哲学上有说从量变到质变的概念,工作经验的积累,在我看来就是量变到质变的过程。在我最初找工作那会儿,也会去背一些面试题,但是坦白来说,有些面试题,即便是背下来了,却还是不知其然,更不知其所以然。举个例子,作为一个前端,经常会有的面试题会问到“前端如何做性能优化”,在最早的时候,完全没有实践,就是去背那些答案。这些答案当然正确,但是却并没有经过实践,只是理论。可是有了这方面的工作经验,甚至是坑之后,想不去明白这些道理都是不行的。让实践跟理论一起去碰撞,实践去印证理论,理论再去指导实践,应该还是一个比较可靠的学习和工作方式,而这,都是要靠时间来积累经验的。

但是又没有必要把工作经验看得特别重要。这也让我想起来,前两天看热门日剧《unnatural》,其中有一集讲到两个解剖的法医比较谁的说法更可靠,一个老头说他解剖过15000具尸体,而由石原里美扮演的女主角则只解剖过1500具尸体,两者之间差了十倍的工作经验,但最终的结果当然是有光环护体的女主战胜了法医权威。所以,还是不能盲目地去崇拜工作经验,以为工作经验多了,水平就一定会直线提高,有时候并非如此。

说回来,对我来说,过去的一年,增长的工作经验,更多时候,是让我去印证之前在书本上看到的理论。让我明白,原来书上短短的一两句话,在实践之中就有如此多的门道。而这,正是我过去一年体会的。如果说的再明白一点,我认为,我关于前端的大部分知识,都是在学习前端的第一年获取到的。而这些获取到的知识,经过工作,消化吸收,则是在过去的一年完成甚至还没有完成,需要继续完成的。

端到端的打通

我在上家单位的时候,做的就是一个纯前端开发的工作,而在过去的一年里,我做起了全栈开发。技术栈是 python + react + postgresql 。起初,对我来说,这样的开发实践是一个很大的挑战,毕竟在此之前,我只是用python 写过简单的爬虫,关于数据库,甚至都没有动手写过一个查询语句。对于这个技术栈的后端,我几乎是从0开始做起,但是好在老大给了我很大的耐心。让我能够去补齐这些短板。我也的确觉得自己还是需要这样的一些全栈工作的训练的,这确实让我更能够理解计算机,理解互联网。以前有一个很有名的面试题,大概是说从用户用键盘在浏览器地址栏上面敲出google.com 到出现页面之间,发生了什么。这个面试题我自己从来没有遇到过,但我看很多人回答过,的确呀涉及到很多的知识。这些知识,当然不止有前端知识,还有很多更广阔的知识,包括计算机网络,通讯等,想的越多,能关联到的知识,学科领域就越多。毕竟,既然有些人能够因为别人是计算机专业的,就去找他修电脑。

我也因为自己的“野路子“出身而出过一些问题,比如在写一些API调用方法的时候,不写异常处理。给自己找理由说前端JS业务代码几乎从来不会进行try catch 的异常处理。也会因为一个break和 continue 的区别,而给代码造成bug。我也试想,如果我在大学里面修了完整的计算机课程,有了基本的计算机素养,或许会好很多。以前,我只写前端的时候,更像是在造空中楼阁,越造可能越虚幻,不稳定。而有了这种端到端的训练,对我来说,即便是以后不再写后端逻辑,也是受用的,至少基础更加扎实了。

前端重要吗

最近正好听了一期podcast,是《anyway.fm》的一期。他们请来了一个做设计的嘉宾进行交流,这位嘉宾提到自己在前雇主那里的收获的时候,说他发现原来设计没有那么重要。换到我自己这里,我也在问自己一个问题,前端重要吗?我的回答其实跟那位嘉宾差不多,用户前端所见所用(UI/UE)对于用户来说也可以笼统地算作设计,设计没有那么重要,前端也没有那么重要,一个电商网站,最重要的是他的商业运作,是能够把货物卖出去卖得好,乃至于无论前端,后端,设计,都不过是工具辅助工具而已,最终服务的,都是商业行为和商业逻辑。所以,我也看到很多程序员后来转型做了管理或者当了产品经理,这里面也不是没有道理的。

明确定位很重要,知道自己吃几碗干饭也很重要。知道了这些之后,如果你再说,我就是喜欢前端,或者说我就是喜欢开发,我就是不喜欢做产品分析,有问题吗?当然没有问题。这就好像是这个社会的分工,每个工作都有他的价值,但总有一些更加重要。我曾经听说某富家千金想以后当一名面点师,面点师当然也是社会的一个重要分工,但他显然这个社会最重要的,没了他,社会还是能够照样运行。但摆正位置,做自己喜欢做的事,或者能够做的事,很重要。

2.生活

过去的一年,我的生活稳定了,相比于毕业那年(2016年)的确稳定了,这种稳定有时候会让我焦虑,有时候又让我无所适从,我有时候也会面临很多新问题,比如相亲。生活当然精彩,在此省略一万字。

记录生活的地方很多,我的推特,我的公号,也欢迎各位看官关注。

3.获取信息

既然是因为博客四周年的由头,写的这篇博文。还是想说说跟博客有关的,过去的一年里,我还是会通过RSS来获取大量的信息,不过RSS里面几十个订阅源,活跃的也的确越来越少了。更多的时候,我会选择在工作日的中午饭后,打开Inoreader这个RSS阅读器进行阅读,这时候很大部分内容是好奇心日报的feed。好奇心日报是我最近一年在看的一个feed,也可以推荐给各位看官老爷。除此之外,我的订阅源里,独立博客虽然也偶尔更新,但是由于我自己很少更新博文了,导致其他博客更新之时,我也没有了去评论互动的欲望。虽然如此,我还在用这种非常传统的方式获取信息,我觉得是很高兴的。我没有用今日头条,但是会用微信的看一看,会关注微信上面有趣的公众号。

4.最后

这篇更新完之后,下次更新会是什么时候呢?


博客三年

我很难说我的博客到底出生在哪一天,我在这个博客一周年的时候,写过《给六个人写博客》 这样的纪念博客一周年的文章,在那里面我也提到这个博客域名是在14年的5月13日购买的,然而实际搭建起来博客,却又是之后的十几天以后了。而到了5月24日,才有了这个博客历史上的第一篇文章,所以评判的标准不同,得到的关于这个博客出生日期的结论也不相同。这个问题当然不算很重要,大致是14年的五月份,我建立了这个博客,这一点是毋庸置疑的了。

我之所以花一定篇幅说明上面一点,大概也是为了证明:这个博客真的已经三年了。

而我之所以要证明他的三年,则是因为三年时间看似很短,然而在中国互联网来说,却又像是一个世纪。由于我这几年一直有订阅RSS,在RSS阅读器上阅读博文的习惯,从博客圈的角度来看,也能看到这三年来,大量的原来关注的博客停止了订阅,当然令人欣喜的是,也看到了一些新的博客涌现了出来,往往也总能给人眼前一亮的感觉。长江后浪推前浪之下,能够坚持三年,的确也是一件并不容易的事情了。

写博客的好处

我在那篇《给六个人写博客》 其实也提到了写博客的好处,然而其实都是比较形而上的东西。我这次,想要举出更细致的切身体会。

写博客让我知识积累

这应该算是一个常识,从我的实际体会上看,我很享受这样的过程。所谓的好记性不如烂笔头,其实说的也是这个道理。

我想谈谈我是怎样利用博客这个工具的:博客写好发布之后,生成新的RSS,通过IFTTT,实现文章自动同步到印象笔记,实现文章自动发布到推特。这样的话,其实知识汇总的大本营其实是印象笔记了,然后如果想要搜索特定的知识点,只需要打开印象笔记,搜索相应的关键字就可以了,这个时候,无论是博客上的内容,还是平时书写的比较私密的笔记,都可以快速阅读。而我最近也在用另外一款Android App,名字叫做 timehop ,他能够将你“历史上的今天”一些社交媒体上发布过的内容全部展示出来,作为一个自己对自己的回顾,在过去的两个月里,我每天都会打开这个App,看上少说几分钟,多则十几二十分钟,理由也很简单,我希望看到自己相比于过去的自己的进步,刚刚提到过,我使用IFTTT实现了博文发布后发出一条推特内含博文链接的功能,到这个时候,我也能回顾过去自己的文章了。这是一个在我看来很Cool的功能,因为你要知道,不是所有人,甚至可能大部分人,都没有定期翻阅笔记的习惯。拿我自己来说,即便是高中时代的自己,面对着那丑陋的笔记本上的字体,也没有想要翻动的意念。所以,我很推荐timehop,不过他目前的支持的社交媒体仅仅包括推特,非死不可,Google photos,instagram ,dropbox等,并不包括国内的新浪微博,微信等,所以可能还是有点水土不服,不过在我而言,倒也是足够了,毕竟我也一直自诩谷歌粉,呵呵呵。

博客和社交

我并不是一个特别注重网络社交的人,虽然在RSS 上添加了很多个人博客,实际上也很少会去留言互动,只是默默地阅读文章,我在我的友情链接列表里,也没列出来几个人。尽管如此,我仍然要说,博客确实帮助我进行着社交这样一个工作,三年来,得到了很多的评论,这里也要感谢即将淡出历史舞台的多说评论系统 ;由于在博客上留下了自己的个人微信号,也加了几个网友,偶尔会在朋友圈互动;之前找工作,由于在简历上留下了博客地址,在论坛上发帖求职,也让博客访问量有所增加,又有一些有志前端的网友与我在博客上讨论;我的转行系列 ,也让我收获了很多意想不到的面试机会和良好的个人印象,甚至于也在一定程度上帮助我找到了一份满意的工作。

当然,我们也不应该过分地夸大博客的作用,在当今这个自媒体的时代里,传统的博客式微,自媒体甚嚣尘上,传统的个人博客影响力远远没有一个有一定推广的自媒体公众号,这也是为什么在过去的三年里,我眼睁睁看着订阅的RSS一个个停止更新,传统的博客也都转投自媒体公众号去了。尽管如此,个人博客还是有其存在的意义,正如那篇《给六个人写博客》 中一个观点,每个独立博客都是一个小岛,我们通过友情链接、通过外链从这个岛屿跳到那个岛屿,来回穿梭,自由前行,这也是我理解的 Internet 的一大意义了。

近期计划

我最近在想这个博客的定位,觉得还是不要把技术文章和生活文章混在一起,也觉得自己的技术水平仍然浅薄,写技术文章也有误导旁人之嫌,所以以后这里可能发布更多技术上的感受,体会,成长,总结,而不敢轻易地写什么教程。我自己的代码实践,不会再随随便便地往博客上面放了,前些天新建了两个Github 仓库,大概以后前端相关的练习代码都会放到这里面,当然也很简单,自然更没有推广的必要了。

我仍然认为除工作之外的生活也很重要,虽然我自己一直标榜自己是 tech nerd ,但是我并不想将自己限制住。正如我这么些年来所崇拜的都是诸如梁宏达、高晓松等知识面广泛、博学多才的胖子, 我也希望自己能够在专业技能之外,有更多的涉猎。而经过这些年的写作,我也确实体会到写作的确是能够反过来促进阅读和自我提升的。另外,我们真实的生活,总是免不了茶米油盐,总是免不了跟各种人打交道,因而,我也希望继续我之前的写作风格,继续写下一些身边的人,身边的事,他们并不一定传奇,甚至在外人看来足够普通,但我还是想如实的记述,就像我这普通的生活。

因而,从今年三月份开始,我在简书 和公众号 ( hktkdycom )上每周五发布一篇小文,这些文章都与技术没有关系,可能是读书笔记,可能是旅行游记,可能是凡人小记,可能是电影评论,可能是时事热点评论,总而言之,与所谓技术没有一毛钱关系。每周一篇,每周花两个小时左右的时间,做这样一件事情,对我而言还是很有价值的,虽然并没有多少阅读量,也希望我能够坚持下去。

写在最后

三年的时间说长不长,说短不短,对我而言,经历了从一个所谓大学生到一个职场人的转变。前不久这个域名到期的时候,我没有像过去两年那样,一年一年地续费域名,而是直接续费了两年,因此,为了不让这个域名浪费,我也会继续在这个Blog 上面写作。我大概不会每年在这个时间写一篇《纪念博客n周年》的文,不过,希望能够在这个博客五周年之时,再次对这个博客进行回顾,那个时候,我也已经毕业三年,应该会有更多的与之前并不相同的感受。

我总是觉得,正是未来规划好的一些事情,亦即所谓的希望,让我们的生活更加有趣。因而,我也期盼和你,在这里,一直等到这个博客的五周年,见证它,也见证我,个人的成长。


my work,study and life.

项目主页:https://github.com/zhangolve/liqi

欢迎star

硬件篇

  • MOTO G 2014,2015年8月份买的,没有想到这么耐用(cao),各种刷机折腾都没有问题,现在仍然是主力机。
  • Lenove E431(已停产),其实我也想用Mac,然而这是公司配的。
  • Apple iPad mini 4,本来买回来是给老妈看视频聊微信用的,结果现在我每次回家总是占着它。
  • 吉列手动剃须刀锋速3,配合剃须膏,手动刮胡子也是一种享受了。
  • 罗马仕 充电宝,10000 豪安刚刚好,用了也两年多了吧。
  • New Balance 574 ,从14年开始穿,作为基本款还是很不错的。

软件篇

通用

  • 翻墙服务 自购ss账户,搬瓦工vps备胎,改善浏览网络体验

windows 7

编辑器和 Terminal

其他相关插件:

系统相关

  • ccleaner ,一路相伴,哈哈哈。
  • everything,据说是很多人至今不愿意放弃windows的一个理由
  • 迅雷极速版,偶尔下个片也不错
  • IDM,接管浏览器下载功能

效率

  • Xshell ,服务器命令行工具
  • WinSCP ,服务器文件可视化操作工具
  • Axure RP Pro 7.0,原型图绘制工具
  • 福昕阅读器,阅读PDF足矣
  • Dropbox,文件同步工具,已经很久不用国内云服务做文件同步了,信不过。

音视频

浏览器

  • Firefox,曾经多年的主力浏览器,现在很少用了。
  • Chrome,现在的主力浏览器,日常工作都很给力。

Chrome 插件

油猴脚本

© 2017 Zhangolve


nocopyright

我一个自动化本科生怎么就做了前端呢?(1)关上一扇扇门
我一个自动化本科生怎么就做了前端呢?(2)把通向自动化的路的门关掉
我一个自动化本科生怎么就做了前端呢?(3)有时候觉得像插队
我一个自动化本科生怎么就做了前端呢?(4)入门和试错
我一个自动化本科生怎么就做了前端呢?(5)独闯北京
我一个自动化本科生怎么就做了前端呢?(6)从毕业到失业到找到工作

春天来了


毕业就是失业

上回说到了我16年的五月份独自一人到北京找工作,虽然没有得到一份让我很满意的工作,但这次经历的确让我认识到了自己做得还很不够。因此,北京之行结束之后,我回到学校,离毕业答辩还有不到半个多月的时间,我开始准备毕业答辩了。

我比较顺利地通过了毕业答辩,16年的6月8号,也就是高考的日子,我迎来了我的毕业答辩,之后我其实可以直接回家,但并不舍得离开生活了将近四年的地方,于是耗到了六月中旬。当我拿到毕业证和学位证的时候,觉得一切都顺其自然,只是,我毕业了,也失业了。


阅读全文 »

缘起

(图床为谷歌,不见图,请翻墙,不会翻墙,爱莫能助)、

2016年的最后一天,我去了天津。如果非要找一个理由的话,大概就是想出去走走了。旅行这件事情,在我看来,一个意义是能够将自己放空,可以什么都不用想,只沉醉在一个陌生的世界里。如果再多说两个理由,也是因为早就想来,却从来都没有来过。我们家其实离天津很近,小的时候最常看的电视频道不是中央台,河北台,而是天津台。我也经常收听天津人民广播电台的节目,虽然我并不是「天津人民」。但说起来,虽然家离着天津这么近,却从来都没有去过。以至于小的时候会很自卑,当身边的小伙伴们讨论起去过的地方的时候,我却只能想起来周围的四邻八村。

阅读全文 »