醉月思 发布的文章

js类似于printf那样的格式化字符串

安装包
npm install sprintf-js
调用包
var sprintf = require('sprintf-js').sprintf,
操作实例:时间前补零操作
for (let i = 46; i >= 0; i--) {
        console.log(sprintf('%2d:%02d', i / 2, (i % 2 ? 0 : 30)))
      }

引言

首先看一张最终效果图

终端.PNG

大致思路

使用win10的linux子系统,安装zsh,默认切换zsh终端。(什么鬼,这和装虚拟机有什么不一样?放心,不一样的,慢慢看)

为什么要需要它?

  1. cmd太丑,cmder略慢,然后就是命令的不统一性。
  2. 一个好看的终端可以让程序员变得开心又愉快。
如下

截图.PNG

准备工作

  1. win10内部版本16215.0以上
  2. 打开win10开发人员模式
  3. 勾选控制面板>程序>启用windows功能>linux子系统
  4. 重启
  5. 打开应用商店>搜索linux, 选择你喜欢的linux发行版安装,我选的是ubuntu18.04,如果卸载了应用商店可以自行百度开启方式

-- 至此:linux系统安装成功

在linux子系统中需要做的操作

在开始栏运行ubuntu

或者win+R,键入wsl运行。

安装zsh

sudo apt-get install zsh

设置默认shell

chsh -s /bin/zsh

安装oh-my-zsh

sh -c "$(wget https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

(可选项)修改主题

nano ~/.zshrc
我的修改如下

2019-03-12T07:02:46.png

让bash每次打开自动执行zsh

重新打开终端窗口,我们目前的效果是这样的。

ssh1.PNG

然后就会发现,这丫的,这怎么跟我的win10保持文件共享呢?

让linux子系统默认打开win10用户根目录

  1. 首先找到C\\windows\\system32\\wsl.exe,复制到你的win10用户根目录。
  2. 再为根目录的bash.exe创建快捷方式发送到桌面。
  3. 运行
看,好神奇

2019-03-12T07:14:16.png

可是,,,难道每次我运行命令都要回到桌面启动?而且就不能像ubuntu那样ctrl + alt + T打开?

为适应win10的一些配置

  1. 右键点击桌面快捷方式,选择快捷键,同时按ctrl + alt + T设置快捷键。
  2. 桌面右键>选择查看>取消勾选显示桌面图标
测试ctrl + alt + T,我可能是为数不多的秀win10桌面的程序员:) (好像还是没有linux的好看?)

2019-03-12T07:23:44.png

在vs code里配置默认终端为wsl.exe。效果展示

2019-03-12T07:27:41.png

结束语

因为截图会变模糊,实际效果比这好看的多,嗯,又多了一个装逼的东西。

为啥需要这个?

有时候我们写微信小程序,写好了。在手机上运行感觉效果还不错,正想分享给别人。突然发现没有分享选项,纳尼?原来是忘记写onShareAppMessage()了。有得加上,再编译。不得不说,麻烦的一匹。

应运而生

然后我就想,要是可以让默认支持分享就好了。

wepy实现方法

大致思路

import wepy from 'wepy';
export default class Page extends wepy.page {
}
分析代码,发现所有的page都继承于wepy.page, 而wepy.page又继承于wepy.component. 这感情好。也就意味着我只需要构建一个超类继承wepy.page就可以了

实践

新建page.js文件,内容如下
import wepy from 'wepy';
export default class Page extends wepy.page {
    onShareAppMessage() {
        
    }
}
然后再调整一下页面继承
import Page from '../page';
export default class Index extends Page {
}
编译运行,果然如此!

如果要自定义分享内容怎么办?

在子page里面重构onShareAppMessage就可以啦。

tips: 现使用uni-app后发现已经默认支持分享了

后续: uni-app说这是个BUG,已经修复了。。

后备方案——使用mixin全局混入

  1. 在main.js中添加以下内容。
import qs from 'query-string'
Vue.mixin({
    onShareAppMessage() {
        console.log('分享路径', '/pages/index?route=' + this.$mp.page.route + '&' + qs.stringify(this.$mp.query))
        return {
            path: '/pages/index?route=' + this.$mp.page.route + '&' + qs.stringify(this.$mp.query)
        };
    }
})

以上代码实现了所有页面都支持转发,并将转发路径设为主页。

  1. 在主页的onLoad函数中加入以下内容
if (options.route) {
                uni.navigateTo({
                    url: '/' + options.route + '?' + qs.stringify(options)
                })
            }

这样就实现了,进入后的页面跳转。

  1. 为什么要这样做?

因为大家都知道,当我们直接分享小程序页面给别人的时候。别人点击进入非tab页面,是没有返回操作的。增加了上面的功能后,所有页面的分享,都会先进入主页,再跳转至分享的页面。用户就可以无缝对接啦!

