墨抒颖

墨抒颖 查看完整档案

绵阳编辑西南科技大学  |  计算机科学与应用 编辑国星宇航  |  webgl高级前端工程师 编辑 msy.plus 编辑
编辑

moshuying.top
前端 vue/three.js/react-app
后端 koa/express/eggjs/php
个人主站 https://msy.plus

正在谋求一份工作Email:1460083332@qq.com

个人动态

墨抒颖 发布了文章 · 2020-11-16

当请求的凭据模式为“包含”时,响应中的标头不能是通配符‘*‘。

欢迎访问moshuying.top查看更多信息

详细错误信息 Access to XMLHttpRequest at 'http://localhost:7894/Login' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

前端 vue-antd-admin
后端 java servlet

<!-- more -->

前后端分离的项目中肯定会碰到跨域的问题,跨域的原因还是为了安全。最近在做一个项目的时候发现,即使我已经设置了跨域信息,前端还是报这个跨域错误。

后来找了有经验的后台来帮忙也是弄了很久都没有解决问题,后来我慢慢看请求头和仔细寻找前后端的代码终于发现了端倪。

我项目中失败的请求头

DkcrSU.png

参考自MDN中失败的一个请求头

img

可以发现多了AuthorizationAccept两个请求头,这两个请求头来自前端项目中的src/utils/request.js对请求经行了简单的安全设置,使得请求中携带了安全信息,查看源代码发现代码中设置了

axios.defaults.withCredentials= true

表示客户端想要携带验证信息,这部分功能需要后台支持,而后台supportsCredentials一般被设置为false即不支持客户端携带验证信息

对后台代码进行修改

protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
    res.addHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));
    res.addHeader("Access-Control-Allow-Methods", "*");
    res.addHeader("Access-Control-Allow-Headers", "Accept,Authorization,DNT,Content-Type,Referer,User-Agent");
    res.addHeader("Access-Control-Allow-Credentials","true"); // 允许携带验证信息
    chain.doFilter(req, res);
}

问题解决

参考链接

mozilla的HTTP访问控制
介绍了跨域中其他的头信息

查看原文

赞 0 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-11-16

前端动画框架GSAP框架随笔

gsap是目前非常流行的前端动画框架,可以非常轻松构造出复杂的动画效果,这里仅对我实际使用中的一些例子进行总结

<!-- more -->

官网

示例

文章种所使用代码的在线示例

基础用法

// 声明一个滚动控制器
let ctrl = new ScrollMagic.Controller({
  globalSceneOptions:{
    offset:-200
  }
})


// MORE+ 
Array.from(document.querySelectorAll(".more")).forEach((el,ix)=>{
  let moreLink = new TimelineMax();
  moreLink.from(el,{yPercent:300,opacity:0}) // 在timelineMax中 from是指从某种样式过渡到现在的样式
  new ScrollMagic.Scene({
    triggerElement:document.querySelectorAll("#app div.home")[0].children[ix+3],
    triggerHook:0.35,
    offset:200
  }).setTween(moreLink).addTo(ctrl)
})

// 同时控制两个元素的过渡动画

// 师资简介
init_swiper_teachear(){
  const vue = this
  class SwiperTeacher{
    now = 0
    max = vue.swiperTeacher.length-1
    imgDom = null;
    infosDom = null;
    numListDom = null
    constructor () {
      vue.$nextTick(()=>{this.getDom()})
    }
    next(){
      return new Promise(async (resolve) => {
        if(this.now === this.max) vue.goNext('ADVANTAGE');

        const imgEnd = gsap.to(this.imgDom[this.imgDom.length - 1 -this.now],{xPercent:-100,ease:'power2.out'})
        const infosEnd = gsap.to(this.infosDom[0],{xPercent:(this.now+1) * 100,ease:'power2.out'})

        await imgEnd
        await infosEnd
        this.now+=1
        resolve()
      })
    }
    pre(){
      return new Promise(async (resolve) => {
        if(this.now===0){resolve();return}
        this.now-=1
        const imgEnd = gsap.to(this.imgDom[this.imgDom.length - 1 - this.now],{xPercent:0,ease:'power2.out'})
        const infosEnd = gsap.to(this.infosDom[0],{xPercent:(this.now)*100,ease:'power2.out'})

        await imgEnd
        await infosEnd
        resolve()
      })
    }
    async go(ix){
      const needGo = ix-this.now
      if(needGo===0) return;
      if(needGo<0){
        for(let i = 0;i<-needGo;i++){await this.pre()}
      }else{
        for(let i = 0;i<needGo;i++){await this.next()}
      }
    }
    getDom(){
      this.imgDom = document.querySelectorAll('.introductionOfTeachers .sliderContent .imgContent .img')
      this.infosDom = document.querySelectorAll('.introductionOfTeachers .sliderContent .infoContent')
      this.numListDom = document.querySelectorAll('.introductionOfTeachers .point-teacher .numList')
    }
  }

  let control =  new SwiperTeacher()
  control = new Proxy(control,{
    set (target, p, value) {
      if(p==='now'){
        control.numListDom.forEach((el,ix)=>{
          el.classList.remove('active')
          if(ix===value){el.classList.add('active')}
        })
      }
      target[p] = value
      return true
    }
  })
  this.$refs['sliderRight-teacher'].addEventListener('click',async ()=>{await control.next()})
  this.$refs['sliderLeft-teacher'].addEventListener('click',async ()=>{await control.pre()})
  this.$nextTick(()=>{this.$refs['numList-teacher'].forEach((el,ix)=>{el.addEventListener('click',async ()=>{await control.go(ix)})})})
  let randomTeacher = new TimelineMax()
  randomTeacher.from('div.introductionOfTeachers .sliderContent',{
    yPercent:100,
    opacity:0,
    onStart(){
      vue.swiperTeacher = vue.randomArr(vue.raw_teacher_data,5)
      control.now = 0
    }
  })
  randomTeacher.from('div.introductionOfTeachers .point-teacher',{
    yPercent:100,
    opacity:0
  })
  new ScrollMagic.Scene({triggerElement:'div.introductionOfTeachers',triggerHook:0.35}).setTween(randomTeacher).addTo(ctrl)
}

