SunXinFei / sunxinfei.github.io

前后端技术相关笔记,已迁移到 Issues 中
https://github.com/SunXinFei/sunxinfei.github.io/issues
32 stars 3 forks source link

比较水的一些问题总结 #3

Open SunXinFei opened 6 years ago

SunXinFei commented 6 years ago

获取url中的?号后的参数

export const getQueryString = (name) => {
  let regData = location.href.match(`(${name}=)(\\d+)`);
  let queryId = regData && regData[2] || '';
  return queryId;
} 

防抖与截流

/**
 * 防抖
 * @param {Function} fn 需要延迟运行的的回调函数
 **/
export const debounce = (fun,delay) => {
  return function (args) {
    let that = this
    let _args = args
    clearTimeout(fun.id)
    fun.id = setTimeout(function () {
        fun.call(that, _args)
    }, delay)
  }
}
/**
上面代码可以用箭头函数省略为
*/
export const debounce = (fun,delay) => {
  return function (args) {
    clearTimeout(fun.id)
    fun.id = setTimeout(()=>{
        fun.call(this, args)
    }, delay)
  }
}
//调用地方
    /**
     * 处理滚动视图的滚动事件
     */
    scrollFn(e) {
      debounce(this.aaa, 1000)(666);
    },
   aaa(num){
      console.log(this.test,num);
    },
//截流
/**
 * 连续的方法 延迟,如持续输入数据,搜索
 * @param {Function} fn 需要延迟运行的的回调函数
 **/
let previous = 0
export const throttle = (fn,delay) => {
    return function() {
        let now = +new Date();
        if (now - previous > delay) {
          fn.apply(this, arguments);
          previous = now;
        }
    }
}
//调用地方
    /**
     * 处理滚动视图的滚动事件
     */
    scrollFn(e) {
      throttle(this.aaa, 1000)(666);
    },
   aaa(num){
      console.log(this.test,num);
    },

关于防抖(debounce) :在事件触发后的n秒之后,再去执行真正需要执行的函数,如果在这n秒之内事件又被触发,则重新开始计时。常见的操作就是搜索,中间不断的输入,我们都可以忽略,只获取最后停止输入的时候,才去请求后端。。 节流(throttling):规定好一个单位时间,触发函数一次。如果在这个单位时间内触发多次函数的话,只有一次是可被执行的。想执行多次的话,只能等到下一个周期里。常见的操作比如滚动事件,每隔n毫秒,我们去请求,或者拖拽,每隔n毫秒改变dom的位置。还比如resize窗口。 参考:

https://github.com/Advanced-Frontend/Daily-Interview-Question/issues/5 https://github.com/mqyqingfeng/Blog/issues/26


el.dataset

el.dataset可以获取DOM元素中绑定的data-的属性值,比如

<div :data-index="index">
</div>

el.dataset-index 即为index的值


JavaScript中 ‘+’ 号

有时阅读源码,会在代码中看到在某个元素前使用 ‘+’ 号,这个操作是将该元素转为Number类型,如果转换失败,那么将得到 NaN。

所以 +new Date 将会调用 Date.prototype 上的 valueOf 方法,而根据 MDN ,Date.prototype.value 方法等同于 Date.prototype.getTime()。所以一下代码效果相同:

console.log(+new Date);
console.log(Number(new Date));
console.log(new Date().getTime());
console.log(new Date().valueOf());
console.log(new Date() * 1);

JS中的'~'号

~是位非运算符, ~-1 === 0 表示true; 所以这个符号常用来搭配 indexOf 方法一起使用,比如:

let aaa = 'abcd';
aaa.indexOf('b') === -1; //false 表示aaa中存在b字符
//
Boolean(~aaa.indexOf('b')) // 非零, 即为true,表示aaa中存在b

Cannot read property 'forEach' of null/undefined

??有效的防止属性的值如果为空字符串或false或0

//等价的写法
const aaa = [1];
(aaa || []).forEach((a) => {
    console.log('aaa', a)
});
aaa?.forEach((a) => {
    console.log('aaa', a)
});

const bbb = null;
(bbb || []).forEach((a) => {
    console.log('bbb', a)
});
bbb?.forEach((a) => {
    console.log('bbb', a)
});

let ccc;
(ccc || []).forEach((a) => {
    console.log('ccc', a)
});
ccc?.forEach((a) => {
    console.log('ccc', a)
});

//一致的结果
let ddd;
console.log('ddd', Object.keys(ddd || [1, 2])); //["0", "1"]
console.log('ddd', Object.keys(ddd ?? [1, 2])); //["0", "1"]

