传于我辈门人,诸生须当敬听:
自古人生于世,须有一计之能。
我辈既务斯业,便当专心用功。
以后名扬四海,根据即在年轻。
何况尔诸小子,都非蠢笨愚蒙;
并且所授功课,又非勉强而行?
此刻不务正业,将来老大无成,
若听外人煽惑,终究荒废一生!
尔等父母兄弟,谁不盼尔成名?
况值讲求自立,正是寰宇竞争。
至于交结朋友,亦在五伦之中,
皆因尔等年幼,哪知世路艰生!
交友稍不慎重,狐群狗党相迎,
渐渐吃喝嫖赌,以至无恶不生:
文的嗓音一坏,武的功夫一扔,
彼时若呼朋友,一个也不应声!
自己名誉失败,方觉惭愧难容。
若到那般时候,后悔也是不成。
并有忠言几句,门人务必遵行,
说破其中利害,望尔日上蒸蒸。
]]>令人难过,BetterTouchTool 的证书又过期了,
诶嘿嘿,我去官网买了一个正版的
]]>令人难过,BetterTouchTool 的证书又过期了,
诶嘿嘿,我去官网买了一个正版的
]]>我下班的时候,窗外突然一道闪电伴随一声惊雷,然后雨就下起来了,而且还下的很大。面对这个场景我并不慌张,因为我已经备好了雨具,那是一个加厚的雨披,后来发现我显然低估了这个雨量。来到大楼门口,此时这里已经聚集了一些人,没伞也没雨披,只好在这里等待雨停。我拿出我的雨披子,它的质感确实不错,就是有点短就只到小腿处。我不紧不慢的穿好雨衣之后,看着这大雨也有些犹豫,但想想等的话不知要等多久,心一横就踏进了雨里,刚进场我就发觉自己草率了,因为这个雨披最末端是没有扣子的还贴心的有个分叉,风一吹就揭开了,走了一步膝盖以下就全湿了😭。
但是我没有慌啊,因为我知道,在我的背后有着数十人的目光在注视着我,于是我一甩衣袖,蹦蹦跳跳的走了,为啥蹦跳,因为地上的水太深了,我把握不住。走在路上明显感觉雨变大了,好在公司到地铁的路上有行道树,感谢行道树,让我可以不必直面风雨。走了一会之后感觉脚下变得柔软起来了,我的态极3.0Pro第一次让我感觉到了“踩屎感”,你也可以给自己的鞋子灌一桶水来体验下,雀石舒服。路上都没几个人在走,靠近地铁人才渐渐多了起来,虽然我穿的雨披看起来有点狼狈,不过打伞的大家也没有很好的样子。
终于到了地铁,脱下我的雨披,膝盖以上还是干的还不错,而且黑裤子黑鞋子,湿透了也看不出来,虽然每次落脚的时候能听见鞋子里积水的挤压声,不过问题不大。好耶!快乐的回家了。
下了地铁,发现天通苑这边一点雨都没下,地都是干的。
]]>这是我第二次坐飞机,原来飞机可以在网上值机的,直呼方便,根据机型选了靠窗的位置,在飞机上看城市的灯光真的老好看了,可惜我不会拍照,试了下手机完全无法拍出我看到的景象。城市的灯光以黄色为主,哪些大楼的炫彩灯光即使离得很远也还是显眼。回来的时候经过济南,我还以为是已经到北京了,济南看起来也很繁华耶,城市的灯光在云层下若隐若现,感觉也是非常喵的观看体验。
]]>这是我第二次坐飞机,原来飞机可以在网上值机的,直呼方便,根据机型选了靠窗的位置,在飞机上看城市的灯光真的老好看了,可惜我不会拍照,试了下手机完全无法拍出我看到的景象。城市的灯光以黄色为主,哪些大楼的炫彩灯光即使离得很远也还是显眼。回来的时候经过济南,我还以为是已经到北京了,济南看起来也很繁华耶,城市的灯光在云层下若隐若现,感觉也是非常喵的观看体验。
10号晚上9点多出发差不多12点到达,在机场附近定的第一晚酒店,有接机服务比较方便,第二天早上起床后先前往西湖区的酒店把行李放下,然后就出发去吃午饭了。
午饭定在离西湖景区比较近的地方,吃的 老吴家 味道还可,吃完之后骑个共享单车两分钟就到西湖景区了,是的,没想到这么近。往里走看见俩广场舞团正在嗨皮,这么热的天在这跳舞是真的有毅力,我出门一个钟头就开始热了,也是带的包有点沉的原因。
沿西湖走了一段,乘坐游船前往中心小岛,游船里居然还有空调,属实得劲。小岛中间有个十字形的连廊,沿着小岛转了一圈之后就从花港再次乘坐游船离开了,这次的船没有空调,很气,下一站目标雷峰塔,到景点门口的时候,我们又决定不上去了,太热了。然后打算做观光车前往 双峰插云 景点,观光车的师傅问是要去看景色么,看景的话就不用去了,那里已经毁了,问茅家埠说还可以,于是我们就直接去了茅家埠。
有一说一,不知道这里是一直人都很少还是我们去的时间偏傍晚了,树木茂盛,曲径通幽,感觉非常适合游览,湖里还有进行独木舟训练的,整个游览的过程就遇到两三个路人。河边的小路旁有很多河蟹洞,但是它们都比较害羞,人一靠近就缩进去了。从茅家埠出来的时候开始下雨了,去吃了小龙虾就回去了
这天主要游览的是西溪湿地公园,当然又是非常热的一天,这里和大家说下,买票的时候记得看下票对应的入口是哪个,因为公园很大,付费的是几片区域而不是整个园子,不然就会像我们,入口在南门,但是我们直接打车去了西门=_=。不过西门有个免费景点,我们看路线也是通向付费区域的,买的门票有说限制上下午场,我们来玩的这时间感觉这里的人并不是很多的样子,想来也没有真的限流。剩下的时间就是在园子里逛,好多池塘里都有福寿螺的卵,鲜红的颜色挂在池子的植物上。我们进来的时候门口的安保大叔和我们说了很多,给了我们一些游玩建议,还和我们说地图上种种。
在景区的入口拍到一只用手枕着头睡觉的猫猫,咋叫都不醒,懒洋洋的,然而最终我也没敢伸手去摸,怕它一捉急要咬我。中午饭是在园子里以随身携带的食物解决的,又有游玩的比较累和热,我们回去的比较的早,先去吃了 杭三姐妹 ,味道一般,回到酒店的时候才6点多。外面的雨很大直接绝了我们想出去玩的想法,无聊的只好看电视来打发时间,还下载了个王者荣耀玩,然后打游戏到两点,绝绝子。
第三天下了挺大雨,我们是晚上的飞机,由于昨天玩太晚大家都没能起的来床(0.0),起床后去吃了个 临记老厨 ,这个店比较推荐,我觉得蛮好吃的,一鱼两吃,鱼汤比较鲜美,红烧的鱼肉一般,主要是刺太多了,还要了个醋炒鸡,因为店家说一个鱼不够三个人吃的,笑话, 完全够,我们饭量都不太大毕竟,醋炒鸡好吃,店家服务也很好,很有那种邻家小馆的感觉。吃完饭大家没有什么好去处,因为我们本来预定的航班取消了,后来改签的那趟时间比较的早了,所以我们要四点就出发前往机场吃完饭之后就俩钟头了,索性去上了一会网🤔,不愧是我们。
同行的伙伴说他坐了那么多趟飞机,取消这还是第一次遇到,不过不用慌张,到机场发现我们改签的航班又延误待定了,绝绝子。最后再机场等待了好久,九点多的时候才起飞,到北京的时候都12点了,没办法,只好和同行伙伴打个车回去了。至此杭州之行圆满结束,好耶!
这波出来我深切的感受到我对风景确实没啥感觉,没有说那种看到个很好的景色就焕然一新的感觉,看到动物倒确实让我很高兴,有时间还是去北京动物园看看吧,据说那里还有大熊猫,听起来比较安逸。还有一点就是夏天不要出门玩耍了,高估了自己的抗热能力,感觉自己已然被热傻了。
]]>由于对于自身爱好不足的担忧,想要发展一门可以拿出来说的爱好,遂准备在摄影这块消磨一下自己时间,购入了一台尼康 ZFC ,但是现在相机的操作还没怎么玩转,打算周末出去外拍一下试试感觉,目前主要在进行一个理论的学习以及多看好的作品以提升审美。有时感觉时间不够,有时在无意义的事情上消磨了时间,摄影不一定能长久坚持下去,希望我可以坚持下去,这事儿也比较有意思了。
之前一直想要拥有一个说说,但是没有好的实现方式与便捷的输入,开始想要通过 artalk 的仅管理员评论模式,但是样式不太好看,也懒得去改动,后来在输入上一个比较好的途径是 flomo 的微信输入,真的很方便,因为平时微信一定是最方便打开的,但是 flomo 的列表不支持 get 访问,数据导出只能导出 html 且每周只能导出一次,后面在网上冲浪的时候发现了这个开源的 Memos-Github ,基本契合我的需要,而且支持 docker 部署,现在真的很喜欢使用 docker ,好多小应用直接 docker 部署别提多方便了,就像这个 Memos ,在服务器新建个 docker-compose.yml ,然后快速加一下域名解析与对应的 Nginx 子域名配置,直接就可以用了,前后就几分钟的时间,就部署好了一个陌生的应用。Nginx 之前谈过添加 ssl 证书,是按通配符添加的,所以域名加上之后就是支持 https 访问的,非常到位。可以在此查看我的碎碎念哈哈 进击的学霸的Memos ,我会把这个地址加在导航栏
数据挂载的 data 文件夹通过 git 仓库的方式进行备份,目前没有加定时备份,只是在每次需要升级应用的时候先进行 git 提交,后进行 docker-compose 升级,防止数据丢失。
最近开始使用 GitHub Copilot ,因为有 60 天的试用,给 GitHub 账户绑定一个 PayPal 或者信用卡就可以了。付费的话需要 $10/month ,年付是 $100 ,如果说试用感觉对开发有提效的话,感觉还是值得购买的。另外还有一个进阶版 GitHub Copilot Labs ,这个最大的用处就是给他一段代码,他可以给解读一下,比较便于用来阅读老代码。之前有跟朋友聊到,他说 AI 的出现会不会让我们失业,我人为是不会的,起码现阶段的 AI 还做不到,最多可以将重复性的工作减少一些,给开发提效,因为目前还没法达到直接将需求文档转换为代码的能力,但是相信在不远的将来应该也是可以实现的,按现在的技术,大的项目整不了,做个小的页面估计还是不在话下的,只不过这个可能还得需要多个方向的 AI 的协作,比如图像识别等。
关于使用方面,因为目前在做的需求偏向于改方面的,所以估计不能完整的发挥出它的作用,但是好多时候的代码提示确实可以小小的减少一些 Ctrl cv 的工作量,另外它的注释提示我感觉也挺有意思的,之前在项目里处理一块逻辑,想说不确定影响面,先这么处理,然后我前半句打出来,后面就给完整的补全了。当前在写这个文章的时候,看的出来它也试图给我一些输入建议,不过在这种带点创作性的文章里,确实没什么用。
上周日去拿相机的快递回来,整一个就是本来今天高高兴兴,然后刚坐下,发现电脑的 MagSafe 灯不亮了,然后开机开不开,长按这些都试过了确实开不开,赶紧预约门店维修,因为我去年 3.5 买的机子,不抓点紧的话可能就过保修期了,约到下午两点的三里屯直营店的,单程过去要一个钟头,饭都顾不上吃就过去了。想想我来北京也五年有余了,第一次来三里屯居然是因为修电脑,这实在是有些瓜,三里屯的人特别多,看着就很繁华的样子。去到店里,工作人员很耐心,帮看了下,推断可能是主板的原因,换主板的话数据就没了,我想了想上面也没什么重要的东西,代码一般都是同步 git 的。但是后面的话,尽量还是得做好备份。由于还在保修期,所以不用花钱,正常的话看是需要花 4.5k 。一趟完事回去就四五点钟了,一天时间就这么过去了,感觉是一个非常快度过的周末。
而且说到这就不得不吐槽一下子了,感觉苹果的品控现在是越来越差劲了,这台电脑去年购入,这一年基本没怎么使用,顶多有时看看视频,结果主板还能坏,公司的那台 13 寸的,用了也是两年有余了,啥毛病都没有,还是属于高强度使用的那种。在给我一次机会的话,我不会再选择 Mac 了。而且以前买 Mac 占比很重的是他的科技感的外观,但是现在这个笨重的感觉,非常不美丽,有时在公司去开会拿上电脑,都会感觉手感相当的舒服,这个 14 的很难有这种体验。
今晚十点的时候发邮件跟我说修好了可以取了,这样尽量明天拿回来好了,不然周日的时间又会被占用了T_T。
最近 AI 的热度真的是太高了,最后我还是再聊一点 AI 相关的,但是要说的不是热度正盛的 ChatGPT ,而是 AI 绘画。今天逛推的时候,看到一个人弄的一个作品,差不多是 AI 生成的图片然后制作的视频,这个令我比较感兴趣,如果这样的话相当于降低了手书制作视频的门槛,以前我有一些想要做成动画视频的想法,一直没有付诸实践,这个的话让我感觉会是一个不错的思路,现在开源的资源还挺多的,周末可以搞一下试试。其实最开始我想 AI 绘画的盈利方式可以是生成涩图,看现在应该也有人是这么做的哈哈哈。
]]>这个是我认为在这个七月份最好看的,网上又说它和历史不符,那个我就不清楚了,我本来对历史也不够熟悉,就当它是平行世界的同人文又有何妨。触动我的有两点,一个是李白与高适的友情,另一个是李白的洒脱不羁,后者给我的感觉太强烈了,就是那种看他在年轻的时候那样的洒脱,当然人确实有才啊,主要不气盛叫年轻人嘛,就是看了这个剧之后,我后面基本上周周都会出去玩了哈哈,感觉在我身上是发生了一点变化的了。
李白与高适的友情,说实话只要是感情相关的,亲情、友情、爱情,都是很容易打动我的,当然演的不到位那种不算啊,第一次与李白的三年还是两年之约,高适如期奔赴,然后李白早已忘了这个约定,后面这个包袱也抖了好几次,也比较好玩。看了时间比较久了,现在一些情节已经想不起来了,但是总之就是好看,我打 9 分。
这部剧,让我感触最深的是俱乐部部长在被网暴的场景,那些无孔不入的媒体、记者,就像是苍蝇一般蜂拥而至,只想挖掘第一手的热点、爆点,根本不顾是否对当事人造成影响等等,网络上的舆论仿佛拥有了执法权,根据他们能看到的视频肆意宣泄自己的”正义感“,但是在演播厅里,当众人肆意指责的时候,部长突然展示了武力之后他们就沉默了,可见有自身风险或者利益受损的可能后立即就缩回去了。而且这些类似的事件,在当今现实的社会中也在发生着。
接下来说说剧情,根据格斗孤儿事件改编,我觉得整体上挺好的,有笑点有泪点,涉及到格斗的部分也很激情,而且没有什么多余的感情线,有人说比药神差远了,但是我想说根本不是一种类型。而且剧中涉及的现实也不少了吧,那些细小的地方,当格斗火的时候,老乡知道这里不收钱还给培训,都争着往这送人,当格斗出事,他们就在媒体的怂恿下把孩子接回去了,这其中孩子的意见没有人关心,孩子的出路也没有人关心,都是主打一个人云亦云。敢拍能拍社会事件改编,而且也能突出矛盾点,我觉得这就很好,很真实,打 9 分。
让黄渤来演姜子牙感觉也太出戏了,感觉找个仙风道骨一点的会不会好些,剧整体都蛮好的,那些年轻演员那个肌肉,真的牛。但是主要我对这类题材没啥感觉,以为是动漫的,看开头的时候还想,卧槽,这建模他么的跟真人都没差了吧,看了一会发现这就是真人。看完没有什么感情波动,打 8 分吧,但是如果你喜欢这类题材的可以去看看,还是非常值得观看的
脖子哥为啥能当主角啊,草率了,看演员列表有他,还以为是配角,真下头,蒋龙很好。剧平平无奇,讲街舞的,但是街舞的场景很少,之前看的预告我寻思街舞得是比较大的占比呢,街舞的场景很帅,所以想去看的。那个感情线,没有一点必要,太多余了,还生硬,脖子哥充分证明了什么是一双不会说话的眼睛,那冷酷坚毅的目光从头到尾,不带变得。
然后关于这个剧情,问一下就是说,凯文这么强,这么想拿冠军证明自己,就是说街舞是没有 solo 赛吗,一定要跟团打比赛然后拿冠军来证明自己吗。整体剧情没有一点出乎意料,就是普通励志文,只不过是街舞的载体。不打分了,不值得
]]>废话不多说,下面进入正文,
这步不会的就不用看了,登录成功后看到的页面应该和下面类似
]]>废话不多说,下面进入正文,
这步不会的就不用看了,登录成功后看到的页面应该和下面类似
配置服务器位置
选择操作系统类型
选择套餐
点击按钮购买
在支付页面选择 Alipay 或者 Wechat Pay,注意这里的支付不止是用来支付 vps 费用的,是类似给账户充值的,最低充值 10 美金,充值后 vps 按照小时计费,但是新建的 server 要在 5 分钟之后才能销毁,销毁后不再计费。这里充值的前提是电子邮箱已经经过核验。
OK ,经过以上的步骤 vps 就已经选购完成,有问题的话可以在评论中给我留言
]]>H5
的聊天嵌入到 Android
中,做到后面发现中间的数据交互很多,互相依赖性太强了,所以还是选择了用 Android
来做聊天,网上资料很多,记录一下以便查阅
Android
代码WebSettings settings = mChatWV.getSettings();
settings.setJavaScriptEnabled(true); // 支持 JS
settings.setSupportZoom(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN){
settings.setAllowUniversalAccessFromFileURLs(true);
}
mChatWV.addJavascriptInterface(new JsInterface(),"jsInterFace");
mChatWV.loadUrl("file:///android_asset/chat.html");
final Map<String, Object> paramsMap = new HashMap<>();
paramsMap.put("orderId", orderId);
paramsMap.put("baseUrl", com.box.common.Constants.WEB_SERVER_DOMAIN);
paramsMap.put("loadMoreTxt", getString(R.string.chat_click_load_more));
// 为了加载完 HTML 之后再调用 JS 方法,你的 JS 方法可以写在 onPageFinished 里面
mChatWV.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String[] userTokens = userToken.split("\n");
if(mChatWV != null) {
// Android 调用 JS
mChatWV.loadUrl("javascript:initData('" + JSON.toJSONString(paramsMap) + "', '" + userTokens[0] + "', '" + userTokens[1] + "')");
}
}
});
public class JsInterface{
/**
* //在 JS 中调用 window.AndroidWebView.showToast(message) ,便会触发此方法弹出一个 Toast。
* @param message JS 端需要传递的参数(也就是要 Toast 的内容)
*/
@JavascriptInterface
public void showToast(String message) {
if (getContext() != null) {
Toast.makeText(getContext(),message,Toast.LENGTH_LONG).show();
}
}
}
H5
的聊天嵌入到 Android
中,做到后面发现中间的数据交互很多,互相依赖性太强了,所以还是选择了用 Android
来做聊天,网上资料很多,记录一下以便查阅
Android
代码JS
代码Android
调用 JS
Android
版本不同有所区分)JS
调用 Android
javascript:jsInterFace.showToast(message);
window.jsInterFace.getData()
var status = window.jsInterFace.checkOrderStatus(currentStatus).toLocaleString();
JS
调用 Android
效率更高,推荐更多使用 JS
调 Android
Js
调用 Android
的方法、返回值如果是字符串、你会发现这个字符串是 native
的、转成 locale
的才能正常使用、使用 toLocaleString()
函数就可以了、不过这个函数的速度并不快、转化的字符串如果很多、将会很耗费时间jQuery
的加载速度很慢,不建议使用本文只是小白开发过程中的整理,参考了不少其他人写的文章,以下参考不分先后
]]>Typecho
源码
本文针对的是 版本 1.1 (17.10.30)
,而网上的大多答案都是 0.x
版本的 Typecho
,其实都是改源码的方式,只不过 1.1 版本的目录结构和旧版的 不同而已
Typecho
源码
本文针对的是 版本 1.1 (17.10.30)
,而网上的大多答案都是 0.x
版本的 Typecho
,其实都是改源码的方式,只不过 1.1 版本的目录结构和旧版的 不同而已
PS:本文路径中的 /var
是相对于 Typecho
的安装目录的,不是服务器上的 var
目录哦
大约在 /var/Widget/Abstract/Comments.php
文件中 376 行左右的位置(我是直接在文件中搜索 href
,第一个就是),将代码
修改为
这个的源码我找了一晚上才找到,可能的文件都翻过了,怪我 php
太菜了,只能通过搜索 href
来进行查找,效率实在是太低了。
大约在 /var/HyperDown.php
文件中 386 行左右的位置有这样一段代码,这是我已经将 target='_blank'
加进去之后的代码了,一样的代码就不多复制了,咱也不知道这代码具体的作用,个人从大致的文件相关来理解这应该是 Typecho
采用的 MD
解析器的源码,我相当于修改了其中对于 link
解析的一丢丢规则,反正这样是可以达成我的目的的,嘻嘻
在手机上进行 web 调试
]]>在手机上进行 web 调试
环境: windows, Android, wifi
工具: fiddler
Fiddler 是一个使用 C# 编写的 http 抓包工具。它使用灵活,功能强大,支持众多的 http 调试任务,是 web、移动应用的开发调试利器。fiddler 的功能很多很强大,在这里我们只使用它的代理功能。
调试需要手机和电脑在同一网络环境下,所以最好是连同一个 WiFi ,其他的方式我未探索过,感兴趣的同学可以自己试一试,以下步骤是默认前提:
选择菜单栏中的 Tools ,在下拉菜单中点击 Options ,进行如下设置,另外可以将 HTTPS 中的抓取 https 请求的复选框也勾选上
选择 Tools 中的 HOSTS 选项,进行代理的相关配置,此处的目的大致相当于:监听手机的请求,如果有请求 xxx.com
的,将其代理到本地的 8080
端口,此处配置可自己根据项目需要灵活设置
首先查看电脑的 ip 地址,这个可以在 fiddler 右上角左右的位置找到一个 Online 的字样 ,鼠标悬浮在上面即可看到一个内网的 IP 地址(类似 192.168...),如果没有的话,就重新连接一下 WiFi
手机连接的 WiFi 可以进行代理的设置,大部分的安卓手机都是可以的,按照之前的配置在手机上进行相应的设置,服务器的 ip 地址就是上面在 fiddler 上看到的 ip 地址,端口是第一步中设置的
现在打开手机浏览器,在浏览器地址栏中输入 xxx.com
,如果电脑上的 8080
端口有项目在运行着,在手机上就可以直接预览到效果啦,改代码后,刷新页面,手机上的页面效果也会改变。
原理大致如下,有四个操作 1 增, 2 删, 3 改, 4 查
,不同用户有不同的权限,甲有 1,2,3
的权限,那么他的权限就存 21 + 22 + 23 = 14,乙有 2,3,4
的权限,那么他的权限就存 22 + 23 + 24 = 28,当判断的时候:
如果和中没有对应的2的次幂的话,&
运算的结果是 0 ,有的话, &
运算结果就是该次幂。来看下这之中发生了啥子:
进制/2的次幂 | 1 | 2 | 3 | 4 |
---|---|---|---|---|
2 | 10 | 100 | 1000 | 1000 |
10 | 2 | 4 | 8 | 16 |
关于位运算,大家可以了解下这篇文章 位运算简介及实用技巧(一):基础篇 ,大佬写的非常详实
]]>我之前的博客有显示我的追番列表,所以想在这里也加个追番页面,想来这是 vue 的项目应该不会太麻烦,但实际上还是花了一点时间,毕竟是调B站的接口,不确定性还是有的。首先可以确定的是直接调是会跨域的,使用脚手架的代理可以解决跨域,试了之后发现还是会有 403 的问题,应该还是有 referrer 的问题,由于不想在前端伪装 referrer ,那只好在 node 上来调用这个接口了,想的是需要有个接口来进行转发,先在 node 上取到数据,然后返回给前端。整个后端项目来处理这事有点浪费,所以就想到用云函数来解决。由于之前使用过微信小程序的云开发,所以此次选择使用腾讯云开发来做,毕竟熟悉些。
建议大家在做开发之前先把相应的文档看下,能减少很多试错的时间。首先进入 云函数工作台 ,如果找不到建议直接在搜索里搜 云函数 ,点击新建云函数
点击完成,此时一个最基础的 hello world 的云函数就创建成功了,然后下面我们来改写代码,实现想要的功能,因为要写的代码量并不多,所以直接使用在线编辑功能就好了, index.js 文件中的代码如下
需要注意的是,我们在代码的编写中引入了一个库,那么这个依赖要如何才能安装到我们的项目中呢,像我们在本地开发一样,在根目录下新建一个 package.json 文件,将我们要使用的依赖记录在里面,记得打开编辑器右上角的自动安装依赖的功能,这样在部署的时候可以为我们自动安装依赖
另一方面,你应该也注意到我的返回值有些奇怪,为啥还把对象转成字符串再返回,这就要引出我们下面提到的功能,触发器
到现在的话,这个函数已经是可以运行的了,你可以在部署后点击编辑器下方的 测试 按钮,这样会调用你的函数并返回结果。但是我们比较想要的是一个 http 接口,所以我们需要新建一个网关触发器,触发方式选择 API网关触发
这里默认勾选了一项集成响应,使用集成响应的话返回值必须按照它规定的格式来,如果格式不对,它就会提示你,这个就难受在它只是告诉你你错了,不会告诉你错哪了,API 网关触发器相关问题 API 网关触发器概述 ,如果不勾选的话是使用透传响应,那需要自己返回一个完整的 http 响应,所以我认为还是使用集成响应要简单一点,点击触发器中的访问链接,就可以在浏览器中看到调用结果
我选择的部署方式是腾讯云部署,官网文档有提供一键部署的选项,如果文档上的链接不好用可以试试 这个 ,跳转之后一定要选择有免费额度的那个环境,我开始部署的时候选择的环境不是那个有免费额度环境的,总是运行不动,非常难受,而且在网上也没找到答案。选择环境之后点完成就可以,这样的话用的是腾讯云的数据库等资源,也比较的放心,有一些免费额度应该是够用的。
部署之后点击访问就可以看到评论页面了,如果没做自己的自定义配置的话,地址应该是这样的 https://*********.ap-shanghai.app.tcloudbase.com/waline
,星号部分是环境名,不要在意,注意无论是访问注册还是登陆,都是要在当前的 url 基础上再加路径,不要把 /waline
忘记了,它在登录态失效的时候跳转链接可能需要手动调整一下,不知道是都这样还是我环境的问题,我的环境之前部署过 rsshub 应用,虽然应用卸载了但有时还会冒出来。
在应用的管理面板可以看到有添加环境变量的地方,点击编辑按钮进入编辑状态,根据 官方文档 上的要求录入相应的环境变量,我录入的是 163 的邮件通知,录完之后大致是这个样子
我是专门注册了个邮件用来做邮件通知的,比较方便,用自己的邮箱也是可以的
我的博客现在使用的主题是 vuepress-theme-hope ,主题作者已经在主题中集成了 waline 的评论方式,所以不用管挂载元素那些,直接在配置里用就好,感谢博客主题作者 @Mr.Hope,我提了建议集成的 issue 之后,老哥很快就加上并更新了版本👍。最后贴一下我的配置
再说下我的 serverURL 配置,直接写云开发的路径的时候会报 CORS 的错,所以这里选择通过代理的方式访问
同样的 nginx 里也要做配置
最近发现表情评论时不能正常显示
一直以来,waline 的文档路径经常会有变化,很多在 issue 里的链接回复都已 404 ,给出具体路径,若 404 可按路径查找 了解更多-常见问题-如何升级?-服务端 #cloudbase 这个说的是保存并重新安装依赖,但我操作之后又报了 module 找不到的问题,查找后又找到这个 issue ,简单来说,就是 nodejs 的版本过低导致的,使用 nodejs > 11 的环境即可解决这个问题,但是由于腾讯 云函数不支持将已创建的云函数更改 node 版本,所以只能将当前的云函数删除,然后在我的应用哪里重新部署应用,此间会自动生成新的云函数,且由于内部进行了 node 版本的锁定,故而这次重新创建的就是合适 node 版本的云函数了,直接 http 访问不报错,页面里的评论表情也可以正常显示了
]]>参考文章,感谢大佬们的倾情分享:
我的配置:
有一说一我这个配置俩人玩有点奢侈了,你在搭建的时候按照自己的需求来即可,关于我服务器的花费后面会详细谈到的。而且下面的配置都是以 root 用户的身份,所以命令都是不加 sudo
的,因为我的服务器每次用完就销毁了,所以应该也没啥安全问题。
我后面找到了新的方式部署,不过需要一点基础才能看懂,建议你看完这篇之后可以去看看我的这篇 饥荒专服部署维护
docker 安装这里我想尽量的快,因为我这个只是用来做游戏专服不是我的主用服务器,这一套命令下去 docker 安装一般就 OK 了。
网上教程很多,先略过
设置阿里云镜像加速器,如果没开加速可能会比较煎熬,这个镜像有一说一还蛮大的,起码明显的有个 1.6G 的包,开了加速之后速度嗷嗷快,差不多三分左右就可以下载完毕。配置加速需要一个 ID ,所以这个页面需要登录之后查看,每个人的加速地址(ID)都是不一样的应该。
镜像拉取及配置工作, ${HOME}
指的是当前用户的用户目录,比如一般我登录用的都是 root ,这里就是 /root/dst
,安装了一个 docker-compose 用来方便命令的配置,不然每次输入一堆命令也很麻烦不是吗
新建一个配置文件 docker-compose.yml
,写入以下内容并保存(注释可以不加,加了可能复制的时候格式会乱)。记得开放你的服务器的端口,阿里云的话是要配置安全组 UDP协议 的 10999-11000 和 12346-12347 。
在 当前目录下执行 docker-compose up
,等待执行完毕后看到输出如下(输出差不多):
Control + c
退出容器编辑配置文件
配置房间信息、森林世界、洞穴世界以及需要的 mods 。
简单配置下,这里基本是关于游戏模式和服务器的设置。你也可以在本地新建一个房间,然后把配置文件拿过来替换掉服务器上的配置。 https://wuter.cn/342.html/ 这里具体配置的作用可以看这个大佬的文章,附录里非常详细的,完全可以满足配置需要了我觉得
本地存档和线上存档都是以 Cluster_
开头的文件夹,后面跟一个数字,这一个文件夹就是这个世界所有的信息了,下文我们使用 Cluster_1
来举例,方便些。我看服务器上和本地的有点区别,就是文件夹内多了个 mods 的文件夹,这个也比较好理解就是世界单独配置模组,不使用公共的,我们在文件替换的时候注意下就好了说下我自己的尝试之后最后总结的方法吧,首先通过前面的操作我们在服务器上开放了4个端口,然后我们在服务器上查看已有的存档设置,可以看到这些端口。PS:不同的安装途径对端口的需求也不一定一样,按照本文的镜像的话是需要这些端口。
因为你本地的存档的端口号的使用八成和你服务器上的不一致,所以这些文件我们还是保留服务器上的,将其他文件上传替换即可。将 Master 和 Caves 中除 server.ini
文件替换为已有存档,如果自己有 leveldataoverride.lua
(自定义世界配置) ,记得把 worldgenoverride.lua
(默认世界配置)删掉,因为后者比前者优先级高。
如果不保留这些文件的话,还要去修改安全组,同理,如果你想要跑多个服务,需要多配几个 docker-compose.yml
把它们的端口区分开,注意容器内的端口可以都使用 10999
这些,只改映射出来的端口应该还容易些。
根据 Master 和 Caves 文件夹下面的 modoverrides.lua
文件,打开可以看到里面有一些 mod id,去 Cluster_1/mods/dedicated_server_mods_setup.lua
文件中使用要求的语法将之挨个引入即可
因为大家网上部署饥荒的服务器的方法可能都有差别,但是一些核心的东西是不变的,比如说要开放端口,比如说存档的迁移,至于是自己手动安装还是脚本安装亦或是 docker 安装专服我理解都是属于基础,看个人爱好选择就好了。我这里用 docker 一方面是练习下 docker ,另一方面已经做好的镜像一般不会出现依赖缺失这样的问题会方便一些。
]]>通过上篇文章大家都知道我用的是 2v4G 的机子,但这机子又没有学生优惠,开一个月都不少钱呢,不慌,我们有按需付费,在阿里云一个 ecs.c7.large
的实例一个月二百多,但是按需付费的话是每小时 5毛 左右,我们也可以选别的便宜的计算型哈,这里就是举个栗子,但是最好别用性能突发实例,之前看到有人分享说不好用,当然你也可以试试,试完了评论说下你的体验给大家参考下。我这个专服就是朋友一起玩,大家白天都上班,这玩意一直在那跑一天也是浪费,所以按需付费是符合我的场景的,不一定符合你的,按照自己的需求来还是。
下面的产品都是阿里云的哈,在这里说下就不再下面说了,然后公网都是开的用的 5M 峰值,按需付费。
将实例创建存为启动模板,每次从模板创建实例能省事不少,然后在不用的时候选择停机不收费模式,但是这样的话云盘还是要收费的,每小时 4分,看起来不多,一天少说要闲置20小时,那就是 8毛 了。想想此时这个云盘上对我们来说比较需要保存的就是存档了,镜像这个装了 docker 之后拉取很方便的。那能不能吧存档文件保存为云文件,我在服务器上像容器一样的去挂载这个数据卷,这样存档一直在那不用管,每次实例创建的时候我挂载一下这个云文件。
可以的,经过我的探索,发现 NAS 文件服务满足我的需求,可以将存储内的某个目录挂载到自己的云服务器上的某个目录,妙啊。
因为本身我是不懂这个服务吧相当于,所以就感觉那控制台可难用了,我创建了文件系统,但是死活找不到去哪新建文件夹,问了客服,客服意思我随着美找个 ecs 挂载一下就能编辑了。这个不好做到云盘那种在线编辑么,起码的能在线建文件夹也好啊,不然我不操作之前只能挂我的根目录啊我丢。好在我按需付费的 ecs 还在,去挂载上,在根目录下新建了十个文件夹,就 dst_save_1 - dst_save_10
,然后把我现有的存档上传到 dst_save_1
文件夹下,唔姆,十个存档位置应该够了(我至今也只用到了一个)。
我买的是最便宜的,你在购买页可能需要换个地域才能看到容量型,默认给到的都是性能型,创建专属网络和VPC,记得和你的实例在一个位置,建议你人在哪就选哪个地域得了,比如你在上海就直接选个上海的地域,记也好记
点进文件系统的详情,在里面找到挂载设置,里面有 ecs 如何挂载文件的说明
有 NAS 之后,我在创建 ECS 实例的时候选择将我的 NAS 根目录挂载到实例的 /ali-nas
目录,然后在饥荒专服的容器数据卷挂载哪里,把 ali-nas/dst_save_1
挂载到容器的 /data
目录,好耶,呼应上了。然后每次创建实例之后只要安装 docker 并拉取镜像运行就可以了,写了个简单的脚本安装 docker 并拉取镜像。利用 ECS 的云助手在每次实例初始化之后就执行这脚本初始化。
通过上一级,基本上可以自动部署了,但是也有一点,我其实不需要 ECS ,ECS 只是用来作为容器运行的环境,那像我这种情况,有没有直接给我提供一个容器实例的地方,我就拉取镜像运行就完了的那种,有的, ECI 弹性容器实例。ECI 有提供一个客户端管理工具 ECI-client(Mac 和 Linux) ,但是这个工具只能管理用 client 创建的实例,唯一的就是它这 ECI 目前没发现有可以停止容器运行的命令,只有启动,重启,删除。
在控制台创建和 ECS 也很像,也需要设置交换机、安全组啥的,不要忘记的是挂载 NAS 到容器的 /data
目录,设置好之后保存为启动模板,这样下次就可以直接从启动模板新建了,有 Mac 或者 Linux 的同学可以直接使用 client 创建,很方便了可以说是。我这里的 yml 配置如下:
执行命令 eci run -f ali-eci.yml -w 5
,就是以配置创建实例,并自动创建弹性公网,带宽5M。这样当我需要的时候一行命令就可以创建实例,然后等它镜像拉取完毕后运行大约十分钟就够了
目前的 ECI 正常启动大约是十分钟的时间,其中拉取镜像需要三分钟左右。这其实可以接受的,但是周末的时候出问题了,镜像拉取完之后启动专服的时候发现一直在 downloading update ,把最近安装的 mod 注释了也还是要 update ,这个之前也出现过,不过之前都是很短的时间就加载完了,我意识到问题并不简单,我猜可能是镜像过时了,确实专服有更新了现在,虽然作者推荐的 latest
是比较稳定的日用的,但是我这里的实际问题确实是更新太费劲,一种是选择使用作者的 nightly
(每晚更新) 的镜像,一种是拉取 github 后自己构建使用,我选择后者,在阿里云新建了镜像仓库,指向我 fork 之后的 github ,增加一个立即构建的触发器,然后在实例就可以直接用自己的镜像了,只要把配置文件中 Image 的地方换成自己的镜像的地址即可,这样可能费用会增加一点点,不过应该还好
至此呢,饥荒专服的研究也差不多了,下一步打算仔细看看那个镜像,毕竟自己现在还是浮于用的地步,弄明白镜像里做了啥,才能对端口是否占用这块有点体会我觉得。这个话我想到有没有人在做这样一种服务,就是出租饥荒专服呢,只要存档能转移是吧,小伙伴保存好自己的存档,每次花一块钱/小时租个云服务器玩耍会有人付费吗?确实,我就不会,太贵了,我选择自己研究研究。主要是游戏热度不够,现在还在的要么是老玩家,要么就是技术流,不会架专服的真不多了。
]]>我需要的就是按需付费,因为伙伴平时都上班的,每天就晚上玩几个小时,为这几个小时开一天就有点亏,如果能有2v4G的学生机那肯定划算,但是我们已经过了时间了,现在再开包年的已经开不起了。
首先因为当前的 NAS 并没有提供一个可以在线编辑文件系统的功能,如果你要编辑自己持久化存储的文件,必须将其绑定到 ECS 实例,然后通过实例来操作,清凉应用服务器是不可以的,所以我们需要一个 ECS 实例:
注意目前来说只有 ECS 可以操作 NAS ,轻量应用服务器是不可以的,之前看这两者的区别的时候,看到说 ECS 支持扩展,当时不知道是什么意思,现在用到了,就明白了,像 NAS 就是扩展之一,给服务器挂载数据卷。我自己之前开的也是轻量应用服务器,毕竟带宽要更好些,然后现在要用 NAS 就得保持账户余额这种方法。
NAS 是阿里云提供的一项持久化存储服务,需要付费,但是以我们的存储量,需要支付的也不会很多,我选的是最便宜的一种(通用型里的容量型),一个月 0.35/GB ,这里的话还是建议大家使用通用型里的性能型,读写延迟更低,价格虽然看起来很多,但是因为我们的使用量并不大,最多也就用个 1G ,我感觉一个月3毛和一个月一块多就还好吧,不如选一块多的。
注意不同地区可提供的套餐也不同,如果发现只有容量型或者只有性能型的选项不妨切换可用区试试,默认给到的都是性能型。创建专属网络和 VPC ,记得 和你的实例在一个位置 ,建议你人在哪就选哪个地域得了,比如你在上海就直接选个上海的地域,记也好记。创建专属网络和 VPC 差不多把必填的都填了就问题不大,拿不准填啥的就用它给你推荐的。
可以看到图中就两个必填项,名称填一个符合格式的,网段上方的提示中蓝字是可以点击的,直接点击一个自动填充进去就好了
在下方的交换机配置中,选择一个可用区, 此处的可用区要和你的实例(如果你有自己的 ECS 实例)对应上的 ,在一个可用区才能通信
NAS 在没有文件传入的时候是啥都没有的就一个根目录,首先创建一个按量付费的 ECS ,配置就选个 1v1G 的配置就好,同样的要注意专属网络和交换机和 NAS 要在同一个区,NAS 中。进入文件系统的详情页,如图显示,选择挂载使用,可以看到下方有显示 挂载到ECS 的选项,点击即可看到操作步骤,十分简单,几步命令就可以了。
挂载成功后,进入 NAS 目录,新建几个存档路径备用,或者使用 ftp 或 sftp 将存档上传到根目录后重命名,假设重命名为 save_1
,这里的存档得是用 docker 镜像版专服生成的存档,其实主要就是确保使用的端口一致。
ECI 可以在页面上创建,也和 ECS 实例一样有启动模板,它提供了一个 eci-client 的方式来创建容器组实例,这里我使用的是 eci-client 的方式,我的目标是以最方便的方式搭建,在页面上操作的步骤还是挺多的,我倾向命令操作。按照 文档 要求安装好 client 客户端,注意这里的客户端目前只支持 Mac 和 Linux ,命令行可用命令参数查看 ECI-CLI 。
新建文件命名为 ali-eci.yml
,文件里面的注释是我为了方便解释加的,如果使用的话最好将注释去了,省的来回粘贴的时候错行了,将安全组ID、交换机ID和 token 填入你自己的,公网带宽的配置我选择放在启动参数里单独写。
新建 h.sh
文件,写入
这样就配置好了,当需要启动的时候只要执行这个脚本就可以了,使用完之后就把这个实例销毁掉。是否写脚本看各自需要。
我用过的 1v2G 的大约每小时 2 毛钱,2v4G 的大约 四毛五每小时,2v2G 的大约是四毛,然后现在 ECI 在推广期,有 100 元的代金券,每天玩几个小时的话能用两三个月。
]]>使用墨水屏显示的设备的尺寸以及形式有很多种,比如墨水屏手机,口袋阅,电纸书,显示器,今天主要想聊聊电纸书,电纸书比较有名的当属 kindle 了,即使你不用肯定也听说过这种泡面盖。电纸书的设备大都是有着宽的边框,在如今的全面屏手机盛行的境况下,似乎是异类的存在。那为什么用电纸书来看书呢,单从看书的角度来说,手机平板一样都可以看书,墨水屏的好处是不发光,可以起到护眼的作用,对于需要长时间阅读的人来说还是很有帮助的。现在的主流墨水屏还是黑白的,也有部分彩色的产品,但是就文字的清晰度来说还是有些差强人意,有点像报纸的阅读质感,据说明年(22年)会有不错的 elink 彩墨屏出现,期待后面的产品吧。所以如果你是彩色阅读的话在选择时就要仔细考虑一番了。
电纸书使用的是墨水屏,不发光,可以保护眼睛,但是我认为良好的看书习惯比护眼的机器更重要,因为除了部分和书关系密切的工作者,大家平时看手机或者电脑这类发光屏幕的时间更久,如果没有一个好的习惯,会格外的费眼。看书习惯,比如保持屏幕距离,适当休息,坐姿等等这些。抛开习惯还有一点不得不谈的就是时间比例,如果你一天要看十个小时的电脑和手机,看30分钟的书,那么这个护眼效果只能说是比没有要好一点点的,时间占比反过来的话自然是很好的护眼效果。
所以你不能说用了电纸书就可以肆无忌惮的看手机电脑了,设备本身的护眼的能力是在的,但具体到个人还是要看使用习惯和使用的时间比例。
不会,电纸书只是工具,不要幻想你有了这个工具之后变得更爱阅读,你得是先有看书的习惯,而后才需要迭代看书的设备,而且如果纸书满足你的需求那便不需要更换。
是的,像我是租房子住,之前从京东、当当买了很多的实体书,每到搬家的时候就很痛苦,这些书放到一个大箱子里,贼沉。有些是已经看过了的,有些还没拆封,如果丢掉可惜,卖又卖不出几个钱,留着又占空间占地方。所以我想尽量把我的存书都电子化,这样携带方便,不占用空间。通勤的时候我会使用一个 6 寸的设备,很轻,解锁屏幕直接就是书籍页面,换乘或者下车直接锁屏即可,缺点就是加上手机要带两个设备。
我手头的设备都是文石的电纸书,一个是之前购入的 6 寸的 PokePro ,一个是最近购入的 10.3 寸的 NoteX。先谈谈我为什么购入这两个设备,因为日常上下班通勤都分别需要 50min 左右,在地铁上的时候手机上常常没啥想看的内容,一般就会用我的 6 寸设备看一会书;下班在家用 10 寸设备看一些扫描的书或者 PDF 体验比较好。我常用的阅读软件是微信读书,但是偶尔也会看一些漫画或者其他的电子书资源,所以我需要一个开放系统,仔细斟酌之后选了文石家的产品。
6寸设备的 ppi 是 300 ,看起来确实比 10 寸的 227 要细腻,但是毕竟是大屏设备,离那么近看的时间也属于是少数,多数时候都会保持一定距离看书,所以这个差别其实还可以接受。大屏也有一个缺点就是,太重了真的,420g 的重量,根本没法长时间拿在手里看,我现在是买了一个蓝牙遥控器,用遥控器翻页,体验害好一点。NoteX 支持提笔就写,但是这个是针对自带的书城或者存储里的书籍,我常用的微信读书是体验不到这个的,顶多能用笔划线方便一点。如果我现在在选择的话我会选择一个八寸的彩屏解决我的所有需求,目前文石有一个 NovaColor 是八寸的彩屏,但是显示效果稍差,据说今年会出新品,可以期待一下。
反光,再怎么宣传墨水屏,它还是个屏幕,就会有反光,反光的话就需要找合适角度观看,不然总看到反光也是挺出戏的。省电,没有实际统计过,但是我充满电之后可以一直用很久,可能也是使用频率一般程度的原因吧。
从价格的角度上来说,PokePro 1k ,NoteX 2.5k ,价格还是蛮贵的,文石在各大城市也有不少体验店,还是建议想购买的选手先去实体店试试之后再做决定,因为第一次使用的话,电纸书可能很难达到你的预期,这种翻页效果,和翻久了之后的残影,不像手机触控的指哪打哪。
说下我为什么购入 NoteX 吧,当时大屏的新品有两个,一个是 NoteX 一个是 Note5+ ,主要看中的是可插内存卡扩展,另外 5+ 虽然用的是柔性屏,但是据群里的小伙伴反馈说看起来会有些不平,而且两个重量上来说只差 40g 半斤八两了属于是,所以还是选择的纯平屏幕的 NoteX 。NoteX 我使用了也有一段时间了,回头可能考虑会出个主观体验视频做纪念哈哈哈。
]]>Vue cli 3
从命令行传入除 NODE_ENV
之外的变量,vue cli3
在环境变量和模式上做了封装,具体的可以查看文档,我们可以很方便的在环境变量文件中定义该环境下的全局常量,但是如果我们需要在项目的命令行上进行配置,比如跟据某个参数的不同打不同的包,环境变量文件中是没法使用变量的。解决办法如下:
]]>Vue cli 3
从命令行传入除 NODE_ENV
之外的变量,vue cli3
在环境变量和模式上做了封装,具体的可以查看文档,我们可以很方便的在环境变量文件中定义该环境下的全局常量,但是如果我们需要在项目的命令行上进行配置,比如跟据某个参数的不同打不同的包,环境变量文件中是没法使用变量的。解决办法如下:
我注意到文档中提及,只会将以 VUE_APP_
开头的变量注入到全局,然后我安装了一个叫做 cross-env
的 npm
包,在命令中写入 "serve:A": "cross-env VUE_APP_PROJECT=A vue-cli-service serve"
在代码中试着输出,是可以读取到的,如果不加前缀则无法读取到,这样我只需要写好不同情况的配置即可,可以说是很方便了。
使用科大源安装,具体见 官方文档
运行之后就开始刷命令行,会要求输入 sudo 密码,需要注意的就是后面有一步下载和安装 Command Line Tools for Xcode
时间会比较久,这要它也没有进度条,看起来就像失去响应了一样,这里只要没有报错,就耐心等待吧。
第一遍安装给我报了个错 Fetching /opt/homebrew failed!
,我直接拿安装脚本又安装了一遍,这次就可以了,命令行最后输出了
按照命令里要求的依次执行这些命令后,输入 brew -v
,能看到输出版本号,就算安装完了
创建 ~/.bash_profile
文件
vim ~/.bash_profile
文件,进行环境变量的配置
完了之后使用zsh终端发现配置的环境变量还是无效,每次打开 zsh 都需要手动 source ~/.bash_profile
解决方案:修改zsh的配置文件,让其在每次启动的时候来读取 ~/.bash_profile
里面的配置。vim ~/.zshrc
在文件的最后面加上source ~/.bash_profile
source ~/.zshrc
使其立即生效
访问 官网 下载最新的稳定版安装包,下载完成后一路下一步即可
访问 官网 下载 Docker Desktop
Chrome 插件 API 文档: https://developer.chrome.com/docs/extensions/reference/
浮层显示,前面的配置完成之后,这只是一个单页应用的开发。写页面这个就不用多说了,里面用到了一些有用的插件 api ,列在下方
获取当前插件的信息,使用的场景是用来打开一个独立页面,就是上面提到的 Index 页面
获取当前 tab 的 url、更新当前 taburl、重载当前 tab 。使用场景是针对 url 上携带的参数进行业务说明,以及编辑参数后重载页面
主要是需要做一个书签页面,添加了开发常用的网址分类等,便于快速跳转。也有一些开发或者查问题用的小工具,做了一个单独的页面,通过在 popup 的页面中主页按钮打开,无甚可说的
因为我们的页面是嵌入到原生 win 应用中的,调试的时候需要通过 Chrome 的 inspect 功能,来查看页面控制台,预期是想做一个能直接在面板中解析页面 url 中的业务参数的功能,这样就不用把 url 复制出来在去解析查看了。但是我琢磨了很久也没找到可以获取 inspect 出来的页面的 url,因为这个 inspect 是一个独立的调试窗口,没有对应的 tab 页签。目前的话我已经放弃了自动获取,选择需要手动输入,起码可以少打开个页面把这样。
获取 inspect 对应页签的 url ,前提是要有页签啊
最近新增了一个功能:给页面注入一个 js 对象并挂载到 window 上,模拟 jsBridge 的作用。
众嗦粥汁,混合开发中,web 和原生应用之间的通信一般由 jsBridge 进行中转,名字可能略有差别,但作用就是帮助 FE 调用 NA,或者反过来帮助 NA 调用到 FE ,我们应用的 Bridge 主要方法有三个:invokeMethod 、addMethod 、callMethod 。需要模拟的是 addMethod 的流程,这个方法实现的是 FE 注册监听 NA 发来的事件,收到事件后执行回调,并传入事件携带的参数。
FE 代码在初始化执行的过程中就试图在 window 上寻找 Bridge 对象,如果找到了就开始初始化监听事件的注册,找不到就不执行了,所以我需要在页面加载前将 Bridge 对象注入,以便页面 js 执行时可以访问到。一切顺利的话,在页面执行中,我可以在 popup 中向页面发送事件来触发回调,实现流程的模拟
新增 inject.js 文件和 QCefClient.js 文件
利用插件的 content_scripts 能力,将 inject.js 注入,但是由于上下文不同,所以直接在 inject 中往 window 上挂对象是只能挂在自己的上下文,无法影响到页面。采用的方法是临时创建一个 script 标签,标签中引入一个可信的 js 脚本资源,只能用路径,不能直接内联代码,然后需要在 manifest.json 中添加一些内容
这样是保证了 Bridge 的注入,然后有注意到我们似乎还用到了一些事件监听,作用就是响应后续由 popup 发送的事件
由于事件是动态的,想要实时触发事件,即调用到对应 tab 的 Bridge ,往页面里实时插入脚本的能力就不能满足了,因为脚本里的内容是固定的,而内联代码又不被允许。解决办法是:先由插件内部通信,由 popup 往 inject.js 发送一个消息,inject 中监听到这个消息后通过 window.postMessage 往 tab 页面发送消息,然后再由 QCefClient.js 中的监听 message 的回调来执行具体的消费事件的动作。inject 和 QCefClient 的代码上面贴了这里不重复贴了,放一下事件发布处的逻辑
里面有一个需要注意的点就是需要有一个 tab 的 id 在流程之间串联,用于找到对应的页面。
后续就是慢慢将事件写在插件中,就可以实现通过插件来 mock NA 的事件消费了。
以上就是使用 vue3 开发一个插件基本要做的,总的来是还是比较简单的,就是做一个多页应用的解决方案,比较耗费时间的是查找需要用的 api ,以及验证使用,因为是业务工具,就不放 github 上了,不过有这些文件基础,复刻一个还是比较容易的哈
]]>首先将自己的需求罗列出来
直接在 Github 上搜索 scp ,高 star 的有一个 scp-action ,听起来就很符合我的需求,而且自带了把文件压缩为 tar 传输的功能,很不错。
主要对于 scp 这个不太懂,所以可能遇到了一些瓜皮才会遇到的问题,tar 压缩的时候是带着 .vuepress/dist 这个路径压缩的,并不是我想象中的只把 dist 中的全部内容提取出来再压缩,但是人给提供了解决方案就是添加参数 strip_components: 2
,主要这个参数介绍,我实在看不懂啥意思,自己试了下才算是意会了。
这个 Action 配置上之后,问题基本就解决了,新的问题是,我部署时用的是新建的 Linux 用户,没有目标目录下的文件增删权限,这个好办,问下 gpt ,得到答案是
设置完成后就可以了。后面发现有的时候简单的方式其实最麻烦,最开始的时候我为了偷懒,让 gpt 给我写解决方案,因为我不熟悉这块的知识,他给我写的方案我无法判断对错,只能相信然后去试,然后在调试它的方案的过程中耗费了不少时间。其实明确自己的需求,拆解之后,现有的库就很容易可以解决需要,像权限这种问一下无可厚非。最后附上我的配置供参考:
因为我这的页面是 hybrid ,不是单纯的 web 页面,所以在 api 的使用上也有着限制。业务场景是,需要用户在别处复制一段内容(一键复制,不需要手动选中),然后来我的页面上进行粘贴,解析后调用接口通过参数传递。首先基于业务场景的考虑,要有一些限制,比如可粘贴的最大字符数是多少,需要做 json 格式校验,需要做内容字段解析,解析出的内容需做简单的 length 判断。然后看粘贴的方案怎么实现,理想的方案是,FE 展示一个按钮,点击按钮的时候调用端的能力去获取粘贴内容,但是当前端并无提供的 action,端改动的话需要跟版,预计会是一个很长的周期,看能不能有 FE 的临时方案,可以无需跟版直接上线,后续等端支持了粘贴能力再做主动获取粘贴。
mdn 上已经将其标记为弃用,自然不在考虑之中
这个也是以前做后台项目常用的,但是这个库只是支持复制,并不支持粘贴能力
这个按说是最合适,浏览器提供的 api 足够强大和安全,但是它在调用的时候会弹出询问框,需要用户点击同意之后才能使用。然后写了 demo 页面在端中测试,当使用端的正式包且使用 https 的页面地址的时候 navigator.clipboard
这个对象才是可用,其次,可能是端的 web 容器对弹出框有拦截操作,在端内使用时,这个询问框根本弹不出来,所以调用会直接报错,error 是 undefined ,所以这个 api 在端内实际用不了
这个 api 具体的使用就不介绍了,网上一大堆
当用户通过浏览器的用户界面发起一个“粘贴”动作时,将触发 paste
事件。试了下这个还是比较符合预期的,但是需要文案提示用户,通过 Ctrl+V 键进行粘贴操作,也算是符合常用的粘贴操作吧,可以接受。
但是这个后面联调的时候发现了一个怪问题,就是我们常见的操作是,点击页面聚焦,然后就可以进行粘贴操作了,但是在端内的时候,需要点击两次才能监听到粘贴事件,只点击一次的时候无法获取到焦点,在浏览器中是没有这个问题的,但是毕竟浏览器的页面本身自带一个聚焦,所以这个对比也不是特别可靠。然后经过了艰苦的排查,并尝试进行 hack,看能否让用户只点击一次就行,结果都是不行,然后想是否容器有问题,因为另一页面的输入框也是需要点击两次才能聚焦,找了端上的老师排查之后,果然,端的底层做了一点事情,将第一次点击焦点直接丢弃了,所以每次需要点两下才能获取焦点。噢漏,这属实难顶。
所以最后的主要方案还是要使用端的能力去主动获取粘贴内容,这样稳定可靠,交互简单。FE 的方案作为发版前的临时方案使用,会给用户提示,需要双击后再 cv 粘贴,然后给粘贴框加了一个 focus 样式,用伪类写一个闪动的光标就行了,然后粘贴框是 div,正常是无法获取焦点的,在标签上添加了一个 tabindex="-1"
的属性,使其可以响应聚焦,这样用 css 就可以准确达到聚焦的效果。用 js 的话反而麻烦,因为页面在端内只是一部分,端内还可能会点击页面之外的地方,一些边界条件需要判断,就比较麻烦。
而且监听粘贴事件的话,没法主动控制粘入的内容的大小,用户粘一个 1G 的内容也是可以的,但是会引起页面的卡顿,这个暂时没什么好的解决办法,只能是等主动粘贴能用之后去掉这个被动粘贴比较靠谱。
]]>我试了一下他的代码,并不行,编码不识别,但是看了下逻辑没有什么特别的,无非就是用一个定时器,每隔一点时间改掉 icon 罢了,自己去找了几个表情的图片格式的,写了一点代码,实现了这个效果,看起来还可以,哈哈哈
链接地址 ,效果如下:
]]>cookie
的值失效了,观看进度都变成了 尚未观看
,为了方便的改 cookie
的值,我想在后台管理里面增加一个配置项,这样我通过后台就能直接更改参数,不用再手动改代码后发布主题。PS:为了方便用我主题的小伙伴(虽然我觉得也没有人会用o(╥﹏╥)o),多加了一个用户 ID
的配置。
]]>cookie
的值失效了,观看进度都变成了 尚未观看
,为了方便的改 cookie
的值,我想在后台管理里面增加一个配置项,这样我通过后台就能直接更改参数,不用再手动改代码后发布主题。PS:为了方便用我主题的小伙伴(虽然我觉得也没有人会用o(╥﹏╥)o),多加了一个用户 ID
的配置。
在主题下面找到 functions.php
文件,我们可以看到文件中有一个主要的函数 themeConfig
,里面的内容大致是:
这里面的 $logoUrl
就是我们在主题的外观设置中的默认的第一项,与之类似的,我们想要增加一个一样的表单项,只需要把这个复制一份,换成我们定义的名字,就可以增加一个表单项啦,比如:
添加好之后,保存,去我们后台管理系统里面,控制台-->主题-->外观设置
,就会发现多了一个输入框出来,那么我们的初步目标就达成啦,接下来就是想办法在追番列表这个页面中取到这两个值
进入到 sub-anime-list.php
文件中(这是我定义的追番列表页面的模板),使用如下代码:
就可以取到这两个值啦,然后在需要的地方把这两个变量替换上,并与之前后的字符串使用 .
拼接上即可,例如:
这样我们回到页面刷新就可以看到啦
typecho使用 themeFileds 增加自定义字段和主题设置 主要参考了这篇文章,感谢大佬的文章,对我很有帮助
]]>export default
和 export
是 ES6 提供的两种模块导出的方式,他俩的区别是前者是导出一个整体,后者是导出单个,举个栗子来说,现在有两个 tools 文件,tools-al
l和 tools-part
,内容如下
]]>export default
和 export
是 ES6 提供的两种模块导出的方式,他俩的区别是前者是导出一个整体,后者是导出单个,举个栗子来说,现在有两个 tools 文件,tools-al
l和 tools-part
,内容如下
在 index.js
中引入使用
看看打包后的结果吧
使用 webpack
打包后的结果中可以看到,虽然我们引入 toolsAll
只使用了 toolAll1
函数,但是函数 toolAll2
也一起被打包进来了,因为是将 toolsAll
整个的引入进来了,而只从 tools-part 中引入了 toolPart1
函数
关于这两种导出方式的使用场景呢,在项目中使用 webpack
打包,相同的文件只会被引入一次,所以按照一般项目的设计来说,类似 api.js
和 tools.js
之中的内容都是项目中要用到的,使用 tools.check()
这样的方法还能比较直观的看出函数的归属文件
然后在设计提供方法的库或者插件的时候,因为别人引用你的插件不一定使用你全部的方法,可能只用一两个方法,这样的场景采用 export
可能是要更合适一些
说一点个人在命名上的理解,如果使用 export default
这样导出整体呢,具体到函数的名字就可以简单一点,因为他们都会有一个前缀,类似 walletApi.create() walletApi.send()
这样;使用 export
导出单个呢,为了让他们和组件内的函数有区别,命名类似 createWalletApi() sendWalletApi()
这样,对于函数的用处从名字上就能得到直观的感受
80
端口,这样就可以通过域名来直接访问我们的项目,但是当我在 Mac 上运行项目的时候,发现项目并没有起在 80
端口,而是随机分配了一个端口。
]]>80
端口,这样就可以通过域名来直接访问我们的项目,但是当我在 Mac 上运行项目的时候,发现项目并没有起在 80
端口,而是随机分配了一个端口。
Mac 上也有 hosts ,修改方式在内容上和在 Windows 上是一样的,我比较习惯用终端,这里只陈述一下终端的方法, 你喜欢从访达里打开修改的话,建议先复制一份出来改好之后再把原先的覆盖掉比较方便。
使用 sudo vim /etc/hosts
输入密码后,打开 hosts 文件,编辑完成后,因为 hosts 文件默认是只读文件,所以先按 Esc 键,输入 :set noreadonly
回车,再输入 :wq
就可以保存文件了。
不建议使用命令将 hosts 文件直接改成可读写的,因为 hosts 毕竟还是重要的系统文件,为了安全起见,将其设置为只读是没毛病的
利用 pfctl 做网络层的转发,转发 80
端口的请求到 9090
端口,此处的端口号建议选择大一点的数字,防止占用系统使用的端口号,因为前端的 vue
项目默认都是起在 8080
端口,因此不建议设置为 8080
端口。修改 pf.conf
文件, sudo vim /etc/pf.conf
,和上面一样的,输入密码后打开文件,修改后的文件如下:
运行以下命令让转发生效或关闭
这样就可以转发 80
端口的网络请求到 9090
端口,注意访问的还是 80
端口,只是我们启动项目时监听 9090
端口。需要注意的是,这样我们的项目和在 Windows 上开发是使用的不同的配置,Windows 的项目配置中是监听的 80
端口,Mac 中是监听的 9090
端口,但是访问的都是 80
端口,不过 Mac 多了一层转发罢了。可以在 package.json
中加一行配置
这样项目确实可以在本地的 80 端口访问并打开了,但是还有一个问题是,项目不能随着代码的保存进行自动的热更新,因为你当前访问的是 80 端口, 9090 端口是进行着热更新的,80 端口并没有,此问题还未找到解决办法,待续。。。
[Mac OS 绑定 80 端口](
]]>!
然后按下 tab
键就可以帮我们自动补全 html
结构,那么当我们写 Vue
或者是 React
的时候,页面其实都是有一个初始模板的,我们要怎样做到类似上面简单输入就可以得到文件模板呢,今天就以 Vue
为模板举栗给大家介绍 VSCode 上的一个很好用的功能,叫做 用户代码片段。
]]>!
然后按下 tab
键就可以帮我们自动补全 html
结构,那么当我们写 Vue
或者是 React
的时候,页面其实都是有一个初始模板的,我们要怎样做到类似上面简单输入就可以得到文件模板呢,今天就以 Vue
为模板举栗给大家介绍 VSCode 上的一个很好用的功能,叫做 用户代码片段。
首先我们选择 文件--> 首选项 --> 用户代码片段
输入 Vue
,在下拉中选择 Vue.json
将文件中的代码覆盖为(注释中的内容可以去掉,在编辑器中鼠标悬浮在对象的键上就可以看到这些提示啦)
然后新建一个 Vue
文件,输入 vue
,选择我们刚才创建的模板,一般是下拉里面的第一个,然后我们的文件模板就生成好啦
生成效果
同样的,我们可以根据上述语法片段来创建我们自己的文件模板,比如项目中自定义的 api
文件等
通过打开的代码片段json文件,右键选择在 finder 中打开,直接在文件夹中删掉对应文件即可。为文件夹创建的代码片段在文件夹下的 .vscode
文件夹中。
settings.json
中添加一段 "[markdown]": { "editor.quickSuggestions": true }
editor.suggest.snippetsPreventQuickSuggestions
置为 false ,我并未用到,关于这项配置可以看看 这篇文章 给出的解析"editor.snippetSuggestions": "top"
来保持自己的代码片段在最上方整理一下常用的文件模板,方便查询使用, vue 的在上面,我就不重复添加了
用的熟练了之后可以注释等辅助去掉,只留一个基础架子
]]>Debug
,做这个功能我是真的佛了,中间都想放弃了,但是实在是不甘心,周一晚上下班回来搞到两点,终于解决了,虽然最后的方案已经远远不是我最开始的时候采用的方法了。我的 PHP
代码写的很渣,不要喷我,我已经尽力了。先贴上 我的代码
]]>Debug
,做这个功能我是真的佛了,中间都想放弃了,但是实在是不甘心,周一晚上下班回来搞到两点,终于解决了,虽然最后的方案已经远远不是我最开始的时候采用的方法了。我的 PHP
代码写的很渣,不要喷我,我已经尽力了。先贴上 我的代码
好多博客上面都带了追番列表这个东西,自己自然也是想要搞一个,于是打开我B站的个人空间,查看我的追番列表都调用了什么接口,发现是调用了一个 api.bilibili.com
的 get
接口,ok ,那么我只要在我的页面中也调用这个接口拿到数据后渲染出来就好啦。
新建页面模板,先把静态页面的样式写完(照着 B站 的样式来的,我个人觉得蛮好看的),然后写 js
,用 ajax
调用接口,返回数据拼接,然后放进页面中准备好的容器 <div class="sub-list-container"></div>
中,先使用 fiddler
代理到本地的 json
文件进行假数据的调试,没问题,跨域的问题我寻思线上环境使用 nginx
做个代理就可以(T_T 我太天真了),上线之后各种报错,nginx
的配置我是改了又改,依然不得行,中间各种操作试图解决问题我就不详述了,因为最终没有使用这个方法来实现。
在我不断的 Google 着试图找到解决办法的时候,我发现了这篇帖子 php查看B站互相关注的好友 ,我当时就惊了,竟然还有这种方式,而且看起来很靠谱的样子,他的接口和我的接口基本类似,我应该也能用类似的方法来实现。
照着他的方法魔改之后测试,果然 OK 了
问题:图片防盗链不能访问
解决办法: img 加上 referrerpolicy="no-referrer"
的属性值,并且在页面头部加上<meta name="referrer" content="no-referrer" />
问题:换行导致代码以不可描述的位置结束报错
解决办法:使用正则将生成的字符串中的 \n
都去掉
问题:追番进度不显示
解决办法:加入 cookie 值 SESSDATA 即可,但是这个值需要定期更新呢
中间省略了很多 debug
的细节,我感觉也没必要贴上,毕竟能 Google 到的问题也不算问题
原因:less 的计算方式和 calc 方法有重叠,两者在一起有冲突;
解决:width: e("calc(50% - 40px)");
或 width: calc(~"100% - 40px");
引申:在 scss 中使用 width: calc(#{$thirdWidth} - #{$padding});
解决问题
原因:less 的计算方式和 calc 方法有重叠,两者在一起有冲突;
解决:width: e("calc(50% - 40px)");
或 width: calc(~"100% - 40px");
引申:在 scss 中使用 width: calc(#{$thirdWidth} - #{$padding});
解决问题
关于博客由框架变更的说明
]]>关于博客由框架变更的说明
有小半年没有更新了,最开始的时候想自己做一套博客从前端到后端,既能练手 node ,又能方便后续扩展,但是计划迟迟没有开始,想了很多,做的很少,还有阿里云的服务器明年初就到期了,自己也不想要太重的应用,维护也费劲,一番寻找最后还是回到 vuepress 的使用。同为静态博客不选择 hexo 的主要原因是自己本身使用 vue 较多,vuepress 基于 vue ,后续做扩展的话也省力一点。动态类博客,WordPress、Typecho 这重的轻的框架我都尝试过了,主要我写的文章本来基于 md ,我自己都有做本地的存储,这样的话感觉静态比较贴近我的需求,稍麻烦一点的就是评论。但是我看了我旧的博客站点,哈哈,运行两年就才五六个评论,所以我认为评论这可有可无吧其实,现在也有比较成熟的插件,像 Valine、Waline、Twiko 之类的,但是我的文章的链接也可能会调整,所以暂时也不接入了,反正有邮箱可以联系毕竟。
说实话现在除非自己有一点流量,不然个人网站的流量真的是比较少的,搜索引擎会更偏重于知乎简书之流,有这么一个网站主要是做做记录,想太多没啥用。vuepress 本身有个侧边栏,好多主题把这个侧边栏去掉了,我感觉这个侧边栏还是很好的,在划分这个侧边栏的时候本身就是在进行文章的分类了,当然也有一些文章不知道他们应该在哪个分类,所以你会看到有的文章是没有侧边栏的。
动态博客的好处在于可以随时改(有 CMS ,操作方便),静态博客则需依赖编译。但是鉴于现在云服务的便利性,可以实现类似 github 修改后提交 --> 钩子触发自动发布 --> 页面更新
(假装我实现了🤔)。
总之:好耶!Fighting!
换到 vuepress 之后最大的感受就是因为都是文档,而这个又没有草稿的概念,所以每次重新构建可能会新增许多的文章
博客现在已经是迁移完的状态了,旧站点还是可以访问,只不过后续不在维护,如果更换服务器也不会再重新部署旧站了
]]>以前用的 Mac 是没带 touch bar 的,最近换的带 touch bar 的这款用了也有些许时日了,先说下我平时的使用习惯,因为我一直用一款截图软件 Snipaste ,它的截图快捷键是 F1 和 F3 ,用的也比较习惯了,再加上前端开发常用 F12 ,所以开始是设置 touch bar 一直显示 F123 键这些,但是这样方便截图之余其他的功能就有些麻烦。接下来进入正题,今天给大家介绍一款可以自定义 touch bar 的软件 BetterTouchTool (emmm,要付费,而且有点贵,但是...对吧),下文简称 BTT 。BTT 社区论坛
先上图给大家看一下我设置的效果,常用截图贴图功能按钮,实时显示 IM 通讯软件状态,音乐播放器控制组件。一句个性签名,静音按钮,锁屏按钮,时间显示,睡眠按钮,emoji选择器,设置按钮,F12 按钮
按住 静音按钮 显示亮度和音量滑块,显示:
按 设置按钮 显示应用栏和清空废纸篓按钮,显示:
基本上通过图片应该就能脑补出这些的作用。
略
BTT 的功能非常多,本文只是用来设置 touchbar ,其他的功能我目前还用不到,如果后续用到的话再和大家分享,所以本文提到 BTT 都是在设置 touchbar 功能里的哈。还有一款叫 Pock 的软件也可以自定义 touchbar ,但是我用的时候它还不支持自定义控件,所以最后是用的 BTT ,自由度比较高。
BTT 里面提供了很多预置的控件,基本上能满足大多数的需求,还可以通过脚本的方式来控制控件,文章后面会有一点篇幅来简单举例如何添加一个控件
软件的一些 touchbar 的基础设置
通过预设导入功能可以导入别人的预设,如果看到网上分享的有意思的预设可以通过这种方式导入,然后自己做一点自定义或者直接拿来用
我使用的软件里面是带有一份默认预设的,默认预设里有很多基础的控件,大多数的需求可以被满足,默认预设提供的控件如下,基本上从控件的名字就能知道它的作用。
选择了控件之后,可以设置这个控件的自有属性以及与 touchbar 相关的共有属性,可以选择为这个控件指定一个触发操作,可指定的触发操作有
可用控件,触发操作以及他们的配置,通过中文或者简单的尝试就能知道他们大体的意思,需求不复杂的话其实也用不到太多的控件,脚本支持 apple script 和 js ,但是 js 的写法肯定有点不一样,其他的功能通过 UI 界面配置起来还是很简单的
举例下说下静音按钮的设置:
亮度和声音
,分组设置默认不显示这样可以将 touchbar 很好的利用起来,日常使用也更方便了有木有。分享下我的预设 ,大家如果有自己的设置欢迎在评论区分享讨论
]]>软件首页是这样的,马赛克掉的是我自己的一些服务器 ip 。
首先我们点击左上角的 Session 按钮来配置我们要进行的会话(连接),打开可以看到中间有一行字 Choose a session type ... 让我们选择一个 session type ,选择 SSH ,可以看到如下界面:
将我们服务器的 ip 填入输入框中,点击 OK 即可,然后我们就会看到左侧的 Users sessions 中多出了一个 ip 地址,就是我们刚才填入的 ip 地址,并且软件会自动为你打开一个会话进行尝试连接远程 ip ,如果这个 ip 是可连接的服务器,便会出现让你输入用户名的提示 login as:
我们在光标处键入用户名然后回车(一般没有进行用户权限分组啥的就只有一个 root 的用户),如果有这个用户,便会出现输入密码的命令提示 Password:
,在光标处输入密码回车即可。注意: 在Linux 中,密码是不可见的。
部分开发人员经常需要使用到 hosts
,要么是从文件中找到位置去修改,要么是直接在终端中修改,当我们有多个项目不同的 hosts
,通过这种方式管理起来就比较麻烦了,今天给大家推荐的是一款可视化操作 hosts
的软件,名字是 SwitchHosts
,下载链接
部分开发人员经常需要使用到 hosts
,要么是从文件中找到位置去修改,要么是直接在终端中修改,当我们有多个项目不同的 hosts
,通过这种方式管理起来就比较麻烦了,今天给大家推荐的是一款可视化操作 hosts
的软件,名字是 SwitchHosts
,下载链接
本文写于 -- 软件版本: v3.5.6
本文只介绍这个软件的基础用法,如果有更高级的需求,推荐去阅读 文档 ,先看一下它的界面
它提供暗色和浅色两种主题,我使用的是暗色主题,左侧列表带开关的都是自己添加的 hosts
,系统 Hosts
是系统当前的 hosts
,你可以在这里看你当前启用的 hosts
,这个文件区是不可更改的。你可以根据你的不同需要建立不同的 hosts
文件,用来区分各个环境,需要时只是打开对应的开关,防止在一堆域名间切换注释造成的麻烦。添加 hosts
的时候提供多种方式可供不同需求选择:
对应的也提供了导入和导出的功能,即使是换了电脑也很方便。
还有一个好用的小功能就是可以直接在托盘选择想启用的 hosts
配置,切换便捷迅速,如图
Windows
下安装后操作不生效,可能是权限引起的,退出应用后,使用管理员身份重新运行Mac
下操作不生效,根据提示输入账户密码本文主要介绍三个工具软件,其实做的都是一样的事情,只是适用不同平台,Windows 平台的 v2rayN ,macOS 平台的 v2rayX 和 Android 平台的 v2rayNG 。iOS 平台是使用 shadowsocketR ,这个软件也不难,但是获取比较麻烦。
]]>本文主要介绍三个工具软件,其实做的都是一样的事情,只是适用不同平台,Windows 平台的 v2rayN ,macOS 平台的 v2rayX 和 Android 平台的 v2rayNG 。iOS 平台是使用 shadowsocketR ,这个软件也不难,但是获取比较麻烦。
v2ray 面板一键安装脚本 ,有选项可以一键开启 BBR 加速,使用非常方便,具体脚本以链接中的为准
待更新
下载地址: https://github.com/Cenmrev/V2RayX/releases
v1.5.1下载链接: https://github.com/Cenmrev/V2RayX/releases/download/v1.5.1/V2RayX.app.zip
将下载的文件解压,解压出的直接就是可用的应用程序了,为了方便使用可以将其拖进 应用程序 里,这样在启动台里就能直接看到它了
在启动台点击,启动了之后会在状态栏出现一个图标,点击 Load core 启动底层程序,启动后这行文字会变成 Unload core ,主要的功能操作已经在图上对应的标出了
点击 Configure 按钮进入配置页面,点击 Import 按钮,选择 Import from other links ,在弹出的输入框中输入链接进行导入
导入完成后设置 Security 为 aes-128-gcm ,关闭配置窗口,点击托盘图标,选择 Server ,选择刚才导入的配置,这样基础工作就已经做好了,后面就根据自己的需求决定使用哪个模式就勾选哪个即可
顺便说下这里的三个模式:
待更新
]]>我常用的功能是截图和贴图,贴图在屏幕上,用来查看设计什么的十分方便,操作简单,使用灵活,用过的小伙伴都说好。截图不多说了,是一款非常实用的的图片工具
这个工具可以把 Windows 的资源管理器以标签页的形式展示,我们平常在工作或者是学习中使用电脑的时候,为了方便,可能会同时打开多个资源管理器,在众多的资源管理器之间切换还是比较麻烦的,还容易点错。
这款软件可以像浏览器一样,让资源管理器以标签页的形式打开,已经打开的文件夹一目了然,切换起来也是清晰明了,另外还有收藏功能,图中马赛克的部分就是收藏夹,在文件夹中 Ctrl + D
就可以快捷的收藏当前文件夹,下次打开的时候就很方便啦。
这个比用电脑自带的搜索效率要高上许多,使用简单方便,在你需要某个文件的时候非常靠谱,会记住搜索历史,像 hosts 文件。
我们经常会想在电脑中查找某个文件,但是自带的文件搜寻的效率实在是太低了,看着缓慢移动的进度条直叫人抓狂, EveryThing 这款软件虽然体积小,但是功能十分强大,能快速从硬盘上检索出你需要的文件,然后再搜索记录中双击打开或者右键打开文件路径就可以,提升工作效率,节省时间。
适用于Windows的免费多功能颜色选择器,这个工具差不多前端同学会比较需要。
快速录制 gif 的工具,这个工具既可以录制 Gif 又可以编辑 Gif ,可惜只在 Windows 上有,操作很简单,我就不赘述了。
这个工具可以快速将图片上传至七牛云图床(七牛云在短暂的试用期之后需要你用备案过的域名来进行访问),在写需要插入图片的 markdown 文章时非常方便。要注意的是,在不用的时候记得关掉他的截图上传和复制上传,不然你的七牛云之中就会多一些奇奇怪怪的图片。
这是一款非常好用的 Markdown 编辑器,以前的时候只支持 macOS ,现在已经支持 Windows 啦,而且界面差不多,这款软件主张的是所写及所得,即你写的 Markdown 语法会即时的转换为预览的样子,也可以选择一边写一边查看预览,支持主题自定义,自带的主题里面我最喜欢的就是 Night ,因为比较喜欢暗色调。PS:本文就是使用 Typora 编辑的。
后续有好用的工具也会及时和大家分享的
]]>https://www.processon.com/ 一个做流程图的网站
https://tinypng.com/ 图片压缩但不丢失清晰度
]]>https://www.processon.com/ 一个做流程图的网站
https://tinypng.com/ 图片压缩但不丢失清晰度
https://www.websiteplanet.com/zh-hans/webtools/imagecompressor/ 可以压缩 JPEG 和 PNG 且最大支持 50MB 的文件。 Thanks for Virgy who provide the info.
https://mpkf.weixin.qq.com/ 在小程序里增加了客服功能的话,可以在网页端便捷管理
https://weixin.hotapp.cn/ 可以生成二维码样式的小程序码
https://transfonter.org/ 在小程序里使用 iconfont 的话会用到
https://code2flow.com/ 用代码写流程图
https://www.uuidgenerator.net/ 可以在线生成 UUID ,临时需要的话可以直接来这里生成一个
https://app.xuty.tk/static/app/index.html#/explore 一些很火的 GIF 表情包可以在线制作,输入文字即可生成很方便
https://www.woodo.cn/home/ 在线幻灯片制作
https://greasyfork.org/zh-CN 油猴脚本大全
https://www.wechatsync.com/ 一次排版发布,多平台同步发布。解放自媒体人生产力,专注于写作本身!
http://www.dmzshequ.com/forum.php IT资源分享站
https://www.toodoo.com/db/color.html 如题
https://www.photopea.com/ 在线 PS ,可以说和 PS 长得几乎一模一样了
https://www.mdnice.com/ 转换 md 文档样式,一般转出 微信公众号、知乎 可直接粘贴的样式
]]>这书挺好的,将IT团队的管理及与公司其他部门的协作以小说的方式呈现,不会有晦涩难懂的专业名词,看着比尔由最开始的迷茫到后面的情况一步步掌控局势。
好吧我承认书读完了之后没啥感想
]]>人际关系的基本技巧 原则1 不要批评,不要指责,不要抱怨 原则2 真心实意地感谢他人、赞美他人 原则3 激发他人的需求
赢得他人喜爱的六个方式 原则1 建立对他人的兴趣,真心诚意地关注他人 原则2 微笑 原则3 无论对于何人,无论以何种语言,自己的名字都是世界上最甜蜜最重要的词汇 原则4 专注地倾听,鼓励他人谈论自己 原则5 谈论对方感兴趣的事情 原则6 真心实意地让对方知道他有多重要
「小结如何让他人想你之所想」 原则1 赢得争论的方法只有一个,那就是避免争论 原则2 尊重他人的观点,绝不要说“你错了” 原则3 如果你错了,请坚决果断地承认错误 原则4 沟通始于友善 原则5 让对方点头称“是” 原则6 让对方主导谈话 原则7 循循善诱,让对方自行得出结论 原则8 抛开成见,将心比心 原则9 体谅他人的想法和愿望 原则10 激发对方内心深处的高尚情操 原则11 戏剧化你的想法 原则12 激将法
如果想改变对方的态度或行为,领导者须将下述建议谨记在心: 1.实事求是。做不到的事情请不要承诺。忘记自己的私利,关注对方的利益; 2.目的明确。清楚知道你希望对方做什么; 3.有同理心。扪心自问什么是对方真正的需求; 4.换位思考。想一想对方帮你做事能得到哪些好处; 5.利益交换。找到上述好处与对方需求的结合点; 6.表明态度。提出请求的时候,向对方说明他如何能从中受益。
「小结如何改变他人,成为领导者」 原则1 欲抑先扬 原则2 间接地引起对方的注意 原则3 批评对方之前,先谈谈你自己的过错 原则4 以引导代替命令 原则5 给对方留足面子 原则6 夸奖他人每一点微小的进步,“由衷地赞许,不吝啬赞美之词” 原则7 用美誉激励他人,他就会努力不辜负你的期望 原则8 鼓励对方勇于改变,让改正错误听起来轻而易举 原则9 让对方乐于为你做事
人们视欣赏和认同如瑰宝,弃虚伪与逢迎如尘灰。
「小结幸福家庭生活的七个法则」 原则1 别唠叨了 原则2 不要试图改变对方 原则3 请勿责难 原则4 真心诚意地欣赏对方 原则5 细微之处见真情 原则6 谦和有礼 原则7 读一本解析婚姻中性事的好书
]]>以前总以为,人生中最难能可贵的是相遇。后来才明白,其实最美好的是久别重逢,别来无恙。那时候没有说再见,是因为知道,我们终会有再相见的一天。
阅读时长: 9h15min
]]>以前总以为,人生中最难能可贵的是相遇。后来才明白,其实最美好的是久别重逢,别来无恙。那时候没有说再见,是因为知道,我们终会有再相见的一天。
阅读时长: 9h15min
书摘:
虽然我说了很多条件,但最终买哪件,不是应该取决于你去商店的初衷吗?为了御寒就买棉衣,为了出席正式场合就买西服。你在商店里站太久,已经忘记自己为什么而来了。就好像有的人出门太久,已经忘了自己为什么要上路。
一半扎根黑暗,一半迎接光明。根扎得越深,看到越多黑暗和腐烂,就会长得越高,越努力争取阳光。
刚刚在天台我其实是想说,除了处长,还有一个人,她像一道光照亮了福安弄。从陈宪民得救那天开始就是了。明明她什么都没变,可我就是觉得她成了另外一个人。就好像身边突然有太阳升起来,到处都被照亮了。
以前总以为,人生中最难能可贵的是相遇。后来才明白,其实最美好的是久别重逢,别来无恙。那时候没有说再见,是因为知道,我们终会有再相见的一天。
这本书讲述了我党在抗战胜利前夕即解放战争期间战斗在隐蔽战线上的同志们的故事,顾耀东从一个单纯的小警察出发,一步步成为一位优秀的战线伙伴,前段时间在看《光荣时代》这部电视剧,在看这本书的时候也能看到很多相互印证的地方,比较有意思。在剧的开始看到的一个书评就又些许的给我剧透到了,说顾耀东没赶上电车是他人生的转折点。看书的前半段,我也有同感,感觉沈青禾的一个小举动却毁掉了顾耀东的生活,但是看到后半段的时候,又在想,如果顾耀东进入了刑侦一处,他应该也还是不会快乐,一处虽然有大案要案可以办,但是他们办的案也不会完全从公正角度出发,像陈宪民案。
顾成长之后也变得进退有度了,无论是否要匡扶正义,只有单纯鲁莽是不够的,有时把问题的失败归因为自己的性格,是否还是因为自己不够努力,像书评一,去商店是为了买什么样的衣服,要实现自己的目标,不应为外物影响判断。在成长的道路上人人都曾是顾耀东,有人后来成为了杨志勇,有人是杨奎,但是也有人是夏继成,是沈青禾。有人淋过雨便想着为他人撑一把伞,有人却只想撕毁别人的伞。书的结局是美好的,顾沈在 5 年后又重逢,但更有千万的人,他们永远不会再相逢,为了信仰战斗,为了给后来人撑一把伞。
他们为了信仰战斗,令人敬佩又羡慕,当年从那个环境奋战至胜利何其困难,当今又有多少人还坚持着信仰,是还在为信仰而战,还是已经在时间推移中已经成为了敌人。
]]>这本书说的不光是治人,也有治国,人病了有药医,国家病了得上思想层面了。这是书的上部,在末尾已经开始讲革命相关的了,下部今天看微读已经上架了,还算连贯。可能不太适合我,感觉看了之后没有太多深刻的感受,但是对于主角三人的友谊印象很是深刻,尤其是孙希作为卧底投了账本和另外两人反目,然后后面又和好的情节。下部我看了个开头,姚英子在称呼方三响的时候已经可以直接说蒲公英了,这也是对于友谊成长的见证,已经是很熟悉的人了,也可以有个类似外号的称呼,虽然最开始的时候方三响是很介意这个称呼的,毕竟自尊心在那,现在不在意了可能也是有一点释然呢。
这个是看了电视剧之后感觉比较有意思所以想去看书的,如果不是电视剧的效果,我想我是不会看这样的书的,这个甚至不能叫做书,应该只是剧本罢了,我所期待的更丰富的剧情,铺垫等等在书里都没能看到,没有了电视剧中那些搞笑桥段感觉整一个平铺直叙,总共花了一两个小时就看完了。这个我还买了纸质的书,因为开始听网上说,电子书是有删减的,只有二十多万字,纸质书完整的,有五十万字,看完纸质的又看了下电子书,发现完全是一样的。
电视剧我看到 30 集就没有往后看了,因为感觉安欣太辛苦,没有了看下去的欲望,坚持正义正直善良就是这么辛苦,更多的人是牺牲在半路上的李响、陆寒、谭思言们,后面也没有提安欣的结局,本来我想说得有一些物质或者职位的提升来回报这些人的坚守,但是最重要的还是坚守到天明。另外,怎样让正义更容易得到伸张,这是值得思考的,在这片大地上,还有很多的安欣与李响,他们得什么时候可以安心,可以实现理想呢?
这本书讲得是 1998-2008 年间一个工厂艰难的发展之路,是我很喜欢看的题材。另外还相当于是 《大江大河》的续作,熟悉的宋运辉、梁思申也都有出现,而且给主角柳钧提供了不小的助力,另外笔墨比较多的还有杨巡,但我真不想提他,有的书评说杨小馒头变了,但是我认为他开始就是这样的人,出身不能成为一个理由,宋运辉也是小地方出来的,也是靠自己的努力一步步登高,但是他在高处的时候也能坚持自己的底线,杨巡自己不当竞争在先,吃了亏之后,就找人给柳钧把手指切了,这真是秀才遇到流氓。
实业确实是很难发展的,尤其是很难坚持,书中也是经历了全民炒股、房地产、互联网,在看到别人的赚钱与轻松后,还能坚持自己热爱的,坚持自己这趟艰难的制造业之行,令人佩服。柳钧的人格操行也是非常好的,不然也没法得到宋总的认可,周边聚集的朋友也是都非常靠谱的,书中和东东还是有点竞争关系的,但是东东也能借给他钱应急,钱宏明不必说了,更是很铁的哥们,两人互相应急多次。国家的稳定发展离不开坚实的制造业基础,希望能多有一些纪录片记录制造业的坚守。
说到钱宏明,真是为他可惜,他的老婆真是蠢啊,【靠,嘉丽居然回国】,这是柳钧在自己的博客上写的,也是我想说的,虽然说被钱宏明保护的很好,不怎么理解钱宏明的具体的工作,但是好友都给你说那么具体了,你回来他会有危险,还是坚持回国,不想想自己的孩子?还以为自己回国是共患难来了,结果逼得钱宏明只能自杀,而在钱宏明死后的三个月,政策就回暖了,只要坚持三个月就柳暗花明了。有那么一刻我还想这人是不是段位实际上更高,她回来是为了报复钱宏明的出轨,但是看后面精神失常这个估计可能性不大。从一定角度上来说,希望女性在结婚后也要有自己的底气或者奋进,不要完全依赖男人,这样才能更好的保护自己。
这个之前看过电影的,很喜欢看,书里会多一些细节,很棒的。结尾留了一个开放式的结局,作者说收到很多读者来信希望一定要给他们一个吻,我反而觉得这个开放式的结尾就是最好的,千人千面,看完书之后自己写出自己想要的结局就可以了,这映射到现实中何尝不是一种选择。布莱斯算是幸运的,他没有到他父亲那个年纪就认识到了自己的懦弱,还有时间有机会去改变,看他最后去院子里给朱莉种无花果树,我就想,这孩子兴许还有救,其他的举动的话真很难想出来原谅他的理由。另外感觉朱莉真的是一个很棒的女孩,有自己的想法,而且家庭氛围也很棒,看到朱莉的父母总是耐心的对待朱莉的想法,就感觉朱莉这个样子是理所当然的,家庭虽然不算富裕,但是在精神上却很富裕。总之这是一部非常值得一看的书,嗯,给小孩子看我感觉也很合适,当然先需要家长认可,如果要在意早恋的影响的话就算求了。作者通过这本书想要表达的就是看到很多小孩子们在一起,但是却没有真正的认识对方,想教大家学会通过表象看到内在。
]]>写了又删写了又删,很难用文字把我的感觉表达出来,这本书说实在的颇负盛名,我也是慕名而来,下面就只谈谈对各个人物的感受吧
白灵,白灵走的太突然啦,我感觉她的故事刚要开始,作者就给了她结束,绝了。作为为数不多的早早觉醒的青年,白灵对自己在做什么很清晰,对自己的追求毫不动摇,讲义气有骨气,但是她在爱情的沉迷也可能是她的破绽,不过她没有机会去向敌人展露她的破绽了。
白嘉轩,白家当代族长,印象最深的莫过于「嘉轩叔的背挺的太硬太直了」,确实非常令我敬佩,人能挺一时,他是挺了一辈子,黑娃着人打断了他身体的背,但他心灵中的背一直坚挺着。白家历代承袭的精神他没有丢,人常说富不过三代,财富在传承的过程中是最容易失去的,但只要精神的传承不断,这个家族就很难倒下。
朱先生,君子。
鹿兆海,兆海原上发丧回来的时候那种悲恸的氛围使我落泪,且不论他最后死因,他确实抗击了日寇这是没跑的,而且战前给朱先生许诺的东西也带回来了,但是最后冒出个兆海媳妇这有点瓜,说好的终生不娶呢。
白孝文最后吃了黑娃的胜利果实还把黑娃害死了,我觉得黑娃比白孝文值得活,但现实往往比这残酷的多,害。鹿兆鹏直接失踪了,白鹿两家最后就白孝文还算支棱的,但你要说白家传承的精神,白孝文传到了吗,就冲他对黑娃做这事,这人就是扒瞎。
鹿三,鹿三最后有一段被田小娥附身的经历,我认为在这么一部书里出现个这种片段不太可能,所以猜测是鹿三一直有心病,由杀人时的狠决到晚年的心存愧疚,他杀人的时候白族长就说了,要是不怕人可以光明正大的杀,月黑风高杀人夜,说白了还是自己心里怕,心里不敞亮。田小娥所谓附身于他多半就是他一直在想这事的结果,而且附身之后说的事情都是大家知道的事情,也不能证明是真的田小娥,还要修庙这么离谱,只像是鹿三想要弥补,想要给自己的心找补一点可以平复下来的借口。
]]>鸡蛋羹是比较简单易做的食物,但是很多同学做完后却发现和网上大家秀出来的不一样,本篇文章就是教下大家怎样简单做出滑嫩鸡蛋羹。
鸡蛋三个大约 180g,温水 270ml,鸡蛋和水的比例为 1:1.5,盐适量(这个依个人口味而定,我习惯是放 1g 左右)。将鸡蛋打入碗中,加入温水和盐并搅拌均匀,熟练的同学可以直接手打,我是用了一个半自动打蛋器,感觉效果还不错,按几下就搅拌好了,也不用插电,如果用的鸡蛋数量多的话建议还是买个电动的。蛋液搅拌均匀后,用小勺子去除蛋液上的浮沫。
蒸锅中加入适量水烧开后,将盛有蛋液的碗放入,盖一个盘子,盖上锅盖后小火蒸 6 分钟,然后关火焖 5 分钟左右就可以出锅了。
出锅之后直接就可以吃了,你也可以加一些自己喜欢的调味。我通常是将香菜和青椒切碎,然后加醋、酱油、味极鲜和一点香油,将鸡蛋羹划开并倒入调味后享用。
知识点:
webpack
打包导致 css3
动画显示异常今天的项目运行的时候发现 css3
动画不动了,在微信调试器上可以正常显示,到了手机上显示就有问题,开始是以为是微信浏览器的问题,毕竟微信浏览器本来就不是个省油的灯,后来发现原因是在 webpack
打包的问题上,打包后的 css
中缺少了 @keyframes
,导致动画不能正常显示
在 static
中加一个 css
文件,在 index.html
中直接使用 link
标签来访问,简单粗暴
使 webpack
对指定文件不打包,这样可以将受影响的 css
代码单独写在一个文件中来避免造成打包的影响。
修改 vue-loader.conf.js
文件里面的代码
不推荐使用,很显然,改成 true
之后,webpack
不再对 css
资源打包,虽然是解决了问题,但是无疑是下下策
-webkit-box-orient: vertical
样式打包后丢失问题原因:
webpack
打包时autoprefixer
自动移除老式过时的代码
粗暴解决,写成行内样式
将打包OptimizeCSSPlugin
配置添加autoprefixer:{remove: false}
。
取消上次请求的使用场景主要是频繁发起的请求导致数据错乱的问题,去抖也只能有效一点点,如果用户的网络有波动,可能会出现请求返回很慢的情况,也可能会出现第一个请求比第二个请求返回的晚的现象,导致预期数据被覆盖掉了。
解决这个问题大致有三个办法,第一个是比较粗暴的,上个请求未返回时不许发起新的请求,确实有人这么做,理由是用户的网络比较快,不会出现卡住的现象🤔;第二个办法是返回的数据中加一个数据的标识,通过判断这个标识是否为预期标识来决定是否覆盖数据,比如请求的是 type 为 2 的列表,返回的数据中也有一个 type: 2 ,这样就不会将其他 type 的数据错误覆盖了,缺点是需要有后端配合返回一个唯一请求参,不够灵活;第三种就是我们接下来要提到的通过取消上次请求的做法啦,发起新的请求时讲上次的请求取消了,便不必担心它一段时间后会自顾的返回数据对我们造成困扰啦。
axios 中为我们提供了取消上次请求的钩子 CancelToken ,官方提供的例子是这样的
You can cancel a request using a cancel token.
The axios cancel token API is based on the withdrawn cancelable promises proposal.
You can create a cancel token using the CancelToken.source
factory as shown below:
You can also create a cancel token by passing an executor function to the CancelToken
constructor:
Note: you can cancel several requests with the same cancel token. If a cancellation token is already cancelled at the moment of starting an Axios request, then the request is cancelled immediately, without any attempts to make real request.
但是我们平时写 axios 的时候已经是封装过的函数了,这样的使用方法我们并不能直接拿来使用,在项目中的使用方式如下:
因为这样会产生一些取消的请求,在 axios 的拦截器中添加配置,标识这些请求是手动取消的,便于业务逻辑代码处判断
通过在 api 函数上新增一个方法的方式来控制取消的操作,在 api 第一次调用的时候还没有 cancelReq 这个属性,所以方法不会执行,调用执行的时候往 getListApi 上挂了 cancelReq 这个属性,下次再次调用的时候就会执行 getListApi.cancelReq() 方法了,如果上次的请求还在 pending ,那么会将上次的请求取消掉,如果上次的请求已经有结果了,那么不会有变化。
]]>要用表单校验需要 el-form
,el-form-item
一起配合使用, el-form 必须要绑定 model 属性,rules 根据具体需求决定是否绑定;el-form-item
需要绑定 prop
属性,rules
在做具体表单项的校验的时候需要绑定规则
表单校验中最重要的三个属性就是 model
、 prop
和 rules
,prop
相当于设置要校验的值, rules
则为校验函数,只要搞明白动态的表单中的 prop
该如何对应,问题就解决了一大半了。我们都知道在使用 element
的表单校验时要使校验生效必须确保 prop
的值和表单项的绑定值对应,这个的前提是校验函数的作用对象是表单项的绑定值,那么为什么要这样绑定呢, prop
的作用是什么,所以要看下 el-form-item
源码里的实现
可以看到 fieldValue
的获取的前提是父组件绑定了 model
的值并且组件有绑定 prop
的值,以 prop
作为一个路径去 model
中取值。下面的伪代码中写了几种可能的场景,可以参考一下 prop
和 model
的关系。
使用场景大致上有静态的表单和动态的表单两种:静态的表单就是表单数量、规则是固定的;动态表单一般是通过循环或者其他方式动态生成表单
普通表单就像 Element UI
文档上展示的 例子 那样使用,此处不做赘述
此处静态校验方式的介绍可以结合表格场景来讨论,表格场景比普通场景是要复杂一些的,但是大致的逻辑是一致的
先看效果
大致代码如下:
表单动态绑定的数据是 propertyForm
,prop
应当是对应的属性值,表单校验生效的关键就在于 prop
的对应,及值的取用 :prop="`propertyList.${scope.$index}.minLen`"
,校验函数中传入的 val
的值就是 prop
对应的值
动态校验规则一般和生成当前表单项的数据相关,校验规则中使用的 value
值其实就是通过 prop
路径从 model
数据中查询到的值,动态校验的要点就是设置要校验的 prop
。此处的业务场景是:表单项是动态生成的,每个表单项有自己的校验规则,最小字符长度和最大字符长度,使用渲染当前表单项的数据做校验 value
,通过获取 value
中的数据来进行校验
先看效果
大致代码如下:
此处绑定的校验值是 :prop="`list.${index}`"
,然后校验函数中就可以根据动态的值来进行校验
import { Message } from 'element-ui'
Vue.component(Message)
Vue.prototype.$message = Message
问题描述:
在flex容器下面的一个flex:1
的子容器里面写了个el-table
用来展示列表数据,在做宽度自适应测试的时候发现该组件的宽度只会增加不会缩小。
问题原因:
通过控制台发现组件生成的table
的宽度是动态计算的,翻查源码,发现以下代码段
也就是说,组件的resize
事件是绑定在this.$el
上了,这应该就是的原因所在了。flex容器下的width:100%
会一直向上继承,直到flex容器下第一级子元素,但是当某个子元素的宽度出现固定值并且大于flex伸展的宽度的时候,那么容器就不会收缩,自然也就触发不了resize
事件了。
可以将设置了flex
属性的容器设置position:relative
,然后在子元素加多一层div包裹内容,设置position:absolute; width:100%;
继承父级宽度,那么内容也会继承该div的宽度了。
ElementUI el-table 在flex下的宽度自适应问题
el-tooltip
不能按预期显示问题描述
hover 时未显示
问题原因
通过开发者工具的元素选择器选择时发现不能直接选取到该元素, 另一元素盖在该元素上方
给触发元素设置 position: relative; z-index: 2;
,使其支棱出来😅
总之用来做没什么变化的竖向滚动容器还可,稍复杂需求就不建议用了,比原生滚动条的优势就是鼠标hover的时候才显示滚动条。至于滚动条样式,原生滚动条样式也是可以修改的,所以也就那样。
]]>做报表的需求遇到,一些表体内容或者表头内容比较长引起折行,折行之后表格整体所需高度增加,好多内容可能就折行了一两个字,不是很美观。做普通表格的话,预留一下数据大体需要的宽度就可以了,但是自定义报表的话你不知道这里将会是什么样的数据,预留太多可能宽了,预留太少可能窄了。要解决这个问题很自然的我们想到,只要知道这一列最宽的那位,将它设置为列宽不就完了🤔,好的现在问题变成了获取本列最长的选手。参赛的选手主要有:
简单点来实现就是算下折合字符数, 字符数 * 字号 + padding + 容错量
,基本能保证 98% 的满足需求,剩下 2% 的话,因为列宽可拖动,可以自己手动调节一下,但是这样计算问题蛮多的,一是字符数计算出来的不准,字符的种类太多,不同的字符的显示大小是有区别的,数目计算不准的话误差特别大;二是css样式对宽度有影响;三是直接加容错量可能会导致过宽。
通过 DOM 配合内容所处环境相同的样式可以测到准确的宽度,最后得到的最大宽就不会有过多冗余了
分成两个函数,计算最大宽度的函数是通用公共函数,因为有两个页面的表格都需要计算,所以再封装一个 handleGetTableColumnMaxWidth
便于业务逻辑处直接调用,DOM计算受 css 影响比较多,具体使用还是根据具体业务改进参数配置
因为有做一个单元格内容不换行的需求,所以排序的时候可能会引起表头的重渲染,重渲染会导致排序样式的丢失,使用自己写排序的方式来修
table 的 column 是循环出来的,列表没有重渲染的时候发现表头的数据已变化但页面上并没有变化。通过给 column 加 key 值,确保数据变化的时候一定会重渲染
]]>安装 webpack 和 webpack-cli
用来指定打包的入口,分为多入口和单入口,单入口是一个字符串值,多入口是一个 对象,里面的键值对对应着多个入口
用来指定打包的输出,只有一个 output ,单入口的时候可以写死 filename ,多入口哦的时候一般利用占位符的概念,name 是名称
webpack 开箱即用支持 js 和 json 两种文件类型,通过 Loaders 去支持其他文件类型并且把他们转化成有效的模块,并且可以添加到依赖图中。它本身是一个函数,接受源文件作为参数,返回转换的结果。不支持的文件类型通过 Loaders 解析。
常用 Loaders :
名称 | 描述 |
---|---|
babel-loader | 转换ES6、ES7等 js 新特性语法 |
css-loader | 支持.css文件的加载和解析 |
less-loader | 将 less 文件转换成css |
ts-loader | 将 ts 转换成 js |
file-loader | 进行图片、字体等的打包 |
raw-loader | 将文件以字符串的形式导入 |
thread-loader | 多进程打包 js 和 css |
增强 webpack 的功能,用于打包优化、资源管理和环境变量注入,作用于整个构建过程,常用插件:
名称 | 描述 |
---|---|
CommonsChunkPlugin | 将 chunks 相同的模块代码提取成公共 js |
CleanWebpackPlugin | 清理构建目录 |
ExtractTextWebpackPlugin | 将 css 从 bundle 文件里提取成独立的 css 文件 |
CopyWebpackPlugin | 将文件或者文件夹拷贝到构建的输出目录 |
HtmlWebpackPlugin | 创建 html 文件区承载输出的 bundle |
UglifyjsWebpackPlugin | 压缩 js |
ZipWebpackPlugin | 将打包出的资源生辰一个 zip 包 |
mode 用来指定当前的构建环境,有三个值: production、development 和 none ,设置 mode 可以自动启动 webpack 对应的一些功能,默认是 production
选项 | 描述 |
---|---|
development | 设置 process.enc.NODE_ENV 的值为 development,开启 NamedChunksPlugin 和 NameModulesPlugin 等 |
production | 设置 process.enc.NODE_ENV 的值为 production,开启 FlagDependencyUsagePlugin ,FlagIncludedChunksPlugin,ModuleConcatenationPlugin,NoEmitOnErrorsPlugin,OccurrenceOrderPlugin, SideEffectsFlagPlugin 和 TerserPlugin 等 |
none | 不开启任何优化选项 |
webpack-dev-server
WDS
不刷新浏览器WDS
不输出文件,而是放在内存中HotModuleReplacementPlugin
插件来使浏览器刷新--open
参数作用,自动开启浏览器webpack-dev-middleware
webpack
配置的更多Webpack Compile
:将 JS
编译成 bundle.js
(打包好输出的文件)HMR Server
:将热更新的文件输出给 HMR RuntimeBundle Server
:提供文件在浏览器的访问。即使用 localhost + port
的方式打开HMR Runtime
:会被注入到浏览器的 bundle.js
里面,浏览器的 bundle.js
就可以和服务器建立连接,通常是一个 ws
连接,当收到文件更新的数据回包之后。就可以自动更新文件的变化bundle.js
:构建输出的文件通常用于版本的管理,在版本发布的时候,通常我们只需要修改更改的文件的文件指纹,没有更改的文件是不用修改文件指纹的,而且文件指纹没有修改的话浏览器也可以使用本地的缓存,可以加速页面的访问
Hash
: 和整个项目的构建相关,只要项目文件有修改,整个项目构建的 hash 值就会更改Chunkhash
:和 webpack
打包的 chunk
有关,不同的 entry
会生成不同的 chunkhash
值Contenthash
:根据问价那内容来定义 hash
,文件内容不变,则 contenthash
不变思考:为什么 js
没有 contenthash
?(主要是要理解 contenthash
的作用)
有一个 Tab 栏,处在页面中间的位置,当滚动过这个位置之后,Tab 栏悬浮在视口上,当滚动经过一个个的模块的时候,对应模块的 Tab 项要高亮显示。
模块是动态加载的,也就是说模块不一定存在(就是这一问题比较麻烦,要加判断,增加了代码量)
东西比较简单,我就不赘述了,看代码就能明白。
主体代码
因为元素滚到锚点处的时候导航栏和悬浮 Tab 会覆盖到要显示的元素,所以在元素上面加一个不显示但是存在的元素,将 id 加在这个元素上面,设置负的 top 值来实现需求
用到的工具方法,用这个方法可以更加准确的获取元素到文档顶部的距离
使用 Vue.filter('filterName', fn)
注册全局过滤器,一般写在 main.js 里,项目中常见写法如下
在一个组件的选项中定义
ts + vue-property-decorator 的写法
使用管道符号 |
作为参数和过滤器名字的分隔,可以链式调用,可以传入更多参数。可以在 v-bind
和插值中使用,链式调用时上个函数的返回值会作为下个函数的入参,传入多个参数时,管道符号前面的是第一个参数,过滤器函数括号中传入剩余参数
const filterFn = Vue.filter('filterFn')
const filterFn = this.$options.filters('filterFn')
在 filters 中是无法访问 this 的,这点要注意,尤雨溪也提到过这个问题,因为过滤器被认为是纯函数,它不应当能访问上下文,如果你要使用 this ,你可以使用一个计算属性或者一个 methods 方法。详见 https://github.com/vuejs/vue/issues/5998#issuecomment-311965292 ,可以通过传参的方式来破解,将需要的属性传入进去使用即可。
顺带着谈谈 computed、 methods 和 filters 的使用场景,这三个都是函数的用法,你可以传入值,然后获取返回值
计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算。注意,如果某个依赖 (比如非响应式 property) 在该实例范畴之外,则计算属性是不会被更新的。methods 每次调用都会执行。filter 在每次模板编译的时候执行。在编码中依据实际情况选择适合的使用即可。
一般 filter 我会用来进行比较多的数据的转换,而且这种数据转换和页面的响应数据关系不大的,比如说我们常有处理表格数据的需求,给某列统一加上百分千分符之类的,用过滤器来做就很方便,而且这是全局通用的逻辑,需要更改的话只改源处。计算属性用在单个值上比较划算,比如要从数组中过滤出一个特殊数组,用计算属性缓存这个特殊数组的值,只要源数据不变,这个值一直有缓存无需重新计算。如果是当前页面的独有的计算,和页面的响应式属性关联比较多的计算,并且不需要链式调用(这一般还真是用不太到),选择使用 methods 来处理。
待续。。。
]]>通过 npm 安装 npm install vue-i18n
,更多安装方式请查看 Vue I18n文档-安装
main.js
代码
tool.js
代码
多语言文件示例
使用起来很简单,
当我们在组件的 props 的 default 中初始化值的时候,需要采取这种写法
但是我们知道有些场景下我们会遇到这样的语句:非常感谢nickName购买了我们的产品
,显然这句话中有一个变量,而由于不同语言的语法不一样,我们并不能直接生硬的翻译变量前后的两句,这时候就要用上格式化了。我们只需要在我们的配置文件中写
使用的时候
避免了我们去拼接变量可能带来的麻烦
之前开发过一段时间的安卓,安卓中也有多语言相关的配置,基本都是采用类似的方式做的多语言,但是安卓开发的编辑器 Android Studio 却有一个很强大且实用的功能,你写在文件中的多语言它会自动帮你替换为文字,当你点击这个文字的时候才会显示源码,这样是非常有助于我们的开发的,因为多语言的配置命名过长会影响代码浏览,命名过短又无法见名知意,这样我们便不用太过纠结命名(当然尽量简短的做到见名知意还是很有必要的)。
VS Code 作为一款受广大开发者欢迎的编辑器,自然已经有人开发出了类似的插件,经过对插件的调查研究(翻阅其GitHub文档,(`・ω・´)),选择了这款插件 Vue i18n Ally ,虽然没有 AS 那么到位,但基本上可以满足我的需求,下面贴一下预览效果
还支持跳转到定义处
好啦,这就是所有的介绍了,以上是工作的基础,如果想要学习更多更洋气的技能可以去它的文档仔细阅读
]]>服务器系统: Centos,服务器软件: Nginx
]]>服务器系统: Centos,服务器软件: Nginx
当我们把 Nginx 安装完成的时候,Nginx 目录下有个 html 文件夹,里面存放着的便是我们的 web 文件,访问 Nginx 的 ip 地址看到的便是这个文件渲染的页面,通常以 index.html 为入口文件,若要以 index.php 作入口文件,需要做相应的配置实现。
好,现在我们知道了,Nginx 加载的页面放在 html 中,并且以 index.html 为入口,想想平时我们的项目打包之后,(一般来讲)会在 dist 目录下生成一个 index.html 和 static 文件夹,打包结束时命令行也会提示,打包出来的文件需要运行在 http server 上,以文件的形式打开不会运行。
我使用的连接服务器的工具是 MobaXterm ,是一个免费的服务器连接工具,参考文章 MobaXterm使用教程 ,个人感觉比 Xshell 用起来要简单一些,好多地方都很图形化的样子,还自带了 sftp 功能,便于上传和下载服务器上的文件,将 dist 目录下的文件上传到 Nginx 下的 html 目录下,运行命令就可以在 ip 访问的时候看到新的页面啦。
#
页面路径后面缀着一个 #
看起来不太美观,那么有办法去掉它吗,当然是可以的,首先我们要在 Vue 项目的 router 的配置中,将 mode 改为 history 。然后修改 Nginx 的配置即可。
项目里用的 UI 库是 Element UI
。一个列表页从 UI 表现来看上至下通常包含这么几部分:筛选栏,列表,分页。在 vue
单文件组件中看的话,主要是模板区和 js
区,项目里列表页一般是统一风格,所以公共样式不会写在列表组件里。首先模板部分我认为是不需要提取出来的,一方面是因为用了 element
表格组件,二次封装会使传值等变的更为复杂,另一方面是封装过后在可读性上有很大的损失
由于只提取了公共的逻辑,模板部分未有提取,而且每个列表页调用的 api
也不同,选择采用 mixin
的方式,在 mixin
中定义公共的数据变量以及方法,在对应的业务单文件组件中引入。mixin
的特性可以在 官方文档 中了解,通过这种方式优点是可以提取公共逻辑,并且可以在混入的地方通过新声明覆盖旧声明的方式重写;缺点是通过 mixin
引入的内容在业务页面是没法直接看到的,这也是使用 mixin
的主要问题。在项目的协作开发,我们采用约定开发的方式,使用者要了解页面所使用的 mixin
,这样可以降低使用 mixin
导致出问题的几率
上述示例是稍复杂的应用,若只是展示列表,只需重置 data
中的数据即可
通过这样的方式,将同类业务中相同的逻辑抽离出来,列表页面的逻辑被简化,后续的业务迭代中只需很少的代码即可实现需求,公共的逻辑在 mixin
中统一维护,提高开发效率
~~目前主题使用的是 vuepress-theme-hope ,~~主题现在是在 vuepress2 默认主题基础上改来的。
因为本身支持一些 vue 的语法,所以在代码中写 vue 的语法时要用 特殊的写法 ,用的话需要这样写😂
因为是自用脚本,所以没做异常检测啥的,白费时间,现在的作用是在编译前生成侧边栏,然后进行编译或打包,对热更新也无影响,缺点就是后续的编译过程 console 的代码没有高亮了。有同样需求的伙伴可以参考下:
有时会发现部署之后页面刷新后还是旧的,只有强刷才会是新的,但是再次普刷之后又是旧的了,这主要是因为 这个原因 ,要么把已打开的 clients 都关闭,要么就点击页面上的 ** 此内容有更新 ** 的按钮主动刷新页面,之后就可以了
]]>前后端在开发前一般会约定一个接口文档,这个文档上主要是后端会提供的接口,每个接口的介绍大致包括:请求参(字段名,类型,是否必填,描述),接口路径,请求类型,返回参(字段名,类型,描述)。示例如下:
登录接口示例
请求参数说明:
字段名 类型 是否必填 描述 userName String 是 用户名 password String 是 密码 成功的返回JSON数据:
响应参数说明:
字段名 类型 描述 expiresIn Long 有效时间 userToken String 令牌
前端可以依照文档中的字段名进行逻辑的编写,这样在联调接口的时候可以减少因为双方的字段名不符引起的小错误地发生,注意接口文档不是一定要开始就写到完美,在开发的过程中可能会因为需求的变动或者理解的偏差进行修改,但是也应当以精简准确为原则,不要带太多多余的参数。文档修改的时候要通知到相关人员,在项目迭代的时候字段的删减要格外注意。
在前端 Vue 项目中现在主要是采用 axios 进行 http 请求(在以前的 Vue 版本使用的是 vue-resource ,不过现在已经不再维护了),为了方便项目中的使用,在 utils 文件夹中的 request.js 文件中对于引入的 axios 进行了封装,配置了请求数据和返回数据的拦截器,以及基础的前缀和超时时间的配置。
根据接口的前缀,以上述的登录接口为例,在 api 文件夹中新建 user.js (命名是为了查找方便,并不是硬性规定),如下编写
在 vue 文件中,先用 import 引入,然后通过链式调用即可实现调用,如下编写
前端的配置中,在 request.js 文件中设置了前端请求的接口的默认前缀都是 /api ,它的作用是什么呢,答案是便于请求的代理,请求的代理是开发工具为我们提供的解决跨域问题的方案,在 vue.config.js 的配置中
检查网络状态;后台服务状态;如果使用的是内网 ip ,是否同一局域网
404 一般是调通了,但是服务端没有这个接口,所以检查接口路径是否正确,大小写。
函数、文件、字段等的命名尽量见名知意
]]>我们知道阅读文档是一件比较枯燥的事情,但是在这里还是建议你阅读相关文档,阅读文档可以让你知道基础知识,你不必急着把它们都记住,有个初步的了解有助于你在后面的代码实践中事半功倍。W3school 上的 web 相关知识比较完备,也提供在线编程完成例子,慕课网上的入门基础是类似闯关的模式,可能会让你更有兴趣。在阅读相关文档的时候,尽量多动手实践
HTML5 和 CSS3 现在主流浏览器基本上都支持了,对这块的了解是很有必要的。
Vue
的官方文档就是对它介绍的最好最完备的,各种语法包括一些基本的原理在里面都能找到,也有完整的实例帮助你快速上手 Vue
Vue 官方文档
学有余力的同学可以关注一下:
对于 JavaScript 来说,ES6 语法也是需要了解的,我们现在在 Vue
或者 微信小程序中一般都是采用 ES6 语法进行编写 JS ,ES6 可以让你的 JavaScript 代码写起来更便利,在这里给大家推荐的是深入理解 ES6 这本书
node v10.13.0 去 官网 下载并安装;
编辑器: 推荐 VS Code
工欲善其事,必先利其器
以下插件直接在 VS Code 插件市场中搜索安装即可
以下介绍的 Vue 相关的知识在官方文档上都能找到更详细的介绍 Vue 官方文档
这块相当于 HTML ,所使用的标签也基本上都是 HTML 标签
模版语法简介:插值,方法,循环,显示控制,使用过滤器,指令,事件
vue 的生命周期:
定义变量,函数,路由
CSS 与 Less ,为什么使用 Less ,Less 的语法,变量。组件样式使用 scope 解决命名空间
Vue 的是一个数据驱动的框架,数据的改变引起视图的变化。下面使用的 UI 框架是 ElementUI ,更多的使用方式请查看他的 ElementUI 组件文档
我们为什么要使用组件? 灵活,方便
组件传值分为父子组件传值和非父子组件传值,前者使用 props 即可解决,后者则需要借助 Vuex 这个全局的状态管理来进行
怎样快速使用 ElementUI 的表单相关组件,表单中的数据绑定,要注意的事情,表单提交
怎样快速使用 ElementUI 的表格相关组件,使用表格配合分页来展示列表数据,数据的获取
通过以上两个实例展示前端如何通过调取接口拿到后端服务的返回数据,返回数据格式示例:
运行命令 npm run build
执行打包,打包后的文件输出在根目录下的 dist 文件夹中
由于是单页面应用,和传统的多页面应用是不同的,所以 nginx 配置中要注意:
Vue 的文档是非常完善的,你在 Vue 开发中遇到的百分之八十的问题都可以在文档中找到答案
]]>cssinspirationguide - csc inspiration guide online
JavaScript - 30 seconds of code
mqyqingfeng/Blog: 冴羽写博客的地方,预计写四个系列:JavaScript深入系列、JavaScript专题系列、ES6系列、React系列。
['1', '2', '3'].map(parseInt)
what & why ?
在 木易杨前端进阶 看到的一道题,比较有意思,做个记录
]]>['1', '2', '3'].map(parseInt)
what & why ?
在 木易杨前端进阶 看到的一道题,比较有意思,做个记录
map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。
展开
前往 官网下载页面 下载最新的稳定版
然后就是选择适合自己的版本,在白框上右键选择复制链接地址即可
先确认你nodejs的路径,我这里的路径为 /service/node-v10.15.3/bin
。确认后依次执行,建立软链接
输出版本号,安装成功
pm2
报错 command not found
,猜测是因为 node 的安装目录是自定义的原因导致
在 package.json 中新增命令 "pm2": "pm2 start ./bin/www"
执行命令运行:
在这之前先来说一个编程中常见的现象,在代码中出现但没有解释的数字常量或字符串,这种数字我们也叫它“魔数”。比如我们在开发功能的时候,有个地方要判断类型,类型有两种1是平台2是个人,然后代码里就比较多的 type === 1
或 type === 2
,写的时候或许还能记得它们的含义,但是过段时间再看代码,或者同事来看你的代码,如果你能在定义 type 的地方写个注释标记它的可能取值及其意思,这都还算好的了,如果连注释也没有,这俩数字就没有语义了,不知道1和2代表啥意思,在去翻文档查语义理解起来就特别费劲。然后这时候因为你要做一点改动,平台的判断码改成 3 了,难受不。
而 1 和 2 是什么?是常量。我们可以将这两个常量命名后使用,比如在代码里定义一个 const PLATFORM = 1; const PERSION = 2;
,在用到 1 和 2 的地方,都以常量名字 PLATFORM
和 PERSION
来代替,这样你点击查找定义的时候也比较方便。如果这个变量在一个文件中用了,那么将其定义在文件逻辑代码的开头,如果是在多个文件中使用了,找一个共同的上级文件位置去存放或者直接放到全局常量文件中
语义理解优 ,如果你命名的OK的话,起码常量能起到一个见名知意的作用,这对于我们代码的语义化是很重要的,与之相对的,如果你命名有问题,那可能就直接误导了别人,通常情况来说的话,用个翻译软件就能解决你大多数的问题了。
易于管理 ,你的相同变量成体系的在一处存储,如果有类型值的变动可以方便清晰的改动,而不必去文件夹下检索所有后一一替换
待续
]]>]]>lang 全局属性 参与了元素语言的定义。这个语言是不可编辑元素写入的语言,或者可编辑元素应该写入的语言。标签包含单个条目,值的格式由 用于定义语言的标签 (BCP47) IETF 文档定义。如果标签的内容是空字符串,语言就设为未知。如果标签内容是无效的,根据 BCP47,它就设为无效。
lang 全局属性 参与了元素语言的定义。这个语言是不可编辑元素写入的语言,或者可编辑元素应该写入的语言。标签包含单个条目,值的格式由 用于定义语言的标签 (BCP47) IETF 文档定义。如果标签的内容是空字符串,语言就设为未知。如果标签内容是无效的,根据 BCP47,它就设为无效。
我们见到这个标签比较多一般是在 html 标签上,当我们在编辑器里输入 !
后按 Tab 默认生成的 html5 基础文档中的 html 就有默认的lang 属性,作用是标记当前页面的语言属性,当 lang 的值和浏览器的默认语言不同的时候就会弹需要翻译的提示(这个设置是可以在设置里关闭的),如果不想有翻译提示弹出,可以去掉这个属性或者设置为 zh-CN
。
微信提供的流程图十分详细
基本就是官方提供的 demo ,封装一个 wxjsBridge.js
调用时传入需要的参数和回调函数即可
调用时
签名无效的原因 99% 是因为参数的原因,要么是不符合要求,要么是配置有误导致签名错误,不是说正确生成了签名就一定是有效的签名,可能其中某个参数错误,导致签名算法正确却报 Unable to verify signature
例如 Window 对象,来自浏览器环境,window 上的属性一部分来自 JavaScript 语言,一部分来自浏览器环境。 JavaScript 标准中规定了全局对象属性, W3C 的各种标准中规定过了 window 对象的其他属性。宿主对象也可以分为固有的和用户创建的两种,比如 document.createElement 就可以创建一些 DOM 对象。宿主也会提供一些构造器,比如我们可以使用 new Image 来创建 img 元素。
固有对象在 JavaScript 代码执行前就被创建出来了,他们通常扮演着类似基础库的角色
通过语言内置的构造器创建的对象
]]>宿主发起的任务是宏任务, JavaScript 引擎发起的任务是微观任务,许多的微观任务的队列组成了宏观任务。JavaScript 引擎会等待宿主环境分配宏观任务,在操作系统中,通常等待的行为都是一个事件循环,所以在 Node 术语中,也会把这个部分称为事件循环。有了宏观任务和微观任务机制,我们就可以实现 JavaScript 引擎级和宿主级的任务了,例如: Promise 永远在队列尾部添加微观任务,setTimeout 等宿主 API 则会添加宏观任务。
Promise 是 JavaScript 语言提供的一种标准化的异步管理方式,它的总体思想是,需要进行io、等待或者其他异步操作呃函数,不返回真是结果,而返回一个"承诺",函数的调用方可以在合适的时机,选择等待这个承诺兑现。
Promise 的语法糖,async 函数是一种特殊的语法,特征是在 function 关键字之前加上 async 关键字,这样就定义了一个 async 函数,我们可以在其中使用 await 来等待一个 Promise
我们现在要实现一个红绿灯,把一个圆形 div 按照绿色 3 秒,黄色 1 秒,红色 2 秒循环改变背景色
轮播图的点的样式相关类名如下所示,稍作修改便可实现一些设计上的简单的效果了
wx-swiper-dots
wx-swiper-dots-horizontal
wx-swiper-dot
wx-swiper-dot-active
小程序的wxss文件font-face的url不接受http地址作为参数,可以接受base64,因此可以先将字体文件下载后,转换为base64,然后引用。字体转换网站
]]>轮播图的点的样式相关类名如下所示,稍作修改便可实现一些设计上的简单的效果了
wx-swiper-dots
wx-swiper-dots-horizontal
wx-swiper-dot
wx-swiper-dot-active
小程序的wxss文件font-face的url不接受http地址作为参数,可以接受base64,因此可以先将字体文件下载后,转换为base64,然后引用。字体转换网站
此处的字体文件就是从 iconfont 下载到本地的文件中的 TTF 类型的文件
转换完成后会出现下载按钮
选择下载文件包中的 stylesheet.css 文件,重命名为 font.wxss ,在 iconfont.wxss 中删掉 @font-face
,添加 @import "font.wxss";
即可
使用
安装插件 Easy Less
,这个插件的作用是自动将你写的 less 编译成 css ,但是我们需要的是 wxss ,在项目目录下新增一个文件夹 .vscode ,新建文件 settings.json ,添加配置:
小程序的 onLaunch 和页面级的 onLoad 异步执行,这两个的执行顺序是不一定的,在 onLaunch 中请求还未返回的时候, onLoad 可能就执行了,需要加判断
为了使用方便,我将这个需求的实现做成了一个组件,便于项目的其他地方复用,也遇到了一些因为使用自定义组件带来的问题
]]>为了使用方便,我将这个需求的实现做成了一个组件,便于项目的其他地方复用,也遇到了一些因为使用自定义组件带来的问题
相关的代码比较长,而且大部分为调用 Canvas 的 api 代码,整体贴出无必要。本文中只描述思路,具体代码看 小程序生成图片的微信代码片段 。
drawRoundedRect
:用来绘制圆角矩形,此处不详述它的画图原理point
:为方法 1 服务的,一看就懂downFile
:对微信的下载方法进行了一层简单封装,传入 url ,返回一个 Promisesave
: 保存图片的相关逻辑doAuth
:当调用 wx.saveImageToPhotosAlbum
方法保存图片时,如果没有保存图片的权限会保存失败,此时需要让用户重新授权computedPercent
:一个快捷的计算比例的方法,传入从设计图上量出来的像素数即可, oldWidth
是设计图上的 Canvas 区域宽度initData
:数据初始化,获取设备相关信息,将网络图下载到本地writeCanvas
: 主要画图逻辑,调用此方法时保证所需数据已处理完毕,开始画图需求中需要显示用户头像和小程序码,小程序码后面是要挂参数的,可以简单理解为要挂个用户参数在后面,类似这样 ?uid=2233
,这就是组件中要传入的 scene 的值,然后根据这个参数,在开始画图之前,先调用接口从服务端那里获取图片的链接,再利用微信的 wx.downloadFile
方法将图片下载到本地,在 Canvas 中使用本地路径,用户头像和小程序码都下载好了之后就可以开始画图了,否则的话,提示网络错误。
为了演示方便,本文中的网络图都换成了本地图片
由于是在组件中,所以获取 Canvas 上下文的时候要传入 this
,根据设计图,从里向外依次往 Canvas 上叠加就是了,从设计图上量出的像素调用方法来获取比例,画完之后调用 Canvas 的 draw
方法技术绘画,并且将 loading 状态取消
保存图片的时候,要注意保存的图片的宽高都乘一下设备的像素比,防止出来的图片太小了,保存图片需要相关权限,若用户为授权,要弹窗让他授权之后再进行保存操作
以下部分问题有时效性,请大家理性看待。
ctx.draw()
方法,不调用的话是什么都不会显示的wx.createCanvasContext(string canvasId, Object this)
,在自定义组件下,当前组件实例的 this
,表示在这个自定义组件下查找拥有 canvas-id
的 <canvas>
,如果省略则不在任何自定义组件内查找。简而言之就是在页面级调用这个方法的时候,第二个参数可以不传,会默认传入 this ;但是在自定义组件中调用这个方法的话,要传入 thisdownloadFile
合法域名对于大部分同学来说,自己项目的需求和我这里实现的可能是有些出入的,所以本文只是起到一个例子的作用,可以帮助你快速上手这个模块的开发
]]>首先给要调用方法的组件的 wxml
元素上添加一个 ID
,然后在 js
中先定义一个变量,onload
的时候给变量赋值组件的实例,这样组件的实例就在当前 page
中都可以用了,调用组件中 methods
中的方法即可
let iptNumberComponent
iptNumberComponent = this.selectComponent('#ipt-quantity')
iptNumberComponent.updated()
首先给要调用方法的组件的 wxml
元素上添加一个 ID
,然后在 js
中先定义一个变量,onload
的时候给变量赋值组件的实例,这样组件的实例就在当前 page
中都可以用了,调用组件中 methods
中的方法即可
onLaunch
和页面级的 onLoad
异步执行,这两个的执行顺序是不一定的,在 onLaunch
中请求还未返回的时候, onLoad
可能就执行了,需要加判断
封装一个全局方法,便于其他页面使用,我们的业务逻辑是只有当用户执行到下单或分享等必须操作时才需要用户登录,用户登录需要先授权个人信息,如果用户授权过个人信息,下次进入的时候就直接登录,登录成功后会赋值 getUserInfoFlag
为 true
。
onLaunch
和页面级的 onLoad
异步执行,这两个的执行顺序是不一定的,在 onLaunch
中请求还未返回的时候, onLoad
可能就执行了,需要加判断
封装一个全局方法,便于其他页面使用,我们的业务逻辑是只有当用户执行到下单或分享等必须操作时才需要用户登录,用户登录需要先授权个人信息,如果用户授权过个人信息,下次进入的时候就直接登录,登录成功后会赋值 getUserInfoFlag
为 true
。
先判断用户是否授权过我们的小程序。若未授权,执行简单操作。如果授权了,app.js
一定会调用登录,判断 getUserInfoFlag
为 true
的话,说明 app.js
的 onLaunch
先于页面级的 onLoad
执行,正常操作即可;若为 false
,说明 页面级的 onLoad
先于 app.js
的 onLaunch
先执行了,此时往 app
上挂载一个 check
函数,函数中执行想要执行的方法,而在 app.js
中则要在登录后判断是否存在 check
函数,进而执行相应的逻辑。
流程图:
具体的还是看代码吧:
在根目录下分别创建
components
用来存放项目需要的组件资源或者自定义的组件
config
新建一个 js 文件用来存放通用域名配置文件
rousources
资源文件目录,存放图片、 iconfont
等资源
service
服务相关目录,用来存放与 api
相关的文件
切换开发环境或者测试环境下,只要更换对应的 url
即可
可以像普通项目封装 axios
一样来对小程序中的请求进行封装,在调用时只调用写好的 api
文件即可
less
安装插件 Easy Less
,这个插件的作用是自动将你写的 less 编译成 css ,但是我们需要的是 wxss ,在项目目录下新增一个文件夹 .vscode ,新建文件 settings.json ,添加配置:
target | currentTarget | |
---|---|---|
定义 | 触发事件的组件的一些属性值集合 | 当前组件的一些属性值集合 |
dataset | 事件源组件上由 data- 开头的自定义属性组成的集合 |
当前组件上由 data- 开头的自定义属性组成的集合 |
target | currentTarget | |
---|---|---|
定义 | 触发事件的组件的一些属性值集合 | 当前组件的一些属性值集合 |
dataset | 事件源组件上由 data- 开头的自定义属性组成的集合 |
当前组件上由 data- 开头的自定义属性组成的集合 |
点击 inner 的时候,两个方法都会执行,点击 outer 的时候,只会执行 handleTap1
总结:
npm
包,但是微信小程序的目录结构显然与我们开发的普通 Vue
项目是不一样的,那么如果我要在微信小程序中使用一个 npm
包的话,我们应该如何操作呢,其实也很简单
]]>npm
包,但是微信小程序的目录结构显然与我们开发的普通 Vue
项目是不一样的,那么如果我要在微信小程序中使用一个 npm
包的话,我们应该如何操作呢,其实也很简单
首先像普通的项目一样,利用 npm
的命令对项目进行初始化,然后安装需要的包,然后点击 工具 --> 构建 npm
就可以啦
点击 工具 --> 构建 npm
,若提示找不到 node_modules
目录,解决办法:
node_modules
文件夹npm
的,执行 npm init
参考文章:
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。
Docker 包括三个基本概念:
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 容器通过 Docker 镜像来创建,容器与镜像的关系类似于面向对象编程中的对象与类,一个镜像可以实例化出多个容器运行。 docker镜像和容器的关系可以参考 这个文章 讲的,比较通俗易懂,一时搞不懂也无妨,在使用过镜像和容器之后兴许会有新的体悟。
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。 一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。 通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure。 |
安装方式网上能找到太多了,我这里只列举我用的,不满足的话再去网上寻找你需要的即可
略
略略
设置阿里云镜像加速器,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了,开了加速之后速度嗷嗷快。
典中典之 Hello World。
Docker 允许你在容器内运行应用程序, 使用 docker run 命令来运行一个容器 并在容器内运行一个应用程序。
各参数解析:
我们通过 docker 的两个参数 -i -t,让 docker 运行的容器实现"对话"的能力
输完命令回车之后你会发现当前命令行的前缀变了,这时我们已经是在容器内部了,可以尝试运行命令 cat /proc/version和ls分别查看当前系统的版本信息和当前目录下的文件列表
可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。
在输出中,我们没有看到期望的 "hello world",而是一串长字符,这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID 来查看对应的容器发生了什么。通过 docker ps
可以查看当前正在运行的容器(docker ps -a
查看所有容器)
列名 | 备注 |
---|---|
CONTAINER | 容器 ID |
IMAGE | 使用的镜像 |
COMMAND | 启动容器时运行的命令 |
CREATED | 容器的创建时间 |
STATUS | 容器状态:created(已创建);restarting(重启中);running 或 Up(运行中);removing(迁移中);paused(暂停);exited(停止);dead(死亡) |
PORTS | 容器的端口信息和使用的连接类型(tcp\udp) |
NAMES | 自动分配的容器名称 |
删除容器时,容器必须是停止状态,否则会报错
当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 Docker Hub 公共镜像源下载
使用 docker images
查看本机已拉取的镜像,各列信息如下
列名 | 说明 |
---|---|
REPOSITORY | 表示镜像的仓库源 |
TAG | 镜像的标签 |
IMAGE ID | 镜像ID |
CREATED | 镜像创建时间 |
SIZE | 镜像大小 |
使用 docker pull 镜像名:版本
如果不加版本默认拉取 latest
使用 docker search 名字
查询可用的镜像
列名 | 说明 |
---|---|
NAME | 镜像仓库源的名称 |
DESCRIPTION | 镜像的描述 |
OFFICIAL | 是否 docker 官方发布 |
STARS | 类似 Github 里面的 star,表示点赞、喜欢的意思 |
AUTOMATED | 自动构建 |
使用 docker rmi 镜像名或镜像ID
删除一个已拉取过的镜像
一般通过以下两种方式对镜像进行更改
以镜像创建容器后进入容器中修改自己想要更改的内容,执行 exit 退出容器,然后 执行 docker commit -m="提交的描述信息" -a="指定的镜像作者" 容器ID 镜像名字(推荐 作者/名字:版本 的命名方式)
来以这个容器创建一个新的镜像
通过创建一个 Dockerfile 文件,并在文件中写入构建指令来从零开始构建一个镜像,执行命令 docker build -t runoob/centos:6.7 .
, -t
指定镜像名字(推荐 作者/名字:版本 的命名方式), .
指定 Dockerfile 文件所在目录,可以指定 Dockerfile 的绝对路径,下文会提到 Dockerfile 文件怎么写,在这里知道有这么个方式就好了。
通过 docker tag 镜像ID 作者/镜像:版本
为镜像创建一个新的标签,打标签的时候最好保持和原镜像的 作者/镜像
相同,因为打完标签后相当于是同一镜像的不同版本,他们的 镜像ID 是相同的。
-P
:容器内部端口随机映射到主机的高端口-p
:容器内部端口随机映射到主机的指定端口,-p 1234:4231
,要注意指的是容器的 4321
端口映射到主机的 1234
端口默认绑定 tcp 端口,如果需要绑定 udp 端口,在端口后加 /udp
即可
通过 -p 127.0.0.1:1234:4321
指定容器绑定的网络地址,这样可以通过主机的 127.0.0.1:1234 访问容器的 4321 端口
使用 docker port 镜像名字 端口
可以方便的查看容器的端口绑定情况
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息,docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。使用 docker network create -d bridge test-net
来创建一个容器网络,-d 指定网络类型,有 bridge、overlay ,其中 overlay 网络类型用于 Swarm mode 暂时不管,test-net 是网络的名称。
在执行 docker run 命令的时候使用 --network test-net 来指定要连接到的网络。例如:
这样运行后在 test1 和 test2 中互 ping 是可以通的,当然前提是已经安装了 ping 。
我们可以在宿主机的 /etc/docker/daemon.json 文件中增加以下内容来设置全部容器的 DNS:
设置后,启动容器的 DNS 会自动配置为 114.114.114.114 和 8.8.8.8 ,配置完,需要重启 docker 才能生效,查看容器的 DNS 是否生效可以使用命令 docker run -it --rm ubuntu cat etc/resolv.conf
,它会输出容器的 DNS 信息。
如果只想在指定的容器设置 DNS,则可以使用命令 docker run -it --rm -h host_ubuntu --dns=114.114.114.114 --dns-search=test.com ubuntu
。参数说明:
参数 | 说明 |
---|---|
--rm | 容器退出时自动清理容器内部的文件系统 |
-h HOSTNAME 或者 --hostname=HOSTNAME | 设定容器的主机名,它会被写到容器内的 /etc/hostname 和 /etc/hosts |
--dns=IP_ADDRESS | 添加 DNS 服务器到容器的 /etc/resolv.conf 中,让容器用这个服务器来解析所有不在 /etc/hosts 中的主机名 |
--dns-search=DOMAIN | 设定容器的搜索域,当设定搜索域为 .example.com 时,在搜索一个名为 host 的主机时,DNS 不仅搜索 host,还会搜索 host.example.com |
如果在容器启动时没有指定 --dns 和 --dns-search,Docker 会默认用宿主主机上的 /etc/resolv.conf 来配置容器的 DNS
仓库(Repository)是集中存放镜像的地方。以下介绍一下 Docker Hub。当然不止 docker hub,只是远程的服务商不一样,操作都是一样。Docker Hub 是目前 Docker 官方维护的一个公共仓库,我们的大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。在 https://hub.docker.com 免费注册一个 Docker 账号。我们使用 Docker Hub 上的公开镜像是不需要登录的,像上文从 Docker Hub 拉取镜像时也未曾要求我们登录,注册登录是便于管理我们自己的镜像仓库。
How to know if docker is already logged in to a docker registry server
docker login actually isn't creating any sort of persistent session, it is only storing the user's credentials on disk so that when authentication is required it can read them to login
需要注意的是,docker login 并没有创建一个持久的对话,它只是将你的信息存储在硬盘上,以便需要的时候读取进行验证,如果你之前登录过的话,那么再次登录就会提示 Authenticating with existing credentials
。然后在登出的时候看输出也可以知道,此时你的身份信息已经移除了
用户登录后就可以推送自己的镜像到 Docker Hub ,命令示例:
以下涉及到的命令都是在 root 用户下的,如果你不是 root 用户,可能需要在命令前面加 sudo
安装必要工具 yum-utils ,它的功能是管理 repository 及扩展包的工具(主要是针对 repository)
使用yum-builddep为Python3构建环境,安装缺失的软件依赖,使用下面的命令会自动处理
完成后下载 Python3 的源码包(笔者以 Python 3.7.4 为例),Python 版本目录:https://www.python.org/downloads/ ,截至发博当日 Python3 的最新版本为 3.7.4 ,
选择适合的版本,点击 Download ,进入下载文件页面
按照图片上的步骤,复制第一项的下载链接,要下载的文件会是一个 tgz 格式的。
最后一步,编译安装 Python3 ,默认的安装目录是 /usr/local
如果你要改成其他目录可以在编译( make )前使用 configure
命令后面追加参数 –prefix=/alternative/path
来完成修改。逐步执行以下命令:
至此你已经在你的 CentOS 系统中成功安装了 python3 、pip3 、setuptools ,查看 python 版本 python3 -V
如果你要使用 Python3 作为 Python 的默认版本,你需要修改一下 bashrc 文件,增加一行 alias 参数,当然如果你使用的安装目录是自定义的,这里的路径也要对应的改成你的自定义路径。
由于 CentOS 7 建议不要动 /etc/bashrc
文件,而是把用户自定义的配置放入 /etc/profile.d/
目录中,具体方法为:
输入 alias 参数 alias python='/usr/local/bin/python3.5'
,保存退出
如果非 root 用户创建的文件需要注意设置权限
重启会话使配置生效
若未设置 Python 3 为默认版本的话,在使用 Python 或者 pip 命令的时候,都要带上 3 执行,像这样: python3 和 pip3
Jenkins 需要 Java 环境,所以先要安装一个 Java JDK
直接去 官网 下载一个对应自己系统的 JDK 即可
我使用的是 Centos7 64 位的系统,所以下载的是对应 Linux x64 版本的 tar.gz 文件
这里要注意一件事,由于在网页上下载的时候是要同意一个协议才能下载的,如果同意了协议之后使用 wget + 下载链接下载文件,文件可以下载成功,但是这种下载默认是不同意协议的,所以在解压的时候可能会出现解压不了的问题,稳妥起见还是将文件下载到本地然后再 ftp 上传到服务器上,解压后重命名为 javajdk
完成之后按 Esc 键,然后输入 :wq
保存并退出
输入 source /etc/profile
使配置文件立即生效
还没有删除过,所以以下方法不确定是否有效
首先执行命令查看服务器下的jdk的版本:命令如下:rpm -qa|grep jdk
然后执行命令: yum -y remove java java-1.6.0-openjdk-1.6.0.0-1.50.1.11.5.el6_3.x86_64
将上面查询出来的每个版本以此删掉即可
最简单的方式: Jenkins 的 Web application ARchive (WAR) 版本的文件可以安装在任何支持 Java 的操作系统平台上。
下载并运行 Jenkins 的 WAR 版本的文件:
下载 最新稳定版本的 Jenkins WAR 文件 到合适的目录中。
在下载目录中打开终端或命令行窗口。
运行命令 java -jar jenkins.war
。
通过浏览器访问 http://localhost:8080
,等到出现 Unlock Jenkins 页面。
运行之后访问地址就可以看到 Jenkins 的新手入门步骤了,按步骤操作即可,这里遇到一个坑就是中间要下载插件,但是它请求的一个文件由于网速原因需要很长的加载时间,导致还没加载完就因为超时被取消,会提示 无法连接到 Jenkins ,我把访问的文件内容拷贝下来,存在本地,然后使用代理将访问的请求转到我本地的文件就 ok 了
现在虽然可以使用 ip 和端口访问了,但是每次输入还是很麻烦,我们可以用域名通过代理来访问它,我的服务器上一直用的是 nginx ,所以就加了一个配置来进行代理,配置也很简单:
要实现的是,一个 GitHub 的项目,当 master
分支上有 push
操作的时候,项目自动构建并部署
新建一个任务,选择自由风格
进入配置页面,通用部分没什么可配置的,直接看源码管理块,选择使用 Git
管理,在展开的区域输入 GitHub 仓库的地址,下面添加的用户要有这个项目的权限,输入用户名和密码添加后在下拉框中选择使用,然后选择用来构建的分支
触发器需要安装 Generic Webhook Trigger Plugin
插件(系统管理-插件管理-搜索 Generic Webhook Trigger Plugin
)如果可选插件列表为空,点击高级标签页,替换升级站点的URL为:http://mirror.xmission.com/jenkins/updates/update-center.json
并且点击提交和立即获取。上面安装的触发器功能很多,但普通的项目一般没有复杂的需要,所以只需要在构建触发器这一项中把 Generic Webhook Trigger
勾选上即可
后面再介绍配置 GitHub 上的 Webhook 来配合这里
下方 nvm
看各自需要配置,
构建,选择增加构建步骤中的 执行 Shell ,为了看起来清晰一点我分成了两段 Shell,也可以写在一段 Shell 中。
配置好之后点击保存,然后去到任务页面,点击构建,试下配置是否出错
配置 GitHub 上的 Webhook ,进入项目的 settings ,选择 Webhooks 项,点击 Add webhook ,填写 Payload URL
然后下面可以选择触发事件,这个看个人需求,填好之后点击 Add Webhook ,然后他会自动触发一次来校验是否能跑通,如果报错,可以根据它请求返回的错误信息来进行排查
这样当项目的 master
分支又 push
请求的时候,Jenkins 就会自动构建并部署
前段时间改一个项目的配置的时候, 另一个项目的构建出了问题,总是构建失败,报错如下:
Execute shell
不是错误的名字,这个指的是执行命令行的时候报错了,说白了就是构建配置那里写的有问题,经过来回排查,定位到原因是在打包后,对生成的文件进行压缩的过程报错了。
前端的项目中没有配置打包时先删除 dist 中的内容,导致一次构建失败后 dist 中一直有 tar 的压缩包,无法进行新的压缩包操作,故而报错,所以为了稳妥起见,在执行 npm run build
之前,先清空 dist 目录,当然前端项目中也要改进这一点,打包时自动清空打包目录
Apache
服务器的安装与配置因为之前已经安装过 yum
了,所以直接在线安装,我的服务器系统是 CentOS 7
主配置文件的目录为: /etc/httpd/conf/httpd.conf
先 yum list
看看有没有可安装的包 yum list httpd
有的话就可以以安装 yum install httpd.x86_64
默认端口是 80
端口,可以不修改,根据个人情况决定,我将其改为了 8080
端口,配置文件的目录为
etc/httpd/conf/httpd.conf
用 vi httpd.conf
命令打开文件,按下 i
键就可以开始修改,要注意开始的时候展示的并不是文件的全部,需要按几次回车才能看到修改端口的地方,修改完成后按 Esc
键退出编辑状态,输入命令 :wq
回车退出并保存。
httpd
服务开机启动到 etc/httpd
目录下输入 /sbin/chkconfig httpd on
命令,回车,看到结果:
httpd
服务还是在 httpd
这个目录下,输入 /sbin/service httpd start
命令,看到结果为:
Redirecting to /bin/systemctl start httpd.service
表示启动了 Apache
服务器,访问 ip
验证一下,如果看到了测试页面说明启动成功。注意:如果你修改了你的监听端口号的话,那么在你访问 ip
地址的时候后面应该加上你的端口号,中间用冒号隔开
我的阿里云的服务器,需要配置安全组规则,允许设置的那个端口被外网访问
systemctl start httpd.service
//启动
systemctl restart httpd.service
//停止
systemctl status httpd.service
//查看状态
systemctl restart httpd.service
//重启
systemctl enable httpd.service
//开机启动
httpd
的卸载rpm -qa | grep httpd
或者 yum list | grep httpd
先确认是否有安装过,因为我安装过,所以我的显示是这样的:
下面开始卸载 httpd
,首先要停止 httpd
服务,
systemctl stop httpd.service
然后通过 rpm -e
或者 yum -erase
命令都可以,不过 rpm -e
命名必须要自己先卸载依赖包,所以我用 yum -erase
命令卸载,命令如下:
yum erase httpd.x86_64
MySQL
安装与配置最好对 MySQL
的命令有一定理解能力,不然光看着教程也不知道是咋回事,就数据库用户名和密码那块不理解就很难办,因为要确保用户名和密码还有数据库名字的一致,如果出现不一致的地方,就会出现数据库连接错误。
MySQL
:rpm -qa | grep mysql
如果你的系统有安装,那可以选择进行卸载
rpm -e mysql
普通删除模式
rpm -e --nodeps mysql
强力删除模式,如果使用上面命令删除时,提示有依赖的其他文件,则用该命令可以对其进行强力删除
MySQL
:因为在 CentOS 7
版本, 由于 MySQL
数据库已从默认的程序列表中移除,可以使用 mariadb
代替,安装命令为:
yum install mariadb-server mariadb
mariadb
数据库的相关命令是:
systemctl start mariadb
#启动 MariaDB
systemctl stop mariadb
#停止 MariaDB
systemctl restart mariadb
#重启 MariaDB
systemctl enable mariadb
#设置开机启动MySQL
安装在成功安装 MySQL
后,一些基础表会表初始化,在服务器启动后,可以通过简单的测绘师来验证 MySQL
是否工作正常。使用 mysqladmin
工具来获取服务器状态,该文件位于 /usr/bin
如果命令未输出任何信息,说明你的 MySQL
未安装成功
MySQL
运行 mysql_secure_installation
安全配置向导
它会告诉你由于你是刚安装完所以默认密码是空的,只需要回车即可,然后设置新密码,再次输入新密码
然后问你是否删除匿名用户,生产环境建议删除
Remove anonymous users? [Y/n] y
是否禁止 root
远程登录
Disallow root login remotely? [Y/n] n
是否删除 test
数据库
Remove test database and access to it?[Y/n] y
是够重新加载权限表
Reload privilege tables now? [Y/n] y
mariadb
的字符集查看 /etc/my.cnf
文件内容,其中包含一句 !includedir/etc/my.cnf.d
,说明在该配置文件中引入了 /etc/my.cnf.d
目录下的配置文件
vi server.cnf
命令编辑 server.cnf
文件,如果 /etc/my.cnf.d
目录下无 server.cnf
,文件,则直接在 /etc/my.cnf
文件的 [mysqld]
标签下添加以下内容vi client.cnf
命令编辑 /etc/my.cnf.d/client.cnf
,在 [client]
标签下添加
default-character-set=utf8
vi mysql-clients.cnf
命令编辑 /etc/my.cnf.d/mysql-clients.cnf
文件, 在 [mysql]
标签下添加 default-character-set=utf8
配置完成后 systemctl restart mariadb
重启服务mysql -u root -p
输入 show variables like "%character%";show variables like "%collation%";
查看字符设置MySQL
要注意由于在 CentOS 7
中安装的是 mariadb
。
mariadb
是否安装
rpm -qa | grep mariadb
输出为:卸载 mariadb
根据 httpd
的卸载,我用 yum erase
命令卸载
yum erase mariadb
卸载 mariadb
依赖
在上一步之后再执行
rpm -qa | grep mariadb
结果为:
mariadb-libs-5.5.56-2.el7.x86_64
执行:
yum erase mariadb-libs
再用命令 rpm -qa | grep mariadb
查看,已经没有输出了,卸载完毕
MySQL
密码1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接 MySQL
数据库。
因为在重新设置 MySQL
的 root
密码的期间, MySQL
数据库完全出于没有密码保护的
状态下,其他的用户也可以任意地登录和修改 MySQL
的信息。可以采用将 MySQL
对
外的端口封闭,并且停止 Apache
以及所有的用户进程的方法实现服务器的准安全
状态。最安全的状态是到服务器的 Console
上面操作,并且拔掉网线。
2.修改 MySQL
的登录设置:
# vi /etc/my.cnf
在 [mysqld]
的段中加上一句: skip-grant-tables
保存并且退出。
3.重新启动 mariadb
# systemctl restart mariadb
4.登录并修改 MySQL
的 root
密码
5.将 MySQL
的登录设置修改回来
# vi /etc/my.cnf
将刚才在 [mysqld]
的段中加上的 skip-grant-tables
删除
保存并且退出 vi
6.重新启动 mariadb
# systemctl restart mariadb
MySQL
远程连接允许 root
用户在任何地方进行远程登录,并具有所有库任何操作权限,具体操作如下:
在本机先使用 root
用户登录 mysql
:
mysql -u root -p"youpassword"
进行授权操作:
mysql>GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youpassword' WITH GRANT OPTION;
重载授权表:
FLUSH PRIVILEGES;
退出 mysql
数据库:
exit
PHP
安装命令:
yum install php
在 Apche
的目录下面新建一文件 test.php
cd /var/www/html
vi test.php
可以键入相关 PHP
代码,以输入 hello world
为例,
访问网站 ip:port/test.php
,如果正常解析,则说明 PHP
环境完成。没有修改端口号就不用加端口号了,修改了端口号的话还要改别的配置,所以我又把端口号改回了 80
,访问可看到网页显示 hello world
WordPress
MySQL
创建用户一定要执行 flush privileges;
刷新权限列表后,你新建的用户名和密码才能生效,不然用新建的用户名登录会提示错误
WordPress
创建数据库WordPress
WordPress
之前,有一个 PHP
模块,我们需要安装,以确保它正常工作。没有此模块, WordPress
将无法调整图像大小以创建缩略图。用 yum
来安装
sudo yum install php-gd
Apache
,以便它识别新的模块:
sudo service httpd restart
WordPress
WordPress
目录 tar
:
tar xzvf latest.tar.gz
wordpress
在你的主目录。 我们可以通过将解压缩的文件传输到 Apache
的文档根目录来完成安装,在那里它可以提供给我们网站的访问者。 我们可以有我们的传输文件的 WordPress rsync
,这将保存文件的默认权限
sudo rsync -avP ~/wordpress/ /var/www/html/
PS
:我直接在 /var/www/html/
目录下下下载并解压了,因为第一次文件传输失败了rysnc
将安全的所有的内容从你解压文档根目录的目录复制 /var/www/html/
。 但是,我们仍然需要为 WordPress
添加一个文件夹来存储上传的文件。 我们可以做到这一点用 mkdir
命令:
mkdir /var/www/html/wp-content/uploads
WordPress
文件和文件夹分配正确的所有权和权限。 这将增加安全性,同时仍然允许 WordPress
按预期工作。 要做到这一点,我们将使用 chown
授予所有权 Apache
的用户和组:
sudo chown -R apache:apache /var/www/html/*
Web
服务器将能够创建和修改 WordPress
文件,并且还将允许我们将内容上传到服务器WordPress
使用 WordPress
所需的大多数配置将通过以后的 Web
界面完成。 但是,我们需要从命令行做一些工作,以确保 WordPress
可以连接到我们为其创建的 MySQL
数据库。
WordPress
的 Apache
根目录:
cd /var/www/html
WordPress
的依赖于主配置文件称为 wp-config.php
。 默认情况下,包括大多数匹配我们需要的设置的示例配置文件。 我们需要做的是将其复制到默认配置文件位置,以便 WordPress
可以识别和使用该文件:
cd wordpress
cp wp-config-sample.php wp-config.php
vi wp-config.php
MySQL settings
和更改 DB_NAME
, DB_USER
和 DB_PASSWORD
为了变量 WordPress
的正确连接和认证,我们创建的数据库。
使用您创建的数据库的信息填写这些参数的值。 它应该看起来像这样:这些是您需要更改的唯一值,因此在完成后保存并关闭文件。
Web
界面完成安装输入 ip:port/wordpress
将导航到 WordPress
安装页面,剩下的只需要按照要求来即可
配置完成后输入 url
地址
Your PHP installation appears to be missing the MySQL extension which is required by WordPress.
先是提示 PHP
没有安装 MySQL
扩展,安装扩展:
yum install -y php-mysql
service httpd restart
安装完扩展又出现如下错误:
Error establishing a database connection
多半是和数据库的连接出了问题,检查你的用户名和密码配置的是否正确,此处需要熟悉一下数据库命令的意思
告诫大家,不懂的地方不要瞎改,不然就要解决到弄懂这个东西,尤其是 WordPress
修改设置也没有个确认按钮,很难受,网站说呲就呲了
CentOS 7.5
yum install -y gcc gcc-c++
进入 PHP 官网 点击 Download ,选择一个合适的版本,建议选择个低于 7.2 版本的,高版本的时候安装会报错,本人是感觉玩不转。。。
因为 php 安装需要编译,所以服务器应该保证 gcc 和 g++ 环境的安装,将下载下来的包上传至服务器
接下来进行参数配置,配置前如果没有libxml2和libxml2-devel会报错,所以应该更新libxml2并安装libxml2-devel,使用在线安装:
补充,因为不同的操作系统环境,系统安装开发环境包的完整程度也不相同,所以建议安装操作系统的时候做必要选择,也可以统一执行一遍所有的命令,将没有安装的组件安装好,如果已经安装了可能会进行升级,版本完全一致则不会进行任何操作,命令除上面2个之外,汇总如下:
以上这些包基本上够用了,如果发现问题再补充,安装完成之后,执行配置:
然后设置 php.ini ,使用: vim /usr/local/php/lib/php.ini 打开 php 配置文件找到 cgi.fix_pathinfo 配置项,这一项默认被注释并且值为 1 ,根据官方文档的说明,这里为了当文件不存在时,阻止 Nginx 将请求发送到后端的 PHP-FPM 模块,从而避免恶意脚本注入的攻击,所以此项应该去掉注释并设置为 0
设置完毕保存并退出,创建web用户:
默认情况下etc/php-fpm.d/下有一个名为www.conf.defalut的配置用户的文件,执行下面命令复制一个新文件并且打开:
安装 php 的 mysql 扩展,去 官网 下载,然后上传到服务器上
在php.ini中添加mysql扩展,在php.ini文件的最后添加一行:
Typecho 是一款非常简洁的博客系统,之前也有用过 wordpress ,着实是有点臃肿,对于一个简单的博客来说,我不需要那么多花里胡哨的东西,然后就发现了现在这一款,简单易用
RHEL 7 Linux 64-bit x64
我的安装目录是 /usr/local/envir
仅供参考
MongoDB
数据库 -- Centoswget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.2.tgz
tar -zxvf mongodb-linux-x86_64-rhel70-4.0.2.tgz
mv mongodb-linux-x86_64-rhel70-4.0.2 mongodb
cd mongodb
mkdir data
mkdir logs
cd data
mkdir db
cd ..
RHEL 7 Linux 64-bit x64
我的安装目录是 /usr/local/envir
仅供参考
MongoDB
数据库 -- Centos/usr/local/envir/mongodb/bin
下新建配置保存后,source /etc/profile
重启系统配置
在 /usr/local/envir/mongodb/bin
下
本文中关于创建管理员参考 (MongoDB——权限管理)[https://www.cnblogs.com/sheepswallow/p/4868519.html] 这位的文章
MongoDB
数据库 -- Windows一个数据库服务器上可以存很多数据库,数据库放着表,表的每一行数据都是一条记录。
MongoDB
是非关系型数据库( postgre
也是),灵活、节约存储空间,缺点,
集合就是表,每行的数据叫做文档,文档是一个键值对( BSON
)
MongoDB
数据类型
mongoDB
配置 服务器与客户端
创建c:\data\db
将数据库安装在这个目录下面
配置环境变量 ....\bin
加到 path
中
进入 mogoDB
的 bin
目录中
>mongod --dbpath
c:\data\db
创建一个服务器,数据库存在该目录下
>mongo
启动一个客户端
windows
服务在 data
文件夹下创建一个 log
文件夹,再在 log
文件夹下创建 MongoDB.log
进入 DOS
窗口, 在命令行中进入到 C:\data\db\bin\
目录中,然后再输入如下命令:
mongod.exe --logpath "C:\data\logs\MongoDB.log" --logappend --dbpath "C:\data\db" --directoryperdb --serviceName MongoDB –install
设置完之后可能无法启动服务,手动无法启动: 报错代码 100
在 data\db\
下找打 mongod.lock
文件,把它删除掉,我不知道这是干嘛的,所以我建议弄个文件夹备份起来,然后启动服务,如果依然无法启动,那么再找到 storage.bson
这个文件,也删除或者备份到其他文件夹中,然后再启动服务,基本上就能轻松启动了。
可以通过 dos
命令进行启动或者停止服务:
启动: net start MongoDB
停止: net stop MongoDB
主键,每条数据都有一个唯一的主键,用来作为这条数据的唯一的标识
show dbs
展示数据库服务器中的已有数据库use name
创建切换数据库,如果有这个数据库,会切换过去,若没有新建一个数据库,但是若未在新数据库中添加数据的话,这个新建的数据库不会保存db.createCollection("collName", {size: 20, capped: true, max: 100});
max
要谨慎使用,防止造成数据丢失db.collName.isCapped();
判断聚集集合是否为定容量,返回布尔值db.getCollection("name") db.getCollection("user")
course.user
得到指定名称的聚集集合db.getCollectionNames()
得到当前数据库中的所有聚集集合db.printCollectionStats()
显示当前数据库中所有聚集的状态db.user.find([{name: "zhang"}])
显示当前聚集中的文档集合中的操作 数据库为 course
,course
内有一个聚集为 user
db.user.save({name: "zhang", age: 12})
向集合中新增文档db.user.insert({name: "liu", age: 13})
向集合中新增文档db.user.update({name: "zhang"}, {$set: {age: 22}})
修改db.user.update({name: "zhang"}, {$inc: {age: 2}})
在原先的基础上加 2
db.user.update({name: "zhang"}, {$inc: {age: -2}, $set: {name: "shang"}}, false, true)
啊修改 ,第三个参数是 upsert
,可选,默认为 false
,如果这条数据没找到, upsert
为 true
会插入一条新数据, false
会不插入;第四个参数是 multi
,可选, mongodb
默认是 false
,只更新找到的第一条记录,如果这个参数为 true
,就把按条件查出来多条记录全部更新。db.user.remove({age: 18})
删除聚集集合查询
db.user.find()
查询所有记录db.user.distinct("name")
查询去重后数据db.user.find({age: 22})
查询 age = 22
的数据db.user.find({age: {$gt: 22}})
查询年龄大于 22
的记录db.user.find({age: {$lt: 22}})
小于db.user.find({age: {$gte: 25}})
大于等于db.user.find({age: {$lte: 25}})
小于等于db.user.find({age: {$gt: 23, $lt: 25}})
大于 23
小于 25
db.user.find({name: /mongo/})
name
中含有 mongo
db.user.find({name: /^mongo/})
name
以 mongo
开头db.user.find({name: /mongo$/})
name
以 mongo
结尾$gt
大于 $gte
大于等于 $lt
小于 $lte
小于等于db.user.find({}, {name: 1, age: 1})
查询指定列,1
为显示, -1
为不现实db.user.find({age: {$gt: 25}}, {name: 1, age: 1})
限制条件 age
大于 25
db.user.find().sort({age: 1})
升序db.user.find().sort({age: -1})
降序db.user.find({name: "zhang", age: 22})
查询 name = "zhang", age = 22
的数据db.user.find().limit(5)
查询前 5
条数据db.user.find().skip(10)
查询 10
条以后的数据db.user.find().limit(10).skip(5)
查询在 5-15
之间的数据db.user.find({$or: [{age: 22}, {age: 25}]})
or
查询,或者的意思db.user.findOne()
查询第一条数据db.user.find({age: {$gte: 25}}).count()
查询某个结果集的记录条数db.user.find({sex: {$exists: true}}).count()
按照某列进行排序db.user.save()
和 db.user.insert()
的区别在不插入带有主键数据的文档的时候,他俩的作用都是添加文档到集合中,但是当要新增的文档记录中有主键 _id
时,如果主键已存在, insert
会报错, save
会直接覆盖替换掉
要注意的是宿主机的文件会被挂载到容器内,像 nginx 配置这些就要注意使用的路径,应当是容器内的路径,这块着实给我困扰了一段时间,nginx 配置文件示例:
相关的命令如下
进入到 nginx 容器中,按照 给网站增加ssl证书 安装 acme 脚本,并生成&安装证书。然后将这个运行中的容器打包成镜像,下次就可以使用这个镜像部署了
这几天在弄一个 artalk 的评论系统,这个也是 docker 部署的,然后我不想将端口暴露在外部,只想通过域名及反向代理的方式访问,在配置反向代理的时候,按照以前的思路使用 proxy_pass http://127.0.0.1:8080/;
结果并不能生效。后来想在容器内运行的时候 127.0.0.1 指向的是容器内部的环境,并不是宿主机的,但是 8080 端口已经被占用不能再分配给 nginx 容器。通过 docker network inspect bridge
命令查看 docker 的网关信息,使用网关地址取代 127.0.0.1 即可成功实现反代。
也可能我的理解是错的,毕竟我确实不是很懂这个,如果你发现我的描述有误,希望可以帮助我指正,不胜感激
]]>现在的项目多是前后端分离的项目,所以我们不必在把前端项目放入后端项目,然后起 Apache 或者 Tomcat 运行后端项目,Apache和Nginx的区别 ,简而言之,现在的 web 项目基本上都是跑在 Nginx 上的,虽然项目部署这类事情不用我们操心,但多了解一点总是没错的。
安装就不赘述了,之前的文章也有提到
]]>现在的项目多是前后端分离的项目,所以我们不必在把前端项目放入后端项目,然后起 Apache 或者 Tomcat 运行后端项目,Apache和Nginx的区别 ,简而言之,现在的 web 项目基本上都是跑在 Nginx 上的,虽然项目部署这类事情不用我们操心,但多了解一点总是没错的。
安装就不赘述了,之前的文章也有提到
通过配置别名的方式来调用nginx
Nginx 的配置默认都在 conf 文件夹下,默认的配置我就不放了,各位安装成功后打开 conf 下的 nginx.conf 就能看到,下面是我改过的配置文件 nginx.conf ,没有用到的一些注释我都删掉了,为了节省篇幅,在 Nginx 的配置中使用 #
来进行注释
下面我们使用的主域名以 xxx.com
为例
多个子域名配置
上述配置大致意思是,都访问的是本机的 80 端口,但是因为访问的域名不同而使用不同的配置,从而达到多域名配置的效果
。。。
七牛云的域名开启 https ,我在自己的服务器上操作了半天,上传的本地证书各种不合格,后来发现直接用七牛云提供的免费证书就可以了,申请只花了 15 分钟。
而且最后发现之前的那个问题是我理解错了,并不需要用 https 链接的图片,但是既然开了就留着用吧
熟悉我网站的伙伴都知道,我的站点系列有四五个左右,子域名使用的比较多,针对这样的情况我想用的方式是申请一涨通配符证书,这样我的子域名都可以使用这张证书,如果为每个子域名都申请一个的话太麻烦了,而且维护也不方便。
通过调研发现 Let's Encrypt
可以提供免费的 ssl 证书,由于只是小网站,用付费的一年几千的证书大可不必,这种免费的就足以满足我的需求,但是它的缺点是只有 90 天的有效期,过了 90 天就得重新申请,以前我觉得麻烦的点也是在这里,然后最近在寻找这块的消息的时候发现了一个比较好用的脚本 acme.sh ,它的作用就是可以从 Let's Encrypt
生成免费证书,而且每隔一段时间(在当前证书失效前)会自动更新证书,这样就解决了 90 天有效期的麻烦。
执行成功后这个脚本就被安装到了 home 目录下,地址为 ~/.acme.sh/
生成证书我这里是采用的 dnsapi 的方式, 文档链接 ,这个方式是最简单方便的方式,其他的方式我试过之后发现如果要生成多域名的就总是有问题,最后采用这个方式是可以成功的。上面文档中列出了十几种 dns 服务商的处理方式,可以根据自己域名提供商的实际情况选用,我的域名是买自阿里云的
按照操作先去生成 Ali_Key 和 Ali_Secret ,这里有一点要注意的是,进去 账户设置 阿里云会推荐你使用子账户来进行后续的操作,这个安全性我觉得是必要的,生成了子账户之后,根据提示,将账户信息保存一下,然后要给这个子账户添加权限,要添加上对应的权限才能调用 dnsapi 的,不是生成就可以调用的 。
权限添加的弹窗这里,在策略的搜索框输入 dns 可以帮助我们快速的过滤出我们想要找的策略,选择 管理云解析(DNS) 这项,我这里因为已经添加过了所以是不可选的,选择之后会出现在右边的框里,然后点击确定按钮,你的子账户的 key 和 secret 就可以操作 dnsapi 了。
依次输入命令并执行后,执行完成后会有 success 的相应提示,然后把证书给你放在什么位置了等等,这里的可以输入多个 -d 和域名,最后只会生成一个证书,生成证书的时候可以按通配符生成,以第一个输入的域名为名字
新建目录 /etc/nginx
,文件不用新建,执行命令的时候会自动创建,安装证书的时候使用生成证书时的名字
查看已生成的证书的信息,同理也是要输入证书名字
首先确定下自己当前的 nginx 是否安装了 ssl 模块 --with-http_ssl_module
,通过命令 nginx -V
,从执行结果可以看到对应的模块是已安装的,如果没有安装该模块的话需要先安装一下,
原先我的配置都是监听 80 端口,然后根据不同的域名给他们做不同的配置,开启 ssl 即访问 https 的话是访问 443 端口,所以我们可以很自然的想到,只要把原来的 80 端口换成 443 端口,按照 ssl 配置要求配置上就可以实现我们的效果了,访问 80 端口(以 http 的方式访问)的时候将他们都转发到 https 的链接上,这样保证了用户访问的一定是 https 的链接。OK,接下来看下具体的配置
首先因为我所有的域名用的是一个证书,也就是说他们的 ssl 配置是相同的,我将这个配置单独写入一个文件,然后通过 include 的方式引入,便于后续的维护,这是我能想到的比较好的解决办法,如果有更简便的方法还请在评论区不吝赐教
配置到这里就 OK 了,访问网站就都是 https 了
Python 3.7.4 (tags/v3.7.4:e09359112e, Jul 8 2019, 19:29:22) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
表示安装成功
]]>表示安装成功
本系列不是 Python 教程,只是本人学习中做的随笔或者总结,阅读本系列文章可能需要一定编程基础,请依照个人能力基础选择。
编程语言基本都有大致的基础,数据类型、变量、函数等等,Python 也是一样,Python 的数据类型主要有整数、浮点数、字符串、布尔值、空值。以下会挑几个差异大的记录
字符串也是支持使用 \
进行转义操作,允许使用 r''
表示 ''
内部的字符串默认不转义,示例:
但是要注意的一点是字符串末尾还是不能是单反斜杠,会导致编译报错,查阅资料说这是 Python 的 bug ,毕竟按照理论上来说,字符串用 r''
包裹后,里面的转义字符会失效,但末尾的反斜杠还是将它后面的引号转义了,从而引发报错了。
多行字符串使用开头和结尾都是三个引号来表示,在交互命令行中输入多行的时候,提示符会由 >>>
变为...
,但是多行字符串也还是字符串只不过写法特别一些,它也可以使用 r''
。js
中 ES6
是使用前后三个反引号,这点还是有区分的,示例:
Python 中的布尔值是用 True
和 False
来表示的,注意首字母是大写的,和 js 是不同的,布尔值的运算使用 and
、or
和 not
运算, js
中进行布尔值运算使用 &&
、||
和 !
这些符号,意义是相通的
空值是Python里一个特殊的值,用None
表示。None
不能理解为0
,因为0
是有意义的,而None
是一个特殊的空值。
在Python中,通常用全部大写的变量名表示常量,这个规则只是个约定的规范,你非要定义别的格式或者改变这个变量值也拦不住你
整数的除法:/
普通的除法和 js 一致; //
称为地板除,除完只保留整数部分; &
取余运算,得到余数
想了想,还是不和工作回顾写在一起了,工作回顾算是我一年周报的汇总,和复盘还是有点区别的。
]]>想了想,还是不和工作回顾写在一起了,工作回顾算是我一年周报的汇总,和复盘还是有点区别的。
今年真的做了很多的项目,但是发现了自己很多不足的地方,组长和我说了一些,我自己感受也有一些。
工作主动性不足。在有调研需求的时候未能调研完全,调研汇报不能达到举一反三的地步说明自己还是未调研到位,调研工作花的是公司的时间,应当更明确的对待。
耐心不足。这个嗯,五五开吧,在某些状态下耐心会差,像工作频繁打断等,大部分时间我的耐心都还是可以的。
在对需求的理解上不足。下半年经常出现估期不足导致加班的情况,不应当受到别人的影响,先对于需求有明确的理解之后,经过思考再给出估期,不能受到影响后,在对需求不明确的情况下仓促给出估期,导致后期越做越多。估期是个比较困难的事情,我经常折在这事儿上,20年应加强这块的理解,更准确的根据自己的工作能力给出适当的估期。
从个人来讲的话,方面还是蛮多的,过去一年变化也是蛮多的
自己的技术实力欠缺。有很多知识自己只是懂表面,对于其内在根本没去理解。时间管理存在问题,未做到合理规划时间。20年要在较短的时间内学完订阅的课程,做笔记,并且做分享,当一门技术能把别人教会的时候,才是自己真的理解了的时候。现在的很多技术上的问题我自己可能都有点懵懵懂懂,在给别人讲解的时候便会暴露出来,自己不知道这么做是为什么,该代码能优化性能,为什么,它怎么优化的性能。
自己的输出不够。 19 年相比 18 年,我写了有十几篇技术相关的文章吧,自己的博客网站也稍微整理了一下,看着文章列表从只有一个 hello world 到分页有五六页,心里肯定是感觉挺开心的。也有少数的文章同步发布在公众号上,主要是公众号上阅读代码不如在 PC 上便捷,所以技术文章很少发。20 年要增强输出能力,更多文章发在博客上、公众号上,公众号上可以多发布一些学习笔记,结合自己的实践以及学习做的笔记。
过去一年有很多无意义的消费。随着消费观念的变化,经常会有一些很想买的东西,像小米众筹的一些东西,感觉挺好玩挺有趣,买了之后没多久就吃灰了,或者点外卖的时候以为自己的食量很大,实则吃几口就会饱,造成一定的浪费行为,所谓积少成多,如果不注意自己的消费,会平白浪费掉很多钱。由于四月份的时候搬了家,新的屋子比较小,买了很多东西以至于都快放不下了。
为了保持自身的竞争力,技术要增长,这样在一些时候就可以自信的做出决定而不是犹犹豫豫被公司左右,今年应该是自己在技术道路上比较重要的一年,是第一个时间节点,不要再重复,应有创新,应有深入,了解远离,学习更多的知识,极客时间的订阅平时的学习零零散散,现在应该重视起来,自己在极客时间上大大小小加起来买了应该也有 1k 的课程了,这些课程不能浪费了,要利用起来,有条件的情况下,边看边做笔记。
学习要有计划,明确自己要学到什么,通过学习我是否学到了自己想要学的,如果没有,要继续去实现学习目标。学到一定程度做分享,我发现好多时候我没能看到问题,如果我把技术讲给别人,别人提问的时候可以问到我没有想到的地方,我再去学习解决这些问题可以知道的更多
多学习区块链知识,对于底层的相关知识要有一定的了解,对于需求要想的仔细,思考过后给出估期,列出详细的 todo list 之后进行工作,任何地方都多想想
不要乱花钱,好多东西买了实际上也用不到,对于小杂耍,应保有一定的理智,但是对于一些该买的东西不要过分犹豫,根据需求,需要的东西就及时购买,过多的犹豫浪费时间和精力
其实对于各项的展望上面都有提到,还是再总的说一下,在 20 年要做的: 促进技术成长,加强工作能力,明确消费价值
]]>在这个方面,我觉得可以给我自己打负分了,基本上每天都在熬夜,有时还会晚到三四点,总是不能克制主自己的想法,总想再多玩一会,实际上都只是在毫无意义的消磨时间,周末的时候睡得晚,起得也晚,常常在中午的时候起床,直接失去了半天时光,感觉非常浪费。
今年年末的时候,北京的疫情放开了,在这之前疫情严峻,公司让居家了两个周,放开后,公司要求回公司上班了,而且不查核酸只看绿码,我是一万个不想回公司上班,但是还是得去,回公司上了一天班之后,第二天早上起床就发低烧,然后申请了居家,第三天早上烧退了,测了抗原阴性,也没其他症状,所以我开始认为我只是感冒了,但是比较严重,然后中午的时候突然烧到38.5,就可以明显感知到体温在迅速升高,我有点慌,因为我没有药,我一直认为国家既然放开,肯定能调控药物,不需要提前储备啥的,但这次显然没有,只能是之前联系的朋友让帮忙在家那边购买然后寄过来。晚上的时候捂了捂汗,第四天早上再测已经回到低烧了,这让我放心不少,低烧持续了两天,第五天的时候就退烧了,然后就是嗓子痛+咳嗽一直持续着,周末的时候忍不住测了下抗原,阳性!,下个周就申请了继续居家,毕竟还没有转阴,咳嗽也还很剧烈。
看着抗原上的两道杠渐渐隐现的时候,心情是很奇妙的,我有预期,放开之后我必定阳,但真的阳还是有些唏嘘。好在我的症状不重,后面和同事沟通,他说基本上周三前出现症状的都不太重,周三后出症状的都比较重,可能是不同的毒株,现在我咳嗽基本已经好了,但我还是有点担心回到公司上班之后会不会再感染一波重的,不过现在已经有药了,所以如果出现也能抗一抗吧。
今年没有特别的理财,还是在跟且慢的理财计划,由于每周都在跟周周同行,且数额较多,所以周周同行在账户资金中的占比不断提高 占比为: 周周同行:39% ; 长赢计划: 18% ;春华秋实: 35% ; 我要稳稳的幸福: 8% 。 整体持有收益: -3.42%
关于理财的书也没怎么看,指数基金定投那本书,好几年了都没看完,没有主动再去炒股这些,没有知识储备还是不做这种事情了。年末有个个人养老金,买了一份,因为说能少交税,多少也能省点吧。
呵,这块可以说是我的盲区了,很少去认识新的人,没什么渠道也
在工作这块,本年度可圈可点的也很少,中间做过项目主R,需求还是一个接一个,人员一度扩充到两个,不过后面又变成一个人了,在需求的迭代中很多计划没有时间去做,可能又到了我的瓶颈期,我需要主动去寻求更多的突破,可以在已有的事情上做更多的事
今年也还是一个人跨年,中间短暂的有过一段感情,各种原因吧,没能走下去。基本上的长假期我都会选择回老家,这样一年回家的次数也还是屈指可数,而且有时因为疫情封控,回家也很麻烦,后面不再封控了兴许回家可以方便一点。
嗷子哥说他明年就要回家去了,他已经在准备考公相关的了,感觉在北京呆的没有未来,我有时也会想这个,什么时机合适回去老家那边,回去的话选哪个城市继续发展,后话了这是,目前没啥回去的必要,再奋斗两三年,看看自己还能有提升不能。
这个看我博客的更新频率也能看出来,今年花在自己专业上的时间相当至少,几乎很少在业余时间学习专业知识。
倒是有学习不少做饭的知识,看了很多做饭的视频,也有自己进行实践,因为今年居家的时间比较多,经常需要自己做饭,自己做饭也要有些许追求,也要吃的丰富,也要吃自己想吃的好吃的。这一块是我能说我今年有花时间去学习了的
在第四季度的时候去考了增驾D证,就是可以骑摩托车的驾驶证,因为已经有C本了,所以是增驾,我的C本已经考出来六年有余了,已经换了十年证了,但是在这期间,实际上基本没有开过车,在北京工作,基本没有那个买车与开车的机会了,骑摩托可以是一个有车的途径,之前正好同事谈起报了名,想着也一起去学个算了,结果我们仨考出来了之后都没有买摩托来骑哈哈。我住的地方离公司比较远,骑车不如地铁方便,其次我感觉骑车不如开车安全些,毕竟肉包铁,内心也有想要不买个车骑着玩玩,就周末去不远不近的地方溜达溜达也可以的样子,明年看看吧,如果我能保持经常出去玩的话,可以考虑一下。
2月份,给自己买了一台14寸的mbp,不一定非要用来做什么,但是拥有会令我比较快乐,买的32+512的版本,实际使用发现16的足够使用,32的有点浪费,不过毕竟要用很多年,也还好了。
8月份,去逛了动物园+海洋馆,自己一个人去的感觉很不错,就是天气太热了,下午早早就回来了。然后为了自己后续出去玩可以好好的拍视频,买了个DJI Pocket2,但是买了不久就迎来了疫情,出门不方便了。
9月份,去吃了千岛湖鱼味馆的鱼头,味道很奈斯,晚上在京的几个大学同学聚会,去什刹海玩耍,然后在别人家店里逗猫的时候被猫抓了(哭泣),针孔大的一个伤口,但是见血了,连夜去打了狂犬疫苗。
十月份,十一假期正好在家,家里人一起给我过了生日。
十一月,买了文石Leaf2 用来看书;买了BOSE QC45 通勤听歌。
将自己闲置的极米H3S、文石NoteX 都出咸鱼卖掉了,回了不少血
今年我的B站播放突破了累计5w,也做了很久的直播,当然都是打游戏顺便开的直播,粉丝数到达了50,还不错
2022年,总的来说还是平平无奇,但在奖励自己这块上总能找到理由,上文也能看出给自己添置了不少东西,当感到生活无趣的时候,买买买总是比较令人舒心的。依旧在坚持买很多的课程,试图做一些学习,最终也并未行动,2023的话,不做什么目标和期望了,感觉自己不会行动的,希望自己在玩乐这块可以更尽兴吧,想出去玩就出去玩,想打游戏就打游戏,多做点视频,明白的摆烂一年又如何,设定了目标不也一样在摆烂么。后面附上一点今年的值得记录的图片:
]]>
年初三月份,因晚上下楼丢垃圾踩滑扭伤了脚,基本上半年都在伤痛中度过,虽然只是踩滑,但是脚撕脱性骨折,感觉就是比骨折轻比扭伤重,然后胳膊也扭伤了,屁股也摔了个敦实。恢复的非常慢,前期请了三周病假,去医院挂号看病,先去的住的附近的,不放心又去的积水潭,还是应该去积水潭啊,已经在北京了,这么好的医疗条件不用可惜了啊。好在没有大问题,自己也足够小心,恢复的虽然慢,但是没有变坏。以前一直以为急诊是那种急到快挂了的才能去,才知道如果是刚受伤就可以去,希望后面不要用到这个知识。
同事听我请了三周,还只是楼梯摔的这么重,都表示不能理解,说要骑个摩托车伤重还差不多。我也很无奈啊,这楼梯我都走了三年了,谁承想有这事,幸好庆宇刚搬到我隔壁,请他速来一楼将我扶起来了,不然感觉能坐半小时不过分。鉴于这次受伤,深刻感觉到自己体质的脆弱,待身体恢复了之后又平稳了一段时间,想着加强一下运动,有点想骑自行车,于是骑共享单车上下班试了一次时间与强度,感觉还行,时间和坐地铁差不多,于是在 9 月购入了山地车,开始进行一个上下班的通勤。下雨、下雪、零下十几度不骑,其他的时候尽量都骑。
12 月份的时候,终于赶得及把公司的体检福利用了(31 号过期),还是检查基础的那些项,查男内科的时候,医生和我说,我的心脏跳动有力,呼吸也很平稳,一看就是平时有坚持运动,我听了不由得窃喜哈哈,有种好像临时抱佛脚但是抱到了的感觉。但是医生也提了我的肚子,说这个肚子啊,不能再大了,再大就不太好了,以后晚饭要少吃,吃清淡,晚上八点之后就不要再吃东西了。因为我平时不吃早饭,所以目前是午饭吃的少,晚饭吃的多,又由于睡的晚,晚上经常还会加餐,所以可能确实不太好,这个肚子也是今年非常的凸出,而且骑自行车不减肥,这个也挺难受,或许我得进行一下跑步才行,希望明年夏天到来之前可以把肚子减下去。
今年巨亏啊,tmd,我最后悔的就是跟了且慢的周周同行,太垃圾了,但是现在投入的有沉默成本,还不好直接弃车也是挺纠结的,今年把春华秋实计划给卖了,这个计划也是辣鸡,或者难道说就因为我买入了,所以才开始跌了么,就是说人平时还是少做这些碰运气的事情,本来就不是很懂,光去相信平台有啥子用
金融知识?还是没学啦诶嘿嘿,学不了一点
今年有三个朋友离开北京,最后一个或许可以算作是明年?算了差不多吧,起码是今年做的决定,上半年是大南哥,下半年是嗷子哥和桃子哥,桃子哥要去武汉了,他媳妇也会过去,真好啊,一起换个城市生活,北京真不太值得留恋,最后又留不下,干多少年都只是打工而已。宇子哥一段时间在我隔壁住,后来也搬走了,这样见面的机会就很少了,毕竟离得挺远的,工作也忙。
今年花了大几百加的 AI 的社群,好像晚一天加上就赶不上潮流了,最后也是没有行动起来,又是白丢钱,下半年直接都不看知识星球了,公司有骑行社群,犹豫了很久还是没有加入,一方面我想加入社群,看下都会组织些什么活动,另外也想获得一些赛事的信息,另一方面又对于这种入群感到胆怯,怕遇到自我介绍的场景
工作内容基本上没什么变化,年底的时候新接了一个项目是基于 pixijs 的画板,这个挺好,是一个我没有接触过的项目,很开心可以学到新的知识,但是这个画板的问题真的挺难排查的。好像回到了我刚接主讲的业务那个时候,仿佛进入了一个问题工厂,出了问题连定位问题都很麻烦,当然最麻烦的是评估影响面,对业务不熟悉很难评估影响面。现在业务已经基本上熟悉了,再加上前面做的一些整合类的大项目逐渐全量,要维护的业务方向有所收缩。在熟悉业务的基础上,也开始做一些业务上的整合,优化项目,减少维护压力。一些事情本该是早早的做的,那时的时机更合适,比现在再改的影响面要好一点。可惜换不得。现在只能是跟一些技术项目或者需求节奏进行我的重构,这样有一个完备的测试计划与灰度放量,可以将影响尽可能的降低。
今年脚受伤的时候因为公司不给居家办公,没办法只能请病假,但是我这方向没有其他的 backup ,同时有一个大的项目正处在测试的阶段,所以病假期间还是要响应工作,虽然说可以按 0.5 人力,但是工作问题来找不会分上午下午,基本也是全部支持了。但是好在付出的努力有得到收获。
说起来,在这家公司已经三年了,11 月中旬的时候发了三周年工卡,我还是挺喜欢这种仪式感的。真的是不知不觉的就三年了,上家公司都没待满三年就走了,也幸好是早点离开了。工作已经快六年了,自然是没有达到自己当初的想法预期,感觉还是菜,瓜的要命,瓜的可以报警
生活还是每天两点一线,没有什么变化,去年说 2023 一定谈对象,但是时间过得太快了,我还没来得及开始,2023 就过去了,主要也是脚伤耽误了挺久的。青藤上认识一个,也见过面,但是聊着聊着感觉没有话题,于是提出,她也是这么觉得,所以就愉快解散了。
也有一点点疑惑,找对象找的是啥捏,玩伴?朋友?我自己是想起码要聊得来的吧,聊得来才会想继续聊,继续了解,其他的话要真诚,就这样了,但是这样也还是很难遇到。
去年的时候我都在嫌弃项目,嫌弃上一个接手的同事不好好写代码,留下很多的冗余和包袱限于影响面不好修正,今年想明白其实自己有时候也有项目周期急的时候,也会写一些垃圾代码,而且自己的目光有限,自己每行写下的代码其实也是祖传代码,只是留待后来的人评说罢了。但是我大部分都是在好好写的,良品率应该要高一点的吧,起码线上工单变少了这样子。今年没怎么学习新技术,唉也不找什么借口,就是懒吧,再一个感觉现在好像也是在一个舒适圈了,唉!
今年去看了开心麻花的演出《乌龙山伯爵》、去看了脱口秀、去了环球影城、去了大同,朋友来北京玩,我做了攻略,招待的的还算周到。以前我很少出门,但是现在想其实出门是最简单的,看演出,看电影,去游乐园,这些只要花钱花时间就可以了,那为什么不去呢?去其他的城市也是一样,自己有相机有 pocket 其实很适合出门采风,所以伙伴相约立即就答应了,而且我们去大同真的是来了一场说走就走的旅行,其实那个周末我俩都是有点忙的,但是因为约好了也就去了,所以说到底,没有放不下的工作,旅行就是说走就走,果断点。
今年上半年主要在玩 LOL,下半年基本都没有再玩 LOL,大部分时间在玩王国之泪,也有一部分时间在部落冲突。
今年开始做很多之前不想做、不敢做的事情,突破自己。脱口秀去了两场,第一场是个小厅而且可以选座,和伙伴选在了第一排,和主持人还有演员都互动了一下,还是很紧张的,感觉说话的时候嘴都在抖,第一排这个互动还是挺难的,第二场去的付航的,这个不敢坐第一排了,再说也抢不到第一排。说走就走的旅行来了一次,环球影城的过山车也坐了。
年底开始骑车通勤,通勤时间和地铁差不多,但是体验还是很独特的,后面天气好的情况下也会一直坚持骑车通勤,可以锻炼身体,增加活力。
根据本年的照片,写一下今年的流水账
整理年度照片才发现,今年没怎么做饭,或者说没怎么尝试新的菜,基本都是在已有的菜里反复操作,明年要学一点新菜这样子。23 年总的来说,上半年感觉过的又快又慢,快是没怎么活动就结束,慢是因为上半年请假和养伤相关的事情还蛮耗费精力的;与之相对的,我的下半年肉眼可见的丰富,去了各种演出,也出去玩了,也招待朋友来玩了,也自己做过攻略了。明年还要继续出去玩,生活已经这样一滩烂包了,不整点乐趣怎么能行,照片拍的还是不太行,明年要继续加强。
今年年底又裁员了,我们这里没有裁,也可能是没有轮到,桃子哥去武汉也是相关的原因,另外岳哥短暂了来了公司几个月,也在这个浪潮中一起离开了.去年年底也有裁员,不过当时给的是 n + 2,今年只有 n + 1 了,想会不会到明年裁自己的时候就只有 n 或者没有了呢,也搞不太清楚公司是什么情况,经营不善会裁员,高歌猛进也裁,只有裁员这么一个节流的方式了吗。聊到这里顺便多说两句,周末去看了《年会不能停》,里面说的裁员真的挺应景的,看到后面的时候就在想,如果是自己的公司遇到,自己该咋整,什么情况下是不担心被裁的,想了很多。
今年的总结写了很多字,但是想想谁会看我的总结呢,有什么所谓,反正最后还是自己看,所以说按自己所想所写,不用考虑辞藻是否华丽,措词是否简练优雅,只是写,只是记录,这样就可以了。
]]>