// 对某个按钮的过渡动画经行处理 通过添加一层元素来经行动画 高阶函数来处理抖动

// 选择院校和新闻大按钮
init_design_button(){
  Array.from(document.querySelectorAll('div.selectInstitution .listContent .designButton,div.news .listContent .designButton')).forEach((el,ix)=>{
    class onceFunction{
      constructor (bg) {
        this.bg = bg
        this.end = false
      }
      main(){
        this.bg.style.backgroundColor = '#e06730'
        this.bg.style.visibility = 'unset'
        gsap.from(this.bg,{scaleX:0}).then(()=>{this.end = true})
      }
      move(){
        this.main()
        this.move = ()=>{}
      }
      leave(){
        if(this.end){
          this.bg.style.visibility = 'hidden'
          this.move =()=>{
            this.main()
            this.move = ()=>{}
          }
        }
      }
    }
    const o = new onceFunction(el.childNodes[0].childNodes[0])
    el.addEventListener('mousemove', ()=>{o.move()})
    el.addEventListener('mouseleave',()=>{o.leave()})
    if(ix===0||ix===3){
      o.move()
    }
  })
}
查看原文

赞 0 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-10-05

在hexo中嵌入three.js运行shader或者three.js的场景

clone代码后查看运行时效果,或立即访问这里查看效果https://moshuying.top仓库链接,点个免费的星星感激不尽。

主题文件默认情况下似乎不会自动clone可以切到主题目录下下载主题,可以自行clone主题

最近想在hexo中嵌入一些shader,折腾了一些时间后终于完善,实际上用这种方法不仅可以在hexo中嵌入shader,也可以嵌入babylonjs,pxixjs,Layabox,Egret,Cocos2等,先看效果,原理什么的其实很简单。

由于一些shader特别消耗显卡性能,在glsl_snippets.js中判定如果第一帧渲染时间超过0.4秒就不再渲染了。

也可以点击shader暂停渲染

嵌入shader

shader来源shaderToy
完全支持shadertoy的代码,参考自大神的代码stackoverflow,在这位大神的代码里获取到完全兼容shaderToy的思路。并将其改成更适用在hexo中。

示例代码

<!-- 至少需要一个div来放置iframe,这样可以方便的将代码移入文章底部 -->
<div id="three"></div>
<script type="module" id="threeMain">
if (!(self.frameElement && self.frameElement.tagName == "IFRAME")) {
  import("http://localhost:4000/uploads/createTHREE.js").then((result) => result.initHexoThreeModule(document.getElementById("three"),document.getElementById("threeMain")));
} else {
  // 这里的代码会被直接执行,window指向iframe内的window(其实就是把代码整个移动到了iframe内)
  import('http://localhost:4000/uploads/glsl_snippets.js').then(async res=>res.glsl_snippets(res.anotherGlsl))
}
</script>

显示效果

嵌入threejs3D场景

一般情况下不建议在一个页面放多个效果如有必要,可以通过交互时渲染,在视图内渲染等方法优化,避免页面卡死

建议clone下这个仓库并运行起来,这两个效果都是可以交互的,也可以直接访问我的小站查看效果https://moshuying.top