const ggg = null;
console.log('ggg', Object.keys(ggg || [1, 2])); //["0", "1"]
console.log('ggg', Object.keys(ggg ?? [1, 2])); //["0", "1"]

//不一致的结果
const eee = false;
console.log('eee', Object.keys(eee || [1, 2])); //["0", "1"]
console.log('eee', Object.keys(eee ?? [1, 2])); //[]

const fff = 0;
console.log('fff', Object.keys(fff || [1, 2])); //["0", "1"]
console.log('fff', Object.keys(fff ?? [1, 2])); //[]

const hhh = "";
console.log('hhh', Object.keys(hhh || [1, 2])); //["0", "1"]
console.log('hhh', Object.keys(hhh ?? [1, 2])); //[]
}

箭头函数

箭头函数的this其实就是包裹它的第一个非箭头函数的函数的this值。因为箭头函数内部没有this。 如果对一些函数比如类内部指向有疑问,Babel转ECMA5看下即可清晰看出箭头函数内this指向。

构造函数

在JavaScript构造函数中:如果return值类型,那么对构造函数没有影响,实例化对象返回对象;如果return引用类型(数组,函数,对象),那么实例化对象就会返回该引用类型;

SunXinFei commented 6 years ago

webpack中的path和publicPath的区别

webpack的output下面有两个路径,一个path,一个是publicPath,其实区别还是很大的,首先path这个不需要特别多的解释,就是编译输出的项目路径,如下图所示。但是实际放置到服务器中,不一定是服务器的根目录下的dist文件夹,有可能是放置在服务器的wwww文件夹下面,这时候就需要我们设置下publicPath文件夹的输出路径。

output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),//项目输出到根目录下面的dist文件夹中,html中的路径显示为src="app.bundle.js"
    publicPath:'/wwww/' //指定的外层目录,html中的路径显示为 src="/wwww/app.bundle.js"
  },
SunXinFei commented 6 years ago

如何生成博客或文档中的目录结构树

平时在写readme.md的时候,可能会使用树状的目录结构,比如

|--
    |-- .gitignore
    |-- package.json
    |-- README.md
    |-- webpack.common.js
    |-- webpack.dev.js
    |-- webpack.prod.js
    |-- prod-dist
    |   |-- index.html
    |   |-- component1
    |   |   |-- index.5a006a90.js
    |   |   |-- index.5a006a90.js.map
    |   |-- component2
    |       |-- index.5a006a90.js
    |       |-- index.5a006a90.js.map
    |-- src
        |-- platform-templete
        |   |-- index.html
        |-- platform-widgets
            |-- component1
            |   |-- index.js
            |   |-- style.css
            |-- component2
                |-- index.js
                |-- style.css
SunXinFei commented 6 years ago

安装在本地的node_modules中的模块怎么运行

比如npm install -g hexo会放置到全局的变量,这种情况下,在命令行里可以直接执行hexo -v这样的命令,但是如果只是运行npm install hexo会安装到当前项目的node_modules文件夹当中,这种情况下需要这么运行node_modules/.bin/hexo -v即可,就是说node_modules/.bin/模块名


快速删除node_modules文件夹

安装npm install rimraf -g 运行rimraf node_modules

SunXinFei commented 6 years ago

Terminal

快速移动光标

  1. 向前移动一个单词:ESC+f
  2. 向后移动一个单词:ESC+b
  3. 移动光标到行首:control+a
  4. 移动光标到行尾:control+e

    vim常用快捷键

    i: 插入光标前一个字符 
    I: 插入行首 
    a: 插入光标后一个字符 
    A: 插入行未 
    o: 向下新开一行,插入行首 
    O: 向上新开一行,插入行首

常用命令

df -lh显示本地文件系统信息 du -h --max-depth=1查看文件夹下一层目录 体积

cmd数据库连接

mysql -u用户名 -p密码 -h远程数据库IP地址 -P端口 -D数据库名

mac 修改host

sudo vi /private/etc/hosts 输入o进入编辑状态; esc退出编辑,:wq 保存 , :q 退出


nginx命令

停止服务:nginx -s stop 启动服务:nginx 重启服务:进入nginx可执行目录sbin下,输入命令./nginx -s reload即可 重启服务:nginx -s reload 查看nginx配置文件目录:open /usr/local/etc/nginx/ 查看nginx被安装到的目录:open /usr/local/Cellar/nginx 测试nginx配置:nginx -t 查看端口占用情况:lsof -i:端口号 查看nginx进程:ps -ef|grep nginx 杀死nginx进程:kill -QUIT 进程号

启动NFS服务

sudo /etc/init.d/nfs-kernel-server start sudo /etc/init.d/nfs-kernel-server restart