更新,现小程序已支持页面返回

想达到本文效果,需使用wepy框架。不了解wepy?转https://tencent.github.io/wepy/index.html

什么是async/await?

在最新的ES7(ES2017)中提出的前端异步特性:async、await。
async顾名思义是“异步”的意思,async用于声明一个函数是异步的。而await从字面意思上是“等待”的意思,就是用于等待异步完成。也就是我们平常所说的异步等待。不过需注意await只能在async函数中使用

为什么需要async/await?

在async/await之前,我们有三种方式写异步代码

1. 嵌套回调

其中思想就是,a函数执行完了得到的结果后在执行b。
形如

wx.getSetting({
      success(res) {
        console.log(res.authSetting['scope.userLocation']);
        if (!res.authSetting['scope.userLocation']) {
          wx.authorize({
            scope: 'scope.userLocation',
            fail(res) {
              Toast('无法获取位置,采用默认排序');
            }
          });
        } else {
          wx.getLocation({
            type: 'wgs84',
            success(res) {
              _this.setData({ location: res });
              console.log('您的位置信息:', res);
            },
            fail() {
              Toast('无法获取位置,采用默认排序');
            }
          });
        }
      }
    });
上面的代码你不用看,就会感觉。这啥东西?乱七八糟的。这就是嵌套回调。很不巧,原生微信小程序开发就是这样的。

2. 以Promise为主的链式回调

所谓Promise,简单来说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。形如
var p1 = new Promise((resolve, reject) => {
 setTimeout(resolve, 1000, 'done');
 })
p1.then(data=>{
 console.log(data); // done
})

如果你的函数够多的话,那么就会一直then()下去。

为了优雅,Promise提供了一个方法Promise.all([p1,p2,p3]) ,用于将多个Promise实例,包装成一个新的Promise实例。接收的参数是一个数组,p1、p2、p3都是Promise对象
分两种情况:
  1. p1、p2、p3的状态都是resolve的时候,Promise.all的状态才会变成resolve;
  2. 只要p1、p2、p3中有一个的状态为reject,那么Promise.all的状态就会变成reject;

所以我们可以用Promise.all()来解决多个异步依赖调用。

3. 使用Generators

function *main() {
    var x = yield 1;
    var y = yield x;
    var z = yield (y * 2);
}
上面代码中的每一条语句都会按顺序一个一个地执行。Yield关键字标明了代码中被阻塞的点(只能被generator函数自己阻塞,外部代码不能阻塞generator函数的执行),但是不会改变*main()函数中代码的执行顺序。这段代码很简单!

但是,这三种写起来都还是不够优雅,ES7做了优化改进,async/await应运而生,async/await相比较Promise 对象then 函数的嵌套,与 Generator 执行的繁琐(需要借助co才能自动执行,否则得手动调用next()), Async/Await 可以让你轻松写出同步风格的代码同时又拥有异步机制,更加简洁,逻辑更加清晰。

示例
async a(){};
const b = await a();

这样做的好处?

唔,你不觉得一个优雅的代码就该是这样吗?好吧,其实这样更容易符合我们平常的思维逻辑

回到本文的题目

在wepy1.4.1以后的版本(之前的版本都是默认开启的),默认不支持async/await,需要用户手动加入,方法如下:

进入项目根目录,安装runtime包

npm install wepy-async-function --save

修改wepy.config.js加入runtime配置

        babel: {
            "presets": [
                "env"
            ],
            "plugins": [
                "transform-export-extensions",
                "syntax-export-extensions"
            ]
        }

在app.wpy中引入引入runtime包

import 'wepy-async-function'; 

在app.wpy中使API promise化

重写构造函数,使其支持async/await。
export default class extends wepy.app {
    constructor () {
        super();
        this.use('promisify');
    }
}

重启编译

wepy build --no-cache

使用示例

在wepy框架官方文档中已说明,对所有的微信小程序都支持async/await操作。只需将形如wx.getuserInfo改写为wepy.getuserInfo即可
async userInfoAsync() {
    const _this = this;
    const data = await wepy.getSetting(); //获取设置数据
    if (data.authSetting['scope.userInfo']) { //判断是否有获取用户信息的权限
      await wepy.login(); //登录
      let data = await wepy.getUserInfo();//获取用户信息
      _this.userInfo = data.userInfo;//采用wepy框架修改过后的功能,支持直接赋值数据绑定
      _this.$apply(); //在async的函数中,必须主动执行`$apply()`来进行脏数据检查
    }
  }
async onShow() {
    this.userInfoAsync(); //调用async函数
  }
以上代码实现了异步同步用户userInfo的功能