实现原理

原因就是hexo对md文件中的script会渲染到页面上,但是不会显示出来,这就有充足的操作空间了。

这里使用iframe的主要原因就是防止来回切换页面导致的webgl上下文问题。不然也不至于这么麻烦。

// 创建iframe并返回iframe内的window对象
function createIframe(divNode) {
  return new Promise((resolve) => {
    let iframe = document.createElement("iframe");
    // ...
    iframe.style =
      "position: absolute; width: 100%; height: 100%; left: 0; top: 0;border:none;";
    iframe.onload = () => resolve(iframe.contentWindow);
    divNode.style = "position: relative; width: 100%; height: 0; padding-bottom: 75%;";
    divNode.appendChild(iframe);
  });
}

创建完iframe后可以为iframe中加载对象了,之前使用的是经典前端的script src加载方式,考虑到可能会被用到,这里保留了函数方便后续修改。
实际使用中利用module中的import()函数直接引入在线文件即可

function cdnLoadTHREE(divNode) {
  return createIframe(divNode).then((iframe_window) => {
    // 创建完iframe才有了iframe内的iframe_window对象
    let link = document.createElement('link')
    link.href = createCss() // 这里对一些样式做了简单修改。
    link.rel = 'stylesheet'
    link.type = 'text/css'
    iframe_window.document.head.appendChild(link);
    return new Promise((resolve)=>resolve(iframe_window));
  });
}

最后将整个script标签复制到iframe内,代码会在复制完后立即执行,由于代码已经在iframe内了,所以window也指向了iframe中,这一步才使得可以方便的使用module保证了向前兼容的同时,也能对老式的代码向下兼容。不至于出现一些奇奇怪怪的问题。

function initHexoThreeModule(divNode,scriptNode) {
  let link = document.createElement("link");
  link.href = createCss();
  link.rel = "stylesheet";
  link.type = "text/css";
  document.head.appendChild(link);
  if(divNode && scriptNode){
    cdnLoadTHREE(divNode).then((iframe_window)=>{
      let script = document.createElement('script')
      script.src = createBlob(scriptNode.text,'application/javascript')
      iframe_window.document.head.appendChild(script)
    })
  }
}

加载iframe到hexo中的完整代码
在iframe中加载shader的完整代码

查看原文

赞 0 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-09-28

js转码与解码emoji

javascript正常的英文编码是utf-8的,mysql默认存的也是这种编码,而emoji表情是utf-16的,这就导致了db存储emoji会有问题,所以最好的方式是,把emoji先转成utf-8的这种实体编码,存到数据库里,要使用的时候,从db拿出来,再解码成utf-16的形式。

原文章


{

 // 表情转码

 utf16toEntities(str) {

 const patt = /[ud800-udbff][udc00-udfff]/g; // 检测utf16字符正则

 str = str.replace(patt, (char) => {

 let H;

 let L;

 let code;

 let s;

 if (char.length === 2) {

 H = char.charCodeAt(0); // 取出高位

 L = char.charCodeAt(1); // 取出低位

 code = (H - 0xD800) * 0x400 + 0x10000 + L - 0xDC00; // 转换算法

 s = `&#${code};`;

 } else {

 s = char;

 }

 return s;

 });

 return str;

 },

 // 表情解码

 entitiestoUtf16(strObj) {

 const patt = /&#d+;/g;

 const arr = strObj.match(patt) || [];

 let H;

 let L;

 let code;

 for (let i = 0; i < arr.length; i += 1) {

 code = arr[i];

 code = code.replace('&#', '').replace(';', '');

 // 高位

 H = Math.floor((code - 0x10000) / 0x400) + 0xD800;

 // 低位

 L = ((code - 0x10000) % 0x400) + 0xDC00;

 code = `&#${code};`;

 const s = String.fromCharCode(H, L);

 strObj = strObj.replace(code, s);

 }

 return strObj;

 }

}

使用示例


const s = 'test emoji 👇👉👈🙌'; 

const dbSaveStr = utf16toEntities(s);

// 结果是: 'test emoji &#128071;&#128073;&#128072;&#128588;' 这样子的实体编码字符串存到db就没问题了

// 要使用时,想数据库中拿到上面的存储记录

cosnt dbOutStr = 'test emoji &#128071;&#128073;&#128072;&#128588;' ;

// 然后将其中的emoji转码成表情使用 

const ret = entitiestoUtf16(dbOutStr ) 

// 得到: 'test emoji 👇👉👈🙌'; 

 将emoji转成UTF-16

这是更通用的方式,因为上面那种只是在web端能显示,如果是要存到db,给c++获取数据再客户端app展示,就行不通了。必须转成unicode-16才行。