PHP 修改代码之后,页面不改变

这个跟php.ini中开启了opcache有关系,可以避免反复编译带来的性能消耗。所以开发状态下关闭即可,但是修改完ini文件之后,记得重启php-fpm和nginx


tar 压缩命令

tar -cvf  MyCard.tar   ./vue-webpack-demo/src/pages/Home/components/MyCard/

Ubuntu创建映射

sudo ln -s  /data0/tui/CMS/storage/app/public   /data0/tui/CMS/public/storage

修改pac.txt, ss 自定义规则书写

自定义代理规则的设置语法规则如下,记得重启:


下载m3u8直播流的视频

  1. 首先安装ffmpeg环境,windows系统下载安装包,配置全局的Path,
  2. 运行该命令即可
ffmpeg -i http://play2.kandian.360.cn/vod_xinwen/vod-media/1160007_3029687_20160725140508.m3u8 "文件名.mp4"
SunXinFei commented 6 years ago

使用flex实现左侧文字自适应,右侧文字长度省略号

需求:在一行中有两段文字,左侧是昵称,右侧为评论,昵称正常展示,右侧评论吃掉剩余长度,超出就省略号 image

<div class="card-comment">
    <div class="nickname">
      <div class="nickname-ellipsis">{{comment.nickname}}</view>
    </div>
    <div class="comment">{{comment.comment}}</view>
  </div>
.card-comment {
  font-size: 0.26rem;
  font-family: PingFang-SC-Regular ;
  display: flex;
  overflow: hidden;
  padding: 0 0.3rem;
}
.card-comment .nickname {
  color: #000000;
  max-width: 5rem;
}
.card-comment .nickname-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.card-comment .comment {
  color: #999999;
  margin-left: 0.2rem;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 2rem;
}

css动画抖动

解决在使用animation动画时,页面出现抖动的问题 给使用动画的元素加上-webkit-backface-visibility: hidden;

css优先级

优先级: !important > 内联样式 > ID选择器 > 类选择器 = 伪类选择器 = 属性选择器 > 标签 > 通配符 > 继承 > 浏览器默认属性

flex:1 导致子元素overflow: hidden; text-overflow: ellipsis;失效的问题

解决方案:将flex:1元素设置overflow: hidden;或者min-width: 0;即可,这里注意一点 如果是flex:1元素N层的嵌套,那么这N层flex:1元素都需要设置。

font-size:0

display:inline-block的元素之间会有一个字符的间隙,这个间隙导致了最后一个会掉下来。 解决方法: 1、给父元素设置font-size:0;


IE10中flex导致文本不换行

<div class="title">
    <span>用户表测试_动态汇总</span>
     <label>某个checkbox</label>
</div>

这个要实现span和label的flex布局,然后space-between,在火狐和Chrome和IE11中可以完美显示,只要加上如下代码:

.title {
   display: flex;
   justify-content: space-between;
}

但是在IE10中会出现span中文本过长但不折行的现象。 解决方案stackoverflow连接并且其他浏览器不受影响

span{
   display: block;
   max-width: 100%;
   flex-shrink: 1;
}

CSS垂直水平居中

1.使用flex

.box {//外层元素
display: flex;
align-items: center; //垂直居中
justify-content: center;//水平居中
}

2.还有一种外层flex,内层margin:auto

.box {//外层元素
width: 200px;
height: 200px;
display: flex;
}
.center {//内层元素
width: 100px;
height: 100px;
margin: auto;
}

3.绝对定位(不需知道内层/外层元素的宽和高)

.center {//内层
position:absolute; 
left:50%; 
top:50%; 
transform: translate(-50%,-50%); 
}

4.绝对定位(不需知道内层/外层元素的宽和高,需设置内层的宽高)

.box {//外层
width: 200px;
height: 200px;
    background:#fff;
    position:relative
}
.center{//内层
width:100px; 
height:100px; 
left:0; 
top: 0; 
bottom: 0; 
right: 0;
margin: auto;
position:absolute;
    background:#000;
 }

5.绝对定位(需知道内层的宽高)

.center{ //内层
width:100px; 
height:100px; 
position: absolute; 
left: 50%; 
top:50%; 
margin-left:-50px; //内层元素的一半
margin-top: -50px; 
}

6.绝对定位(需要知道外层/内层元素宽和高)

.center {//内层
position: absolute;
width: 100px;
height: 100px;
left: 50px;//外层元素一半减去center元素一半
top: 50px;
}

CSS中z-index不起作用

这种情况发生的条件有三个: 1、父标签 position属性为relative; 2、问题标签无position属性(不包括static); 3、问题标签含有浮动(float)属性。