参考文献:

  1. 使用Promise链式调用解决多个异步回调的问题
  2. 关于js的callback回调函数以及嵌套回调函数的执行过程理解
  3. ES6 Generators并发
  4. ES7前端异步玩法:async/await理解
  5. 理解 JavaScript 的 async/await
  6. Async/await学习
  7. 浅谈async/await
  8. wepy项目中使用async await

vscode

Vscode 格式化vue Template代码段

1.安装 vetur
2.在User Setting中增加设置:
"vetur.format.defaultFormatter.html": "js-beautify-html"

2020.07.08留:我现在已经使用prettier来格式化代码了

Vs code 添加 wepy template 代码

  1. 打开File > preference > user snippets, 选择vue
  2. 编辑vue.json
{
"Print to console": {
        "prefix": "vue",
        "body": [
            "<!-- $0 -->",
            "<template>",
            "  <view class='page'> </view>",
            "</template>",
            "",
            "<script>",
            "import wepy from 'wepy'",
            "export default class Index extends wepy.page {",
            "config = {",
            "    navigationBarTitleText: '场馆预订',",
            "    usingComponents: {}",
            "};",
            "",
            "components = {};",
            "",
            "mixins = [];",
            "",
            "data = {};",
            "",
            "computed = {};",
            "",
            "methods = {};",
            "",
            "events = {};",
            "",
            "onLoad() {}",
            "}",
            "</script>",
            "<style lang='less'>",
            "</style>"
        ],
        "description": "Log output to console"
    }
}

使用emmet自动代码补全

  1. 打开File > preference > setting, 搜索emmet.triggerExpansionOnTab
  2. 设置为true

自动读取eslint文件并进行修复

  1. 先安装eslint
  2. 设置中添加以下内容
{
  "eslint.autoFixOnSave": true, //  启用保存时自动修复,默认只支持.js文件
  "eslint.validate": [
    "javascript", //  用eslint的规则检测js文件
    {
      "language": "vue", // 检测vue文件
      "autoFix": true //  为vue文件开启保存自动修复的功能
    },
    {
      "language": "html",
      "autoFix": true
    },
  ],
}
2020.07.08留:这个配置已经过时了

正则删除HTML标签

Ctrl + H 正则匹配 <[^>]+> 替换为空

正则替换换行

Ctrl + H 正则匹配 \n 替换为你想要的

tab无法缩进代码

Ctrl + M试试

多光标操作

1、按住alt,用鼠标左键点击,可以出现多个光标,输入的代码可以在光标处同时增加。
2、按住Ctrl + Alt,再按键盘上向上或者向下的键,可以使一列上出现多个光标。
3、选中一段文字,按shift+alt+i,可以在每行末尾出现光标
4、按shift+alt,再使用鼠标拖动,也可以出现竖直的列光标,同时可以选中多列。

rpx单位

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。要实现4:3的展示则可以
image{
    width:750rpx;
    height:563rpx;
}

使用组件库,写的css样式优先级太低

不管三七二十一,加!important
.findButton {
  width:300px !important;
  height:35px !important;
}

样式各种飘,不居中怎么办?

<view class="nickName">
  <view>{{userInfo.nickName}}</view>
</view>
.nickName {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 44px;
}

selectedColor无效

selectedColor 和 list 是同级别的。写在list数组外面就可以了。

背景虚化

blur中的参数是虚化比例
filter: blur(1px);

scroll-view设置`scroll-x"也不会横向滚动

要给scroll-view加上white-space: nowrap; ,给scroll-view的子元素box加上display:inline-block;

安装nodejs

sudo apt-get install nodejs
sudo apt-get install npm

全局安装包

sudo npm i -g cnpm

查看全局安装的包

npm list -g --depth 0

全局卸载包

sudo npm uninstall -g cnpm

清理缓存

npm cache clean -f

默认镜像太慢换淘宝镜像

npm config set registry https://registry.npm.taobao.org
现在我常使用cnpm包
检查配置是否成功
npm config get registry

正则删除关键字所在行

查找:

^.*大师兄.*$
替换为:(空)

如果不留空行:
查找:

^.*大师兄.*\r?\n

替换为:(空)

正则删除HTML标签

Ctrl + H 正则匹配 <[^>]+> 替换为空

正则替换换行

Ctrl + H 正则匹配 \n 替换为你想要的

好好学习

每天花大把时间在微信上,但其实有没有什么重要的事情。仔细统计了一下,如果我一天不看微信,每天至少可以多出1-3h。每次都高估了自己被世界需要的可能性。没看手机时,以为全世界都在找我,看手机时发现没人关注我。

预备,晚上

今晚会不会有人发现我不在了?一想到要坚持三天就感觉有点困难。

第一天

正常

第二天

由于不可抗力,该计划被迫终止。