// http://www.2ality.com/2013/09/javascript-unicode.html

function toUTF16(codePoint) {

 var TEN_BITS = parseInt('1111111111', 2);

 function u(codeUnit) {

 return 'u'+codeUnit.toString(16).toUpperCase();

 }

 if (codePoint <= 0xFFFF) {

 return u(codePoint);

 }

 codePoint -= 0x10000;

 // Shift right to get to most significant 10 bits

 var leadSurrogate = 0xD800 + (codePoint >> 10);

 // Mask to get least significant 10 bits

 var tailSurrogate = 0xDC00 + (codePoint & TEN_BITS);

 return u(leadSurrogate) + u(tailSurrogate);

}

使用示例


// using codePointAt, it's easy to go from emoji

// to decimal and back.

// Emoji to decimal representation

"😀".codePointAt(0)

>128512

// Decimal to emoji

String.fromCodePoint(128512)

>"😀"

// going from emoji to hexadecimal is a little

// bit trickier. To convert from decimal to hexadecimal,

// we can use toUTF16.

// Decimal to hexadecimal

toUTF16(128512)

> "uD83DuDE00"

// Hexadecimal to emoji

"uD83DuDE00"

> "😀"

判断字符串是否为emoji字符


const emojiReg = /(?:[u2700-u27bf]|(?:ud83c[udde6-uddff]){2}|[ud800-udbff][udc00-udfff])[ufe0eufe0f]?(?:[u0300-u036fufe20-ufe23u20d0-u20f0]|ud83c[udffb-udfff])?(?:u200d(?:[^ud800-udfff]|(?:ud83c[udde6-uddff]){2}|[ud800-udbff][udc00-udfff])[ufe0eufe0f]?(?:[u0300-u036fufe20-ufe23u20d0-u20f0]|ud83c[udffb-udfff])?)*/;

文章来源

查看原文

赞 1 收藏 1 评论 0

墨抒颖 发布了文章 · 2020-08-12

typescript 配置 alias

1 安装依赖

npm install --save-dev babel-plugin-module-resolver
# yarn add babel-plugin-module-resolver --dev

根目录新增.babelrc文件
参考以下内容按您项目中的需要去修改

{
  "presets": ["next/babel"],
  "plugins": [
    [
      "module-resolver",
      {
        "alias": {
          "@/actions": "./actions",
          "@/components": "./components",
          "@/constants": "./constants",
          "@/pages": "./pages",
          "@/public": "./public",
          "@/reducers": "./reducers",
          "@/utils": "./utils"
        }
      }
    ]
  ]
}