less中calc计算异常问题

.flow-node-modal .ivu-modal {
  @marginVal : 20px;  //这里使用了变量
  margin: @marginVal;
  top:0;
  .ivu-modal-content {
    height: calc(~"100vh - "@marginVal*2); //注意!,这里的写法,一般的写法less解析calc会有问题
  }
}

sass的写法为:

height: calc(100vh - #{$marginVal*2}); //注意!,这里的写法,一般的写法sass解析calc会有问题

关于text-align:center和vertical-align:middle

text-align具有继承性,给祖先元素添加,即可实现内部行内元素的水平居中; vertical-align属性只对行内元素有效,给需要垂直居中的内容元素添加,父级元素需要添加line-height,如果内容元素只有一个,可以不添加vertical-align:middle也可以垂直居中。 块级元素,给定宽度使用margin:0 auto,水平居中,

css中的transition与animation

拜读了大漠的两篇文章写得还是非常系统的: Vue 2.0学习笔记:Vue的transition Vue 2.0学习笔记:Vue的animation

实现卡片自适应布局

一种常见需求:有n个宽度相同的卡片,需要间距相等,从左到右铺满内容区域,直接用flex的space-between会导致,不满一行的数量卡片,布局异常。 解决方案:用N个空元素占位 image

  /**
   * 填充N个空dom,来解决flex中space-between布局的问题,
   * 宽度为卡片宽度,N为填满一行的数量
   * @returns
   */
  const getEmptyDom = () => {
    let emptyFiles = []
    for (let i = 0; i < EmptyFilesLength; i++) {
      emptyFiles.push(
        <div key={i} className={styles.flexEmpty} />
      )
    }
    return emptyFiles
  }
<div className={styles.cardContent}>
        <Card size='small' bordered={false} title='Inner Card title' className={styles.innerCard} >
            Inner Card content
        </Card>
        <Card size='small' bordered={false} title='Inner Card title' className={styles.innerCard}>
            Inner Card content
        </Card>
        {
          // 填充N个空dom,来解决flex中space-between布局的问题
          getEmptyDom()
        }
      </div>
.cardContent{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    align-content: flex-start;
    .flexEmpty{
      width: 33%;
      border: 1px solid transparent;
      margin: 0;
      visibility: hidden;
      height: 0 !important;
    }
    .innerCard{
        width: 33%;
        margin-bottom: 10px;
      }
  }
SunXinFei commented 5 years ago

window.on与addevent区别

    window.addEventListener('click', ()=>{
        console.log(1)
    }
    )
    window.addEventListener('click', ()=>{
        console.log(2)
    }
    )
    window.onclick = ()=>{
        console.log(3)
    }
    window.onclick = ()=>{
        console.log(4)
    }
window.click();//1 2 4

简而言之,on会进行覆盖,而addEventListener会进行无限次添加,不会覆盖。

var a = [{id:1,name:1},{id:2,name:2},{id:3,name:4}];
var result = a.find(function(a,b,c){
    if(a.id == 3){
        return a;
    }
});
console.info(result);

result = a.filter(function(a, b, c){
    if(a.id == 2){
        return a;
    }
});
console.info(result[0]);

a.forEach(function(a, b, c){
    if(a.id == 3){
        result = a;
        return;
    }
});

console.info(result);

a.map(function(a,b,c){
    if(a.id == 2){
        result = a;
        return;
    }
});
console.log(result);

a.some(function(a){
    if(a.id == 3){
        result = a;
        return;
    }
});

console.log(result);

var b = a.entries(),
    c;
while (!(c = b.next()).done) {
    if (c.id == 3) {
        result = c;
        break;
    }
}
console.log(result);
SunXinFei commented 5 years ago

git SSH配置

1.首先查看ssh是否存在

$ cd ~/.ssh
$ ls

看一下有没有id_rsa和id_rsa.pub(或者是id_dsa和id_dsa.pub之类成对的文件),有 .pub 后缀的文件就是公钥,另一个文件则是密钥。 2.命令创建ssh密钥 ssh-keygen -t rsa -C "your_email@youremail.com" 2.1 如果需要创建不同的ssh,那么中间一步需要输入自己想要的路径地址,而不是直接回车 3.查看密钥 cat ~/.ssh/id_rsa.pub 4.将密钥复制粘贴到网站对应位置即可


git 配置多个本地SSH

ssh-keygen -t rsa -C "YOUR_EMAIL@YOUREMAIL.COM" -f ~/.ssh/zidingyi

运行命令创建config文件

vim ~/.ssh/config

根据项目进行配置

# default                                                                       
Host git
HostName domain.com
User xinfei
IdentityFile ~/.ssh/id_rsa
# two                                                                           
Host github
HostName github.com
User xinfei
IdentityFile ~/.ssh/id_rsa_github

测试是否成功

ssh -T git@github.com

git放弃当前工作区更改

放弃所有更改:git checkout . 放弃某个文件:git checkout -- filename


git项目上传至两个git工程中

git remote add origin2别名 git@github.com:xxxxxx.git git push origin2别名 master 如果添加-u的参数,则会将该服务地址为默认push地址


在本地新建分支并推送到远程

git checkout -b test git push origin test 这样远程仓库中也就创建了一个test分支

git常用的分支命令

git branch -r       #查看远程所有分支

git branch           #查看本地所有分支

git branch -a       #查看本地及远程的所有分支,如下图

git fetch   #将某个远程主机的更新,全部取回本地:

git checkout 分支 #切换分支:

git push origin -d 分支名  #删除远程分支: 

git branch -d 分支名  #删除本地分支

git remote show origin  #查看远程分支和本地分支的对应关系

git remote prune origin #删除远程已经删除过的分支

git clone giturl 项目名称 # git clone 不包含外层文件夹

git 命令别名

# 设置
 git config --global alias.gb "branch --show-current"
# 使用
 git gb
#设置
 git config --global alias.cm "commit -m"
# 使用
git cm 'fix: 123'
# 设置
 git config --global alias.c- "checkout -"
#使用
git c-

git撤销push后的代码

第一步: git log --pretty=oneline   查看当前提交的日志 第二步: git reset --soft XXX   XXX是commitID(d6cdbba417....) 回退当前工作空间的上一个版本,并且保留代码更改 第三步: git log --pretty=oneline   再次查看当前提交的日志,确认是否成功撤销,当然,你也可以不看,基本上都会成功,保险一下,看看呗 第四步: git push origin BranchName --force   强制提交当前版本号,以达到撤销版本号的目的.必须添加参数force进行强制提交,否则会 ## git撤销merge(注意 ,可能会导致本地某个分支,覆盖另一个分支 第一步 git reflog 查看提交日志 第二步 git reset --hard 【merge前的版本号】

重置你的本地分支以匹配远程分支

git reset --hard origin/main 这个命令会将你的本地main分支重置为远程仓库origin上的main分支的状态。--hard选项会使你的工作目录中的文件匹配远程分支的状态,这意味着所有本地的更改和提交都会被丢弃。

SunXinFei commented 5 years ago

npm install的异常错误Unexpected end of JSON input while parsing near ' :

总结下来,多为网络环境导致的一些包依赖并没有下载成功,真正解决方案为: 1.删除npm cache

  1. 删除本项目的node_modules
  2. 切换一个网络环境,或者连接手机的4G网络共享
SunXinFei commented 5 years ago

chrome 调试console点开时数据不对value below was evaluated just now

错误:console控制台输出会有惰性问题,在查看对象、数组这种引用型变量时,会出现控制台输出与运行时的值不正确的问题 解决方法:使用console.log(JSON.stringify(obj))或者alert 参考依据:Is Chrome's JavaScript console lazy about evaluating arrays? eg:

var s = ["hi"];
console.log(s);
s[0] = "bye";
console.log(s);

将以上语句在console控制台输出,会发现展开之后不同的结果,原因大致为控制台输出的堆区对应的地址的数据,会导致引用类型的变量,在展开的时候会出现执行后的值,如图: image

SunXinFei commented 5 years ago

iView按需加载以及iview is not defined

按照官网的配置babel

npm install babel-plugin-import --save-dev

{
  "plugins": ["transform-vue-jsx", "transform-runtime",["import", {
    "libraryName": "iview",
    "libraryDirectory": "src/components"
  }]]
}

注意main.js修改如下,不然会有iview is not defined的错误信息:

import Vue from 'vue';
import VueRouter from 'vue-router';
import App from 'components/app.vue';
import Routers from './router.js';
// import iView from 'iview'; <=注释掉
import 'iview/dist/styles/iview.css'; //<=保留

Vue.use(VueRouter);
// Vue.use(iView);<=注释掉
//<=在此页面增加或Vue页面中添加均可
import {Input,Dropdown } from 'iview';
Vue.component('Input', Input);
//<=增加
// The routing configuration
const RouterConfig = {
    routes: Routers
};
const router = new VueRouter(RouterConfig);

new Vue({
    el: '#app',
    router: router,
    render: h => h(App)
});

image

iview按需加载之前后比较,明显降低 image


vue懒加载

参照文档为官方vue-router教程

  1. 首先为了方便我们直观的查看打包文件我们安装webpack-bundle-analyzer插件,
    npm install webpack-bundle-analyzer --save-dev

    在webpack的dev配置文件中配置一下即可

    • 添加以下代码
      const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
      plugins: [
      new BundleAnalyzerPlugin(),
      ]

      然后npm run dev即可看到效果。 image 注意我箭头指示的地方,名称不同的原因即为vue-router中的映射代码,特殊注释命名

      const Project = () => import( '@/components/Project')
      const Flow = () => import(/* webpackChunkName: "flow" */ '@/components/Flow')

      这样,我们可以通过该工具来分析哪个文件是最大的来有目的的优化 !!注意,如果没有在entry中指定,那么chunkName会等于chunkId,即为0.chunckhash.js 懒加载配置完,对比明显 image

SunXinFei commented 5 years ago

路径中的无斜线 与 ./ 与 / 的区别

<script type="text/javascript" src="js/test0.js"></script> 
<script type="text/javascript" src="./js/test1.js"></script>
<script type="text/javascript" src="/js/test2.js"></script>

假如index.html在template文件夹下的话,访问index.html为127.0.0.1:80/template/index.html test0和test1都表示index.html所在的当前文件夹下,即为127.0.0.1:80/template/js/test0.js 而test2表示服务根目录下的js文件夹,即为127.0.0.1:80/js/test2.js

SunXinFei commented 5 years ago

使用fiddler监听Https和手持端请求

  1. 打开fiddler配置Tools –> Fiddler Options.
  2. 打开HTTPS配置项,勾选“CaptureHTTPS CONNECTs”,同时勾选“Decrypt HTTPS traffic”,弹出的对话框选择是(这里是按照fiddler自己的证书)如果跟我一样手机跟电脑是用wifi进行链接的话还需要选择“…fromremote clients only”。如果需要监听不可信的证书的HTTPS请求的话,需要勾选“Ignore servercertificate errors”。
  3. 打开Conections配置项, 这里可以修改Fiddler代理端口号。勾选“Allow remote computersto connect。提示需要重启fiddler。

    charles抓包安卓和笔记本

    • 手机输入网址http://charlesproxy.com/getssl,下载并安装
    • 电脑需要将charles证书设置为信任 image
SunXinFei commented 5 years ago

关于webpack下,本地IP无法访问localhost项目的问题

解决方案:在package.json中的dev指令中加入--host 0.0.0.0即可 webpack-dev-server --host 0.0.0.0 参考文献-github 注意: 如果修改webpack的config的文件修改host均不起作用,或会导致ip写死,本地127.0.0.1无法正常访问


nodejs 获取本机IP

function getIPAdress(){  
  var interfaces = require('os').networkInterfaces();  
  for(var devName in interfaces){  
        var iface = interfaces[devName];  
        for(var i=0;i<iface.length;i++){  
             var alias = iface[i];  
             if(alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal){  
                   return alias.address;  
             }  
        }  
  }  
} 
SunXinFei commented 5 years ago

echarts 绑定click事件

//this.inventoryChart为echarts实例
//this.option 为echats实例的配置项
//给本页面的echart添加click事件
    bindEventForChart() {
      //获取echats的canvas区域,并绑定click事件
      this.inventoryChart.getZr().on("click", params => {
        const pointInPixel = [params.offsetX, params.offsetY];

        if (this.inventoryChart.containPixel("grid", pointInPixel)) {
          //将点击区域的横轴像素值转化成x轴index
          let xIndex = this.inventoryChart.convertFromPixel(
            { seriesIndex: 0 },
            [params.offsetX, params.offsetY]
          )[0];
         //将x轴坐标index,转化成对应像素值
         let offsetX = this.inventoryChart.convertToPixel(
            { xAxisIndex: 0 },
            this.option.xAxis.data[xIndex].value
          );
          //处理点击事件的逻辑
          this.handleEchartClickEvent(xIndex, offsetX);
        }
      });
    },
SunXinFei commented 5 years ago

think php中打印sql语句的方法

echo M('explorer_class')->getLastSql();

SunXinFei commented 5 years ago

使用命令行 快速启动vscode 打开项目

方法有很多可以搜下,这里说一种比较简单的命令:

  1. 首先在vscode中进行命令注册,即在VSCode 中 打开 Command+Shift + P 输入 Shell command,选择 image
  2. 在终端进入想打开的项目文件夹,输入 code . 即可
SunXinFei commented 5 years ago

在Linux系统中创建shell脚本

  1. 创建shell touch update-demo.sh
  2. 使用vim命令写入
    #!/bin/bash
    cd /data/react-grid-layout-between
    sudo git pull
    npm install
    npm run build
    sudo rm -rf /data/wwwroot/demo.sunxinfei.com/*
    sudo cp -r /data/react-grid-layout-between/build/* /data/wwwroot/demo.sunxinfei.com/
    echo "********************************"
    echo "*********** complete ***********"
    echo "***** $(date "+%Y-%m-%d %H:%M:%S") *****"
    echo "*********** $0 ************"
    echo "********************************"
  3. 运行该脚本 sh update-demo.sh

使用nodejs创建github的webhook

如果想实现github上push代码,页面实时更新,就需要借助webhook这个功能,它会提供代码更新的接口,比如push,这样我们就可以在服务器端进行监听,然后执行相应的命令。

  1. 首先在服务器中配置server,让服务器监听端口 eg: /usr/local/nginx/conf/vhost
    # 意思是我们监听 http://test.com/webhook 请求,转到本地服务器的7777端口
    server {
    listen 80;
    server_name test.com;
    location /webhook {
                proxy_pass http://127.0.0.1:7777;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header X-Forwarded-Port $server_port;
        #    root   html;
        #    index  index.html index.htm;
    }
    }
  2. 保存上面的配置,并且重启nginx,/usr/local/nginx/sbin/nginx -s reload
  3. 在服务器任意一个地方,创建deploy.js文件
    
    // 如果报错github-webhook-handler模块找不到,就打开下面这句注释
    // module.paths.push('/root/.nvm/versions/node/v8.12.0/lib/node_modules');
    var http = require('http')
    var createHandler = require('github-webhook-handler')
    var handler = createHandler({ path: '/webhook', secret: '设置的github中的密钥' })

function run_cmd(cmd, args, callback) { var spawn = require('child_process').spawn; var child = spawn(cmd, args); var resp = "";

child.stdout.on('data', function(buffer) { resp += buffer.toString(); }); child.stdout.on('end', function() { callback (resp) }); }

http.createServer(function (req, res) { handler(req, res, function (err) { res.statusCode = 404 res.end('no such location') }) }).listen(7777)

handler.on('error', function (err) { console.error('Error:', err.message) })

handler.on('push', function (event) { console.log('Received a push event for %s to %s', event.payload.repository.name, event.payload.ref) run_cmd('sh', ['./update-demo.sh',event.payload.repository.name], function(text){ console.log(text) }); })

handler.on('issues', function (event) { console.log('Received an issue event for %s action=%s: #%d %s', event.payload.repository.name, event.payload.action, event.payload.issue.number, event.payload.issue.title) })

4. 在github的的对应项目中,打开setting选项,进入webhooks标签,

Payload URL填写http://test.com/webhook Content type 修改为 application/json Secret设置自己的密钥之后,记得同步修改到前面创建的deploy.js中。

5. 准备工作都已经做完,我们可以实验是否已经打通,我们在服务器端的deploy.js目录下运行`node deploy.js`,我们更新下代码或者打开网址 `http://test.com/webhook`,查看是否服务器端有console.log输出。
6. 现在我们需要[pm2](https://pm2.io/doc/en/runtime/overview/?utm_source=pm2&utm_medium=website&utm_campaign=rebranding),因为目前该deploy的node脚本没有在服务器端后台运行。我们需要用pm2进行进程管理。

npm install pm2 -g pm2 start deploy.js

查看log

pm2 logs appName --lines 1000

SunXinFei commented 5 years ago

nginx服务器屏蔽ip地址访问,并可以通过域名访问

/usr/local/nginx/conf进入该文件夹下面,修改nginx.conf文件,

server {
    listen 80 default;
    rewrite ^(.*) https://github.com/SunXinFei permanent;
 }
 server {
    listen 80;
    server_name aaa.com;
    *******省略其他配置
}  

保存,重启nginx 该配置可以满足ip地址访问的时候,重定向至其他页面,如果是想域名访问的话,需要配置host,将aaa.com 指向 ip,即可用aaa.com访问原来的页面

SunXinFei commented 4 years ago

Mac卸载node

sudo npm uninstall npm -g
sudo rm -rf /usr/local/lib/node /usr/local/lib/node_modules /var/db/receipts/org.nodejs.*
sudo rm -rf /usr/local/include/node /Users/$USER/.npm
sudo rm /usr/local/bin/node
sudo rm /usr/local/share/man/man1/node.1
sudo rm /usr/local/lib/dtrace/node.d

验证卸载:

node -v
npm -v
SunXinFei commented 4 years ago

VScode 插件

VS Code Counter 统计项目代码行数,区分注释、空行以及有效代码行,只需要安装后,右击文件夹即可 Live Server一件启动web服务

SunXinFei commented 4 years ago

开源项目的徽标

什么是徽标?如 image

徽标生成的网址一般用如下网站: https://shields.io/ https://badgen.net/ https://forthebadge.com/ https://badge.fury.io/ https://github.com/boennemann/badges 网站会按照你的参数生成你所需要的徽标样式,例如 webpack version ![webpack version](https://img.shields.io/badge/webpack-4.1.1-blue.svg) 将该链接添加到ReadMe中即可

SunXinFei commented 4 years ago

如何在chrome的devtools中复制json

If the right-click -> copy is not available you could try: 1 - Right-click the object and select "Store as global variable" 2 - The console will print the new variable's name, for example: //temp1 3 - Type: copy(temp1)
The object is now available in your clipboard. image

参考:https://superuser.com/questions/777213/copy-json-from-console-log-in-developer-tool-to-clipboard/792240#792240?newreg=e18f413c36c84cfc95a6e1720c347773

SunXinFei commented 4 years ago

关于进程与线程

有一个有趣的回答:

  • 进程=火车,线程=车厢线程在进程下行进(单纯的车厢无法运行)
  • 一个进程可以包含多个线程(一辆火车可以有多个车厢)
  • 不同进程间数据很难共享(一辆火车上的乘客很难换到另外一辆火车,比如站点换乘)
  • 同一进程下不同线程间数据很易共享(A车厢换到B车厢很容易)
  • 进程要比线程消耗更多的计算机资源(采用多列火车相比多个车厢更耗资源)
  • 进程间不会相互影响,一个线程挂掉将导致整个进程挂掉(一列火车不会影响到另外一列火车,但是如果一列火车上中间的一节车厢着火了,将影响到所有车厢)
  • 进程可以拓展到多机,进程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在行进的不同的轨道上)
  • 进程使用的内存地址可以上锁,即一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。(比如火车上的洗手间)-"互斥锁"
  • 进程使用的内存地址可以限定使用量(比如火车上的餐厅,最多只允许多少人进入,如果满了需要在门口等,等有人出来了才能进去)-“信号量”

参考:https://www.zhihu.com/question/25532384/answer/411179772

SunXinFei commented 4 years ago

js中Object的属性遍历中key的顺序

这里直接抛出结论:Object的属性遍历顺序如果key是数字会按照数字先排序,字母或数字加字母类的key则按照原有顺序输出。 所以如果定义Object定义key尽量不要用数字防止后期出现顺序问题。

let aaa = {
        '2b':'bbb',
        '1a':'aaa',

    }
    Object.keys(aaa).forEach(k=>{
        console.log(k) //2b  1a
    })
 //这里顺序会有问题
   let aaa = {
        '2':'bbb',
        '1':'aaa',

    }
    Object.keys(aaa).forEach(k=>{
        console.log(k) //1 2
    })
   let aaa = {
        'b':'bbb',
        'a':'aaa',

    }
    Object.keys(aaa).forEach(k=>{
        console.log(k) //b a
    })
SunXinFei commented 4 years ago

前端使用CDN的资源分离的访问流程图

image

SunXinFei commented 4 years ago

git提交流程规范

image

SunXinFei commented 4 years ago

package.json版本号

"dependencies": {
        "foo": "1.0.0 - 2.9999.9999",   
        "bar": ">=1.0.2 <2.1.2",        必须大于等于1.0.2版本且小于2.1.2版本
        "baz": ">1.0.2 <=2.3.4",        必须大于1.0.2版本且小于等于2.3.4版本
        "boo": "2.3.1",                 必须匹配这个版本
        "boo": "~2.3.1",                约等于2.3.1,只更新最小版本,相当于2.3.X,即>=2.3.1 <2.4.0
        "thr": "2.3.x",
        "boo": "^2.3.1",                与2.3.1版本兼容,相当于2.X.X, 即>=2.3.1 < 3.0.0,不改变大版本号。
        "qux": "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
        "asd": "http://asdf.com/asdf.tar.gz",   在版本上指定一个压缩包的url,当执行npm install 时这个压缩包会被下载并安装到本地。
        "til": "~1.2",   
        "elf": "~1.2.3", 
        "two": "2.x",
        "lat": "latest",             安装最新版本
        "dyl": "file:../dyl",         使用本地路径
        "adf": "git://github.com/user/project.git#commit-ish"    使用git URL加commit-ish
    }
SunXinFei commented 3 years ago

umd、cjs、cmd、amd

image

SunXinFei commented 1 year ago

lodash一些方法注意问题

_.isEmpty(0) // true

const aaa = {a: null}
_.get(aaa,'a', '-') // null