Results 17 issues of Geoff Zhu

I'm going to rewrite this component, about a month later. If you have any suggestions, write in below.

这次的故事要从Vue1.x的模版语法开始,Vue模板中通过指令传递props,语法如下 ```javascript ... ``` 指令的值(既`foo.bar[0].url`)可以是任意对象取值字符串,只要符合JavaScript语法既可。这个字符串会在模板编译阶段转化为render函数,其中的`foo.bar[0].url`会被解析成`['foo', 'bar', '0', 'url']`。每次render函数执行时,通过解析后的数组,一个循环就可以取到值了`data['foo']['bar']['0']['url']`。 上周我们团队Coding,就是实现这样一个方法,输入对象取值字符串,解析成数组。 最后的结果可以说是百花齐放,很有意思。我自己收益也颇多,尤其是对Proxy,所以才分享出来。 将`foo.bar[0].url`解析成`['foo', 'bar', '0', 'url']`,看似简单的对象字符串解析,如果要实现的健壮,也是要下一番功夫的。毕竟javascript对象取值的写法也不少。在Vue1.x中,为了解决对象路径字符串解析的问题,直接祭出了[有限状态机](https://github.com/vuejs/vue/blob/1.1/src/parsers/path.js),这才算满足了需求。 可以停一分钟思考下,你会怎么实现上面这个方法呢? ... 好了,先来看看一号选手,一行代码 ```javascript /** * 获取子字符串 * @param {String} source - 字符串 * @return -...

> 看了不少styled-components的文章,但没怎么找到与我产生共鸣的,所以就自己写一篇了 在写业务代码的过程中经常遇到前端命名规则和后端接口返回不一致的情况,我们需要在代码中做很多烦人的转换,例如 ``` javascript fetch().thne(resp => { this.userName = resp.user_nick_name; }) ``` 我们需要这种把user_nick_name转换为userName的适配代码,以便把后端的数据放到前端的各种组件和Store中,这种操作是一种映射,通`this.userName = resp.user_nick_name;`这句绑定前后端数据的映射关系。 思维稍微发散一下,你会发现,CSS和DOM之间不也是通过这种映射关系绑定才让样式生效的嘛! ``` html ``` 上面这段代码的写法,DOM和CSS是完全分离的,我们通过`class="red-button"`这种方式将CSS样式中的key与DOM绑定到一起,让样式生效。 这样写有好处,样式和DOM分离,单独来看都比较便于维护。 但问题就出在`class="red-button"`这句绑定上,当我找`.red-button`具体的样式时,如果项目目录结构比较规范,还算方便的就能找到CSS的文件,然后在文件中搜`.red-button`,定位红色按钮的样式代码,还算OK。但如果项目目录结构不规范,`.red-button`可能被定义在整个工程的anywhere。这时候就麻烦了,我一般都会直接全局搜索,并不是那么的舒服。 这时候一定会有人说css-modules,它可以让你像引入js那样引入css为json对象。这样的话,css文件就好找了。 ``` javascript import styles from './style.css';...

> 如果你追求极致的WEB体验,你一定在站点中使用过PWA,也一定面临过在编写serviceWorker代码时的犹豫不决,因为serviceWorker太重要了,一旦注册在用户的浏览器,全站的请求都会被serviceWorker控制,一不留神,小问题也成了大问题了。不过到了现在有了Workbox 3,一切关于serviceWorker都不再是问题。 ## 科普ServiceWorker 如果你已经熟悉ServiceWorker,可以跳过此段。 ServiceWorker是PWA中最重要的一部分,它是一个网站安插在用户浏览器中的大脑。ServiceWorker是这样被注册在页面上的 ``` javascript if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') } ``` 为什么说SW(下文将ServiceWorker简称为SW)是网站的大脑?举个例子,如果在www.example.com的根路径下注册了一个SW,那么这个SW将可以控制所有该浏览器向www.example.com站点发起的请求。只需要监听fetch事件,你就可以任意的操纵请求,可以返回从cacheStorage中读的数据,也可以通过fetch API发起新的请求,甚至可以new一个Response,返回给页面。 ``` javascript // 一段糟糕的sw代码,在这个SW注册好以后,整个SW控制站点的所有请求返回的都将是字符串"bad",包括页面的HTML self.addEventListener('fetch', function(event) { event.respondWith( new Response('bad') );...

> 笔者也是在工作2年多以后才有接触到前端容灾的概念,毕竟项目不到一定规模,是不需要前端来做容灾的。 ## 什么是容灾 容灾的概念始于后端,指当遇到某个服务器或某个机房发生自然灾害、断网断电等情况下的应急办法,可以保证服务依然可用。 新入行的小伙伴可能有疑问,都断网断电了怎么可能保证网站还可以正常访问那?其实这是对大型网站,理解不深导致的,你认为的网站是这样的 ![单机](http://img.mukewang.com/5b2641960001c09702480382.png) 像这种单机的服务自然没法做什么容灾了,这一台机器挂了服务也就挂了。但现在的大型网站,早就不是上图那个样子了,而是这样 ![同机房多机](http://img.mukewang.com/5b2641a50001572307720780.png) 甚至这样 ![多机房多机](http://img.mukewang.com/5b2641e400018f6b13621036.png) 最外层那个抗压的服务器一般是Nginx或Apache ,可以做到当某台机器挂了以后屏蔽掉那台机器,这就是后端容灾的基本手段之一,通过集群做到高可用。 说这些只是想让你理解什么是容灾,这不是今天的重点。今天的重点是前端容灾 ## 什么是前端容灾 前端容灾指的是当后端接口挂了,依然可以保证页面展示信息完整。我们以百度首页中新闻模块举例,当你打开百度的时候,服务端渲染好的页面出来以后,需要请求新闻接口拿到数据渲染新闻模块。你的老板告诉你,不论任何情况,必须展示新闻和广告,即使新闻接口挂了。这个时候怎么办,也就是前端容灾的范畴了。 ## 前端容灾可用手段 ### localstorage缓冲接口数据 新闻模块的接口,每次有返回的时候,都存入localstorage中,以接口路径为key,返回数据为value,当新闻接口请求失败的时候先从localstorage中读上次成功请求时候的数据,展示出来。 ### 备份一份静态数据到CDN 让业主方同学提供一份兜底新闻数据,存放在CDN上,新闻接口返回失败,用户localstorage中也没有数据的时候,去CDN对应地址拉取数据渲染 ### 利用Service worker的caches API做页面接口缓存 Service...

[首发地址](https://github.com/GeoffZhu/geoffzhu.github.io/issues/12) > 周五组内同学讨论搞一些好玩的东西,有人提到了类似『5分钟实现koa』,『100行实现react』的创意,仔细想了以后,5分钟实现koa并非不能实现,遂有了这篇博客。 ## 准备 先打开koa官网,随意找出了一个代表koa核心功能的的demo就可以,如下 ``` javascript const Koa = require('koa'); const app = new Koa(); // x-response-time app.use(async (ctx, next) => { const start = Date.now(); await next();...

> 目前博主所做负责的App是一个高度混合的App,混合了Web(cordova)、Weex和Native。产生这样的杂交方案有一定历史原因,最早它只是一个单纯的Cordova混合App,但随着项目的迭代,web页面的加载和用户体验不能满足产品的需要,所有引入了Weex。在开发的过程中,已有架构有很多问题,导致各端开发效率和体验都不太好,经过思考,有了此文,以便解决多端开发协作遇到的问题。 ## App架构概述 为了讲清楚为何要做技术优化,我先从几个不同的角度来讲讲App整体的状况和开发中的痛点。 ### App启动流程 1. App启动,拉取配置中心配置 ``` javascript // 省略了配置中心的模块概念 { host: 'http://75-up.domain-test.cn', loginApi: '/api/m/user/login', homePage: '/api/m/user/getHomePage', ... sidebarWeex: { '账户中心': 'http://static.domain-test.cn/sy/project/up-mobile-weex/accountCenter.js?weex=1' }, sidebar: { '使用反馈': 'http://73-up.domain-test.cn/vip/m/user/getHomePage#/feedback',...

[教程官网](http://geoffzhu.cn/weex/) > 2017年春节,工作以后最长的一次假期~~21天,总要找点事干,于是萌生出做视频教程的想法。毕竟当老师也是我的梦想之一吧!上学时候就挺好为人师的:joy_cat:,虽然自己也是半瓶子醋逛荡 :smile: 做这套视频的另一个原因是自己正在使用weex,相信weex做好了很有前途,也深知weex文档社区还不成熟。自己也可以贡献一份力,能影响几个人算几个人。 整套课程我花了15天录制,2天剪辑。录制的过程中,每天都是上午写稿子,下午录,倒也一点不累,唯独我这口痴比较难受,因为总是说错字,读错音,要一遍一遍的重录:ok_woman:,非常抓狂。 这是我视频教程的处女座,略显粗糙,但毕竟我已经把我对weex的理解都说出来了,无憾。因为我自己是前端出身,可能对Native方面理解错误,以免出现问题,我故意没有涉及Weex中Native模块等内容,这样也给我自己去学习Native留了个坑儿,学好了Native也可以再补。 想学习weex的小伙伴可以加群,这个群我在视频中也有提到,一起交流,keep fighting!

## 语法篇 ### 基础数据类型 int、float、double、char ``` int i = 0; float i = 0.1; doublle i = 0.1; char i = 'A'; ``` OC同时支持C语言的字符串 ``` 'C语言字符串' NSSting: @"OC字符串" ``` 变量名是大小写敏感的...

>最近工作上需要做一些HTML邮件模版,就是在平时邮箱里收到的那种推广邮件。深入研究之后,才知道这坑有多深。 ## 回到蛮荒时代 最初我的理解是,既然是HTML,我大前端的看家本领!半小时搞定没啥问题。试了才知道,HTML邮件没有任何标准,而且不管是HTML和CSS全部都是被阉割了的(啥?你还想用JS?),并且不同邮件客户端之间差异也很大。对于div和float的处理也带有很多的不确定性,所以浮动布局,flexbox啥的一样也用不了,只能用90年代流行的表格布局,90年代啊!开发体验是奇差无比,更重要的是我并不想去学过时的table布局。 我这次的要做的是出模版,服务端套,还需要考虑到收件人可能用的是手机客户端查看的邮件,所以需要响应式。对于我来说,可以拖拽的邮件工具肯定是不合适的,它并不能很好的实现设计和需求,况且作为一名开发者应以它为耻。 ## 找工具 ### [1. foundation-emails](http://foundation.zurb.com/emails.html) 首先GitHub找到了[foundation-emails](http://foundation.zurb.com/emails.html),扫了一下文档和DEMO,感觉非常好用,还能用sass,狂笑!!等模版做完了,按照文档 ``` npm run build ``` 文档上说这是把所有样式插到行内(没看到会压缩啊),当我执行之后,我看到的是这样的画面。 ![](http://o80ronwlu.bkt.clouddn.com/E17CB90D-9059-4250-A541-CA930E06F68B.png) 还是要在build的之前往里面插入服务端模版引擎的循环语句?只能手动去格式化html代码再加循环?我首先试了试第一个在模版里面想替换的地方加几个模版引擎常用的 ``` {{ }} ``` 结果build之后,直接就编译没了,再去GitHub看看,找到了这条还没有修复的[issue](https://github.com/zurb/foundation-emails/issues/666),看来大家都还没什么优雅的办法。 对于只需要替换个用户名或者只有少部分内容需要动态的邮件,foundation-emails是非常不错的选择,在其中使用响应式非常非常简单,格栅布局,就像这样 ```HTML ``` ### [2. mjml](https://mjml.io/)...