修改tsconfig.json文件

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@components/*": ["./components/*"],
      "@pages/*": ["./pages/*"],
      "@public/*": ["./public/*"]
    }
  }
}

注意"baseUrl": "./",不能省去,否则ts报Option 'paths' cannot be used without specifying '--baseUrl' option.错误

next.js中配置alias也可以参考如上步骤

查看原文

赞 1 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-06-30

ahk键盘增强✨✨✨v1.1

ahk键盘增强✨✨✨更新至v1.1

myahk旨在增强windows下的键盘功能?

首先感谢ahk的大神们,这个工具能极大地增加生产力

ahk的一个键盘增强脚本,仅在winwods下可用,长期更新 仓库链接

2020/6/30日更新

使用了小半年之后发现了一些问题,所以更新了一下

  • [x] 移除了连点器
  • [x] 移除了打开指定文件夹,在开始界面中显然更好用
  • [x] 已关闭默认打开键鼠(开机了之后会忘记关闭蒙蔽半天)
  • [ ] 预计的新特性,按键显示,此功能可以方便做教程

安装

windows执行以下步骤,?复制粘贴到命令行中执行

未安装git和ahk的用户可以在联网状态下使用一行命令安装

Set-ExecutionPolicy Bypass -Scope Process -Force;[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'));choco install git;choco install autohotkey.install;git clone https://gitee.com/moshuying/myAHK.git;cd myAHK;.\easyWork.ahk;New-Item -ItemType SymbolicLink -Path "C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" -Name ".\easyWork.ahk.lnk" -Value ".\easyWork.ahk"

有ahk和git的用户可以自行按步骤安装
ahk下载地址

git clone https://gitee.com/moshuying/myAHK.git;
cd myAHK;
./easyWork.ahk;
New-Item -ItemType SymbolicLink -Path "C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup" -Name ".\easyWork.ahk.lnk" -Value ".\easyWork.ahk"

功能概要

由于用caps + a替换了capslock功能,所以下表中的caps均指向capslock按键

简述热键详解
获取路径win + ctrl + c在文件浏览器下选中文件后直接复制路径
deletecaps + o向后删除,不能作为实体delete键来用,仅仅能向后删除
backspacecaps + p向前删除,就是退格键
appkey ?caps + g就是鼠标右键啦,替代shift + f10的一个方案
homecaps + hhome键,移动到行首
endcaps + nend键,移动到行末(这个结合shift + caps + h可以飞速选中一行,选中后caps + i向上多选,caps + j下下多选)
上下左右 ?caps + ijkl超级好用上下左右,我想你也不喜欢每次移动光标时都把手挪动一大截吧,尤其是写代码灵感来的瞬间
切换大小写caps + a将capslock键改成了caps,用这个组合键来切换大小写
鼠标滚轮增加音量(有鼠标侧键才可以使用,XButon2是靠前的侧键) ?XButton2 + 向鼠标前方滚动
鼠标滚轮减少音量XButton2 + 向鼠标后方滚动
键盘增加音量caps + pgup
键盘减少音量caps + pgdn
打开计算器caps + c
滚动当前鼠标下窗口的滚动条(向下滚动) ?caps + [滚动当前鼠标指向窗口的滚动条
滚动当前鼠标下窗口的滚动条(向上滚动)caps + ]滚动当前鼠标指向窗口的滚动条
桌面切换(下一个)win + ctrl + tab两个项目同时忙起来的时候换虚拟桌面用的
桌面切换(上一个)win + ctrl + shift + tab
模拟鼠标(开) 默认关闭 ?caps + d开启后按d对应左键,f右键,ijkl移动鼠标
模拟鼠标(关)caps + f
括号补全(开) 默认关闭caps + 9在一些代码编辑器内已经默认开启了代码补全,某些输入法也给了括号补全,这个自动补全仅作为备用默认关闭,第一次按组合键打开,再按组合键关闭
括号补全(关)caps + 9
`caps + 168键的键盘打反引号和波浪号稍微费事一点
~caps + 2
=caps + ;
+caps + '
自动循环按键按下ctrl + win + a 后随意按键(功能键暂不支持)自动循环按ctrl + win + a 后的按键

长期更新,觉得有用麻烦点个star吧

查看原文

赞 0 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-06-30

vscode 快捷键大全

vscode 快捷键大全

官方文档

widnows
liunx
mac

挺简单的,文档描述清晰内容排版也不错,一看就懂,这里写的是我自己翻译的(太过简单的没必要翻译),同时也为了方便自己查阅和使用

[注意] 插件的快捷键请在插件说明(文档)内查看,vscode不提供此类快捷键

Visual Studio Code (Keyboard Shortcuts for Windows)

按键说明
General普通
Ctrl+Shift+P,F1 Show Command Palette
Ctrl+PQuick Open, Go to File…
Ctrl+Shift+NNew window/instance
Ctrl+Shift+WClose window/instance
Ctrl+,User Settings
Ctrl+K Ctrl+SKeyboard Shortcuts (显示所有快捷键,太多专业名词调到中文你就懂了)
Basic editing基本编辑
Ctrl+XCut line (empty selection)
Ctrl+CCopy line (empty selection)
Alt+ ↑ / ↓Move line up/down
Shift+Alt + ↓ / ↑Copy line up/down
Ctrl+Shift+KDelete line
Ctrl+EnterInsert line below(在当前输入行的下面插入一行)
Ctrl+Shift+EnterInsert line above(在当前输入行的下面插入一行,试了一下没成功)
Ctrl+Shift+\Jump to matching bracket(跳转到匹配的标签)
Ctrl+] / [Indent/outdent line(缩进取消缩进,注意中间那个][中间的斜杠不需要按)
Home / EndGo to beginning/end of line
Ctrl+HomeGo to beginning of file(跳转至文件开始处)
Ctrl+EndGo to end of file(跳转到文件结尾处)
Ctrl+↑ / ↓Scroll line up/down(滚动一行)
Alt+PgUp / PgDnScroll page up/down(整页滚动)
Ctrl+Shift+[Fold (collapse) region(收起当前代码块)
Ctrl+Shift+]Unfold (uncollapse) region(打开当前代码块)
Ctrl+K Ctrl+[Fold (collapse) all subregions(收起所有代码块)
Ctrl+K Ctrl+]Unfold (uncollapse) all subregions(打开所有代码块)
Ctrl+K Ctrl+0Fold (collapse) all regions(收起所有0级代码块,还有1~9级)
Ctrl+K Ctrl+JUnfold (uncollapse) all regions(打开所有代码块)
Ctrl+K Ctrl+CAdd line comment(添加行注释)
Ctrl+K Ctrl+URemove line comment(删除行注释)
Ctrl+/Toggle line comment(切分编辑窗口)
Shift+Alt+AToggle block comment(添加块级注释)
Alt+ZToggle word wrap(切换自动换行,效果同ctrl+z)
Navigation导航
Ctrl+TShow all Symbols(搜索文件,输入标记搜索文件标记,效果同ctrl+p)
Ctrl+GGo to Line...
Ctrl+PGo to File...
Ctrl+Shift+OGo to Symbol...(ctrl+t的搜索框中输入@)
Ctrl+Shift+MShow Problems panel(打开panel中的问题部分,按ctrl+j打开panel)
F8Go to next error or warning
Shift+F8Go to previous error or warning
Ctrl+Shift+TabNavigate editor group history(切换打开中的窗口)
Alt+ ← / →Go back / forward (整词移动光标)
Ctrl+MToggle Tab moves focus(切换标签移动焦点,无效果)
Search and replace查找和替换
Ctrl+FFind
Ctrl+HReplace
F3 / Shift+F3Find next/previous(在搜索结果中移动焦点)
Alt+EnterSelect all occurences of Find match(选中所有匹配)
Ctrl+DAdd selection to next Find match(选中下一个匹配)
Ctrl+K Ctrl+DMove last selection to next Find match
Alt+C / R / WToggle case-sensitive / regex / whole word(搜索窗口切换大小写,正则,全匹配)
Multi-cursor and selection键鼠多选
Alt+ClickInsert cursor(点选输入位置)
Ctrl+Alt+ ↑ / ↓Insert cursor above / below(脑子进水快捷键,windows下根本用不了)
Ctrl+UUndo last cursor operation(反alt+click)
Shift+Alt+IInsert cursor at end of each line selected
Ctrl+L Selectcurrent line(整行选中)
Ctrl+Shift+LSelect all occurrences of current selection(选中当前选中的所有匹配)
Ctrl+F2 Selectall occurrences of current word(选中当前单词的所有匹配)
Shift+Alt+→Expand selection(扩大选择,效果不如单词选择或者整行选择)
Shift+Alt+←Shrink selection(缩小选择)
Shift+Alt +(drag mouse)Column (box) selection(按住shift+alt然后鼠标左键点住拖动,点到那选到那)
Ctrl+Shift+Alt + (arrow key)Column (box) selection(就近选择当前光标位置)
Ctrl+Shift+Alt+PgUp/PgDnColumn (box) selection page up/down(就近选择一页)
Rich languages editing丰富语言编辑器
Ctrl+SpaceTrigger suggestion(触发建议)
Ctrl+Shift+SpaceTrigger parameter hints(触发参数提示)
Shift+Alt+FFormat document
Ctrl+K Ctrl+FFormat selection(格式化选定内容)
F12Go to Definition
Alt+F12Peek Definition(查看定义)
Ctrl+K F12Open Definition to the side
Ctrl+.Quick Fix
Shift+F12Show References(转到引用)
F2Rename Symbol(重命名符号)
Ctrl+K Ctrl+XTrim trailing whitespace(裁剪尾随空格)
Ctrl+K MChange file language(切换文件语言)
Editor management编辑器管理
Ctrl+F4, Ctrl+WClose editor
Ctrl+K FClose folder(关闭窗口回到初始界面)
Ctrl+\Split editor
Ctrl+ 1 / 2 / 3Focus into 1st, 2nd or 3rd editor group
Ctrl+K Ctrl+ ←/→Focus into previous/next editor group
Ctrl+Shift+PgUp / PgDnMove editor left/right(向左/右移动编辑区)
Ctrl+K ← / →Move active editor group(向左/右移动编辑器组)
File management文件管理
Ctrl+NNew File
Ctrl+OOpen File...
Ctrl+SSave
Ctrl+Shift+SSave As...
Ctrl+K SSave All
Ctrl+F4Close
Ctrl+K Ctrl+WClose All
Ctrl+Shift+TReopen closed editor
Ctrl+KEnter Keep preview mode editor open
Ctrl+TabOpen next
Ctrl+Shift+TabOpen previous
Ctrl+K PCopy path of active file
Ctrl+K RReveal active file in Explorer
Ctrl+K OShow active file in new window/instance(当前文件在新窗口中打开)
Display显示
F11Toggle full screen
Shift+Alt+0Toggle editor layout (horizontal/vertical)(垂直或水平布局)
Ctrl+ = / -Zoom in/out (缩放)
Ctrl+BToggle Sidebar visibility
Ctrl+Shift+EShow Explorer / Toggle focus
Ctrl+Shift+FShow Search
Ctrl+Shift+GShow Source Control
Ctrl+Shift+DShow Debug
Ctrl+Shift+XShow Extensions
Ctrl+Shift+HReplace in files(侧边替换栏)
Ctrl+Shift+JToggle Search details
Ctrl+Shift+UShow Output panel
Ctrl+Shift+VOpen Markdown preview
Ctrl+K VOpen Markdown preview to the side
Ctrl+K ZZen Mode (Esc Esc to exit)
Debug调试
F9Toggle breakpoint
F5Start/Continue
Shift+F5Stop
F11 / Shift+F11Step into/out
F10Step over
Ctrl+K Ctrl+IShow hover
Integrated terminal集成终端
Ctrl+`Show integrated terminal
Ctrl+Shift+`Create new terminal
Ctrl+CCopy selection
Ctrl+VPaste into active terminal
Ctrl+↑ / ↓Scroll up/down
Shift+PgUp / PgDnScroll page up/down
Ctrl+Home / EndScroll to top/bottom

[Other operating systems’ keyboard shortcuts and additional unassigned shortcuts available at aka.ms/vscodekeybinding]
一个前端开发者的笔记

查看原文

赞 0 收藏 0 评论 0

墨抒颖 发布了文章 · 2020-02-02

windows下的效率神器 AutoHotKey(使用一年后表示非常好用)

ahk键盘增强✨✨✨

ahk的一个键盘增强脚本,仅在winwods下可用,长期更新
仓库链接

首先感谢ahk的大神们,这个工具能极大地增加生产力

功能简介

myahk旨在增强windows下的键盘功能😎

使用流程

windows执行以下步骤,💻复制粘贴到命令行中执行

国内用户把clone仓库链接中的hub换成ee即可,两个仓库完全同步
git clone https://github.com/moshuying/myAHK.git
# git clone https://gitee.com/moshuying/myAHK.git
cd myAHK
AutoHotkey39219
easyWork.ahk

功能概要

由于用caps + a替换了capslock功能,所以下表中的caps均指向capslock按键

简述热键详解
获取路径win + ctrl + c在文件浏览器下选中文件后直接复制路径
deletecaps + o向后删除,不能作为实体delete键来用,仅仅能向后删除
backspacecaps + p向前删除,就是退格键
appkey 🍥caps + g就是鼠标右键啦,替代shift + f10的一个方案
homecaps + hhome键,移动到行首
endcaps + nend键,移动到行末(这个结合shift + caps + h可以飞速选中一行,选中后caps + i向上多选,caps + j下下多选)
上下左右 👏caps + ijkl超级好用上下左右,我想你也不喜欢每次移动光标时都把手挪动一大截吧,尤其是写代码灵感来的瞬间
切换大小写caps + a将capslock键改成了caps,用这个组合键来切换大小写
鼠标滚轮增加音量(有鼠标侧键才可以使用,XButon2是靠前的侧键) 🥩XButton2 + 向鼠标前方滚动
鼠标滚轮减少音量XButton2 + 向鼠标后方滚动
键盘增加音量caps + pgup
键盘减少音量caps + pgdn
打开计算器caps + c
滚动当前鼠标下窗口的滚动条(向下滚动) 🍧caps + [滚动当前鼠标指向窗口的滚动条
滚动当前鼠标下窗口的滚动条(向上滚动)caps + ]滚动当前鼠标指向窗口的滚动条
桌面切换(下一个)win + ctrl + tab两个项目同时忙起来的时候换虚拟桌面用的
桌面切换(上一个)win + ctrl + shift + tab
模拟鼠标(开) 默认开启 🌭caps + d开启后按d对应左键,f右键,ijkl移动鼠标
模拟鼠标(关)caps + f
括号补全(开) 默认关闭caps + 9在一些代码编辑器内已经默认开启了代码补全,某些输入法也给了括号补全,这个自动补全仅作为备用默认关闭,第一次按组合键打开,再按组合键关闭
括号补全(关)caps + 9
`caps + 168键的键盘打反引号和波浪号稍微费事一点
~caps + 2
=caps + ;
+caps + '
关闭窗口shift + esc等同于alt + f4

长期更新,欢迎各路大神提issue

查看原文

赞 0 收藏 0 评论 0

墨抒颖 收藏了文章 · 2020-02-02

git 高级用法小抄

如果你觉得 git 很迷惑人,那么这份小抄正是为你准备的!请注意我有意跳过了 git commitgit pull/push 之类的基本命令,这份小抄的主题是 git 的一些「高级」用法。

导航 —— 跳到之前的分支

git checkout -

查看历史

# 每个提交在一行内显示
git log --oneline

# 在所有提交日志中搜索包含「homepage」的提交
git log --all --grep='homepage'

# 获取某人的提交日志 
git log --author="Maxence"

哎呀:之前重置了一个不想保留的提交,但是现在又想要回滚?

# 获取所有操作历史
git reflog

# 重置到相应提交
git reset HEAD@{4}
# ……或者……
git reset --hard <提交的哈希值>

详见我的另一篇文章 What's happens when you git commit

哎哟:我把本地仓库搞得一团糟,应该怎么清理?

git fetch origin
git checkout master
git reset --hard origin/master

查看我的分支和 master 的不同

git diff master..my-branch

定制提交

# 编辑上次提交
git commit --amend -m "更好的提交日志"

# 在上次提交中附加一些内容,保持提交日志不变git add . && git commit --amend --no-edit

# 空提交 —— 可以用来重新触发 CI 构建
git commit --allow-empty -m "chore: re-trigger build"

如果你不知道该怎么写提交日志,可以看我写的这篇介绍 Angular 风格的提交日志惯例的文章

squash 提交

比方说我想要 rebase 最近 3 个提交:

  • git rebase -i HEAD~3
  • 保留第一行的 pick,剩余提交替换为 squash 或 s
  • 清理提交日志并保存(vi 编辑器中键入 :wq 即可保存)
pick 64d26a1 feat: add index.js
s 45f0259 fix: update index.js
s 8b15b0a fix: typo in index.js

修正

比方说想在提交 fed14a4c 加上一些内容。

git 提交分支

git 提交分支

git add .
git commit --fixup HEAD~1
# 或者也可以用提交的哈希值(fed14a4c)替换 HEAD~1

git rebase -i HEAD~3 --autosquash
# 保存并退出文件(VI 中输入 `:wq`)

rebase 的时候在每个提交上执行命令

如果特性很多,一个分支里可能有多个提交。如果测试失败了,你希望能找到导致测试失败的提交。这时候你可以使用 rebase --exec 命令在每个提交上执行命令。

# 在最近 3 个提交上运行 `npm test` 命令
git rebase HEAD~3 --exec "npm test"

 

暂存

暂存不止是 git stashgit stash pop ;)

# 保存所有正在追踪的文件
git stash save "日志信息"

# 列出所有的暂存项
git stash list

# 获取并删除暂存项
git stash apply stash@{1}
git stash drop stash@{1}
# ……或使用一条命令……
git stash pop stash@{1}

清理

# 移除远程仓库上不存在的分支
git fetch -p

# 移除所有包含 `greenkeeper` 的分支
git fetch -p && git branch --remote | fgrep greenkeeper | sed 's/^.\{9\}//' | xargs git push origin --delete

GitHub = Git + Hub

我把 Hub 当成 git 的一个封装来用。你如果也想这么做,可以设置一个别名:alias git='hub'

# 打开浏览器访问仓库 url(仅限 GitHub 仓库)git browse

其他命令可以参考这里

额外福利:我最喜爱的 git 别名

alias g='git'
alias glog='git log --oneline --decorate --graph'
alias gst='git status'
alias gp='git push'
alias ga='git add'alias gc='git commit -v'

# 🤘
alias yolo='git push --force'

# 每周站会汇报工作时用
git-standup() {
    AUTHOR=${AUTHOR:="`git config user.name`"}

    since=yesterday
    if [[ $(date +%u) == 1 ]] ; then
        since="2 days ago"
    fi

    git log --all --since "$since" --oneline --author="$AUTHOR"
}

你最喜欢的 git 命令是哪个呢?

感谢花时间阅读本文。我希望你觉得这篇文章有所帮助!

原文作者:Maxence Poutord ,内容经授权转载自 New Frontend 网站。
查看原文

墨抒颖 发布了文章 · 2020-01-16

vue超简单加载字体方法,解决scss难加载字体的问题

vue超简单加载字体方法,解决scss难加载字体的问题

scss在加载字体方面一直不太好用,需要繁杂的配置才能达到想要的效果,这里说一种非常简单的方法

App.vuestyle标签下引入字体文件后,scss设置的字体依旧可以正确识别,注意style的lang不要写,就使用原生css

示例引入

<style>
@font-face{
    font-family: pingfang;
    src: url('./style/pingfang.ttf')
}
</style>

然后想要的位置设置font-family为pingfang即可,自己定义别的名字也可以

查看原文

赞 0 收藏 0 评论 0

认证与成就

  • 获得 22 次点赞
  • 获得 2 枚徽章 获得 0 枚金徽章, 获得 0 枚银徽章, 获得 2 枚铜徽章

擅长技能
编辑

开源项目 & 著作
编辑

  • npmEnv

    各种node下的开发环境,也包括一个js解释器

  • ddinit

    钉钉数据获取模块

注册于 2019-11-05
个人主页被 1.3k 人浏览