这些是在搭建本博客之前,在爱奇尔工作时进行的一些总结,篇幅略长。
React-intl
- 后台没有,再去正式环境添加;一定在正式环境添加key;只添加中文;测试环境的由后端同步(李建龙);
- 登陆网站,请求接口获得messages数组;
- 先写页面,实现功能,再进行国际化;
- 问题:冗余key;代码中中文
erp项目
- module:数据源,actions,initstate,reducer
- antd表格,表单
- 后期任务:
- 后期做erp web app;antd-mobile;
- 采购管理»采购订单,后期可能会改造;
- 菜单
- 菜单路径定义:aiqier-erp-admin-web/src/components/App/AppMenu.js
- 菜单引用:aiqier-erp-admin-web/src/components/App/AppMainWrapper.js
- AppLogo:左侧logo
- AppHeader:右侧头部
- this.renderAppMenus():菜单
- this.renderAppContent(pathname):右侧内容
- Redirect to={temObject}
- Notification
- AnchorButton:scrollTop/scrollBottom
- 项目操作
- git命令
- git remote -v
- git remote add root http://……git
- git remote -v
- git status
- git pull root master
- git branch -a
- git checkout – package.json
- git checkout –yarn.lock
- rm -rf package - lock.json
- rm -rf node_modules/
- yarn install
- git add .
- git commit -m’XXXXXX’
- git push
- git pull root master
- git log
- git push
- 项目部署
- 地址:webpack.XX.org(Jenkins)
- PR代码(yarn merge)
- yarn merge:root test
- yarn deploy (test)
- yarn merge:root prod
- yarn deploy prod
- profile.json文件
{ "git": { "userName": "个人账号", "password": "XXXXX" }, "ci": { "j_username": "公司名", "j_password": "XXX" } }
- git命令
react-dropzone上传文件类型支持:
<Dropzone
onDrop={this.onDrop}
accept={'image/jpg, image/jpeg, image/png, image/gif, application/zip, ' +
'application/x-rar-compressed, application/msword, application/pdf,' +
' application/vnd.openxmlformats-officedocument.wordprocessingml.document,' +
' application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
style={_styles.drop}>
<Icon
type='inbox'
style={_styles.icon} />
<p style={_styles.title}>
Click or drag file to this area to upload
</p>
<p style={_styles.message}>
Support for a single or bulk upload. Strictly prohibit from uploading company data or other band files
</p>
</Dropzone>
参考: office 所有后缀对应的 content-type
如果你用到了constructor就必须写super(),是用来初始化this的,可以绑定事件到this上; 如果你在constructor中要使用this.props,就必须给super加参数:super(props); (无论有没有constructor,在render中this.props都是可以使用的,这是React自动附带的;) 如果没用到constructor,是可以不写的,直接:
class HelloMessage extends React.Component{ render (){ return ( <div>nice to meet you! {this.props.name}</div> ); } } //不过这种只是用render的情况,使用一般的ES6函数写会更简便: const HelloMessage = (props)=>( <div>nice to meet you! {this.props.name}</div> )
工具/插件/库
-
树形展示GitHub项目代码Chrome插件:Octotree
- 命令行工具
- idx使用:现在多使用’?.’写法(?.是一个整体,相当于一个运算符),可以不使用idx。新的’?.’写法:@babel/plugin-proposal-optional-chaining
示例:- obj?.foo.bar?.baz
- obj?.[‘foo’]?.bar?.baz
-
function test() { return 42; } test?.();
- || 和 ??区别
let a = { b: { c: 0 } } console.log(a?.b?.c || 33) // 33 console.log(a?.b?.c ?? 33) // 0 console.log(a?.c?.c || 22) // 22 console.log(a?.c?.c ?? 22) // 22
function idx<Ti, Tv>(input: Ti, accessor: (input: Ti) => Tv): ?Tv { try { return accessor(input); } catch (error) { if (error instanceof TypeError) { if (nullPattern.test(error)) { return null; } else if (undefinedPattern.test(error)) { return undefined; } } throw error; } } const nullPattern = /^null | null$|^[^(]* null /i; const undefinedPattern = /^undefined | undefined$|^[^(]* undefined /i; idx.default = idx; module.exports = idx;
-
console-importer:在在 Dev Tools 里面来使用 npm 插件!
- Lodash-文档
- omit 忽略值:
var object = { 'a': 1, 'b': '2', 'c': 3 }; _.omit(object, ['a', 'c']); // => { 'b': '2' }
- omit 忽略值:
- curl
百科:cURL是一个利用URL语法在命令行下工作的文件传输工具,1997年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具。cURL还包含了用于程序开发的libcurl。
- Next.js文档 | Next.js英文文档(React) | UmiJS | NuxtJS(Vue)
技巧技法
git
- 已提交过的代码,被删除,git status会是绿色,相当于已经add过了,会被下一次commit和push带着自动提交远程
- Git文件名大小写敏感:
- 问题:本地代码运行ok,但是发现push上去的代码运行后报错,发现有个文件没注意大小写,于是重命名了该文件,发现git没有识别这个更改,不能提交
- 查看git 的设置:git config –get core.ignorecase
- git默认是不区分大小的,因此当你修改了文件名的大小写后,git并不会认为你有修改
- 更改设置解决:git config core.ignorecase false
- git push代码,window下:
error: RPC failed; HTTP 401 curl 22 The requested URL returned error: 401
解决:(修改remote origin,在协议后加name@)
cd .git;vim config; url = http://name@XXXXX:30000/XXX/XXX.git
JS
- js判断对象是否为空对象的几种方法
- Node.js 中文文档 | Node.js 英文文档
- 函数防抖运用:
A.js // 防抖实现 export const debounce = (method, wait) => { let timeout // args为返回函数调用时传入的参数,传给method return function (...args) { let context = this if (timeout) { clearTimeout(timeout) } timeout = setTimeout(() => { // args是一个类数组,所以使用fn.apply // 也可写作method.call(context, ...args) method.apply(context, args) }, wait) } }
B.js //调用: import { debounce } from A; debouncedFn = debounce(this.props.getProductItems, 500) //实际使用: this.debouncedFn(data)
- react如何产生随机不重复的key
<div key={+new Date() + Math.random()}>
- 使用数组的索引
- 使用uuid:https://www.npmjs.com/package/uuid
- 使用uniqid:https://www.npmjs.com/package/uniqid
- Date.now()
- PureComponent使用(以选择框为例)
- 使用PureComponent,父组件传递的props不能全是对象和不变的量,否则会导致一直不更新(如果渲染用的checked来自对象,也应该传一个每次切换会变化为true和false的checked,即便不直接使用)
- 直接使用shouldComponentUpdate,nextProps和this.props进行对比的属性也不能来自对象(例如:return nextProps.item.checked !== this.props.item.checked,也会导致不更新)
- 函数组件:React.memo(…)是React v16.6引进来的新属性。它的作用和React.PureComponent类似,是用来控制函数组件的重新渲染的。React.memo(…) 其实就是函数组件的React.PureComponent。
let TestC = (props) => { return ( <div> { props.count } </> ) } TestC = React.memo(TestC);
- PureComponent减少ES6的类组件的无用渲染;React.memo(...)减少函数组件的无用渲染 - 参考阅读
- Modal.confirm的onOk,可以把this传进去,也可以写箭头函数
Modal.confirm({ title: messages['common_0005'], content: messages['prod_br_0008'], onOk () { _this.props.method() }, <!-- onOk: () => { this.props.method() }, --> onCancel () { } })
- 后端返回的 { responseType: ‘blob’ }数据,需要用react-file-download转化;
import FileDownload from 'react-file-download' this.props.actions.downloadPictures(this.props.selectedIds).then((res) => { // 不能加if(res.data.success)的判断,因为返回的数据是blob,找不到res.data.success FileDownload(res.data, 'images.zip') this.props.cancelSelected() })
下载文件时,很可能需要写responseType,否则可能打不开文件:
axios.put(this.url + '/zip', data, { responseType: 'blob', headers: { 'x-access-token': localStorage.token } })
上传文件:
onDrop = (accepted) => { this.setState({ fileName: accepted[0].name, file: accepted[0] } } const uploadFile = new FormData() uploadFile.append('file', this.state.file) this.props.actions.uploadCalcExcel(uploadFile)
上传、下载进度条实现:
- 通过axios的onDownloadProgress和onUploadProgress配置进度条
- 给原生XMLHttpRequest添加
xhr.addEventListener("progress",()=>{}
监听
- Fetch请求可以直接在控制台调用
let content = {some: 'content'} // Post request with fetch fetch('some-url', { method: 'post', headers: {'Content-Type': 'application/json'} body: JSON.stringify(content) }).then(status) .then(json) .then(function(data){ console.log("请求成功,JSON解析后的响应数据为:",data); }) .catch(function(err){ console.log("Fetch错误:"+err); });
-
next.js中的window is not defined:next.js文档中提供了一种动态导入模块的办法’next/dynamic’
- url-loader和file-loader
- url-loader依赖file-loader
- 当使用url-loader加载图片,图片大小小于上限值,则将图片转base64字符串;否则使用file-loader加载图片,都是为了提高浏览器加载图片速度。
- 使用url-loader加载图片比file-loader更优秀
-
js实现窗口全屏示例:无URL、导航栏等
-
如何实现图片缩放?:将图片按照要求生成缩略图,或者进行特定的缩放(阿里云)
- arguments对象:
arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。例如,它没有 pop 方法。但是它可以被转换为一个真正的Array:
var args = Array.prototype.slice.call(arguments); var args = [].slice.call(arguments); // ES2015 const args = Array.from(arguments); const args = [...arguments];
- momentJS问题:
- 东八区问题 moment().format() 有时间差
- 解决Moment格式化时间出现时区差的问题
- 使用moment.js 获取当前时间往前的时间
moment().format("YYYY-MM-DD HH:mm:ss"); //当前时间 moment().subtract(10, "days").format("YYYY-MM-DD"); //当前时间的前10天时间 moment().subtract(1, "years").format("YYYY-MM-DD"); //当前时间的前1年时间 moment().subtract(3, "months").format("YYYY-MM-DD"); //当前时间的前3个月时间 moment().subtract(1, "weeks").format("YYYY-MM-DD"); //当前时间的前一个星期时间
- url出现了有+,空格,/,?,%,#,&,=等特殊符号的时候,可能在服务器端无法获得正确的参数值(当参数中含有”#”这些等对于URI而言有着特殊含义的符号时,发现“#”字符后面的信息全被裁掉了):
- 在拼接参数的时候,使用 encodeURIComponent() 进行手动转义:
var url = "xxx?name=" + encodeURIComponent( "wz#aa" );
- 用其他字符替换,如:
js var str = '少林寺3#101'; var result = str.replace(/#/g, '%23');
- 在拼接参数的时候,使用 encodeURIComponent() 进行手动转义:
-
antD Form组件中,Form.Item中有带htmlType=’submit’属性的Button时,会导致在Form中回车提交表单,删除htmlType=’submit’,然后给Button加一个提交的onClick事件即可;
- JS中为什么[‘1’,’7’,’11’].map(parseInt)返回[1,NaN,3]?
- map返回3个参数,item,index,Array,所以[1,7,11].map(console.log)打印:
1 0 (3) [1, 7, 11] 7 1 (3) [1, 7, 11] 11 2 (3) [1, 7, 11]
- parseInt接受两个参数:string,radix,其中radix默认为10;每次调用parseInt,相当于:parseInt(item,index,Array),map传递的第三个参数Array会被忽略,index为0时取默认值10;parseInt(7,1)中,7在1进制中不存在。
- map返回3个参数,item,index,Array,所以[1,7,11].map(console.log)打印:
-
MessageChannel是什么,怎么使用?:MessageChannel的postMessage传递的数据也是深拷贝的,这和web worker的postMessage一样,而且还可以拷贝undefined和循环引用的对象,如下所示:
MessageChannel创建了一个通信的管道,这个管道有两个端口,每个端口都可以通过postMessage发送数据,而一个端口只要绑定了onmessage回调方法,就可以接收从另一个端口传过来的数据。function structuralClone(obj) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel() port2.onmessage = ev => resolve(ev.data) port1.postMessage(obj) }) } var obj = { a: 1, b: { c: 2 } } obj.b.d = obj.b // 注意该方法是异步的 // 可以处理 undefined 和循环引用对象 const test = async () => { const clone = await structuralClone(obj) console.log(clone) } test()
- 个人博客相关
- 在个人博客里添加评论系统–Gitalk
- 引入图片的方式
- GitHub图片:需要在路径分支前加blob,图片后缀后加?raw=true(关键词百度)
- 相对路径(liquid语法:使用站点url与基地目录(site.url与site.baseurl)):{ {site.url} }{ {site.baseurl} }/images/posts/XXX/XX.png?raw=true
- Markdown超链接在新窗口打开:
[example](https://king-hcj.github.io){:target='_blank'}
- 在A节点的兄弟节点B的n级后代节点中触发A节点DOM上的click事件(如果要传参数,可以引入sessionStorage或者localStorage):
document.getElementById('Tools_FBA_Calculator').click()
备注:就算是使用React中的onClick绑定的事件,也可以通过
.click()
触发 - 跨平台桌面应用:
- flex布局设置子元素换行:
.container { display: flex; flex-wrap: wrap; }
- 查看端口占用并释放
- 查看占用:
netstat -ano|findstr 3003
- 任务管理器详细信息,根据pid结束任务
- 查看占用:
- Antd Select组件属性
- showSearch:使用Select的时候, 选项比较多, 通过输入来筛选选项;
- labelInValue:是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 string 变为 {key: string, label: ReactNode} 的格式;默认情况下 onChange 里只能拿到 value,如果需要拿到选中的节点文本 label,可以使用 labelInValue 属性。选中项的 label 会被包装到 value 中传递给 onChange 等函数,此时 value 是一个对象。
- optionFilterProp:搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索。(默认值为’value’)
- optionLabelProp:回填到选择框的 Option 的属性值,默认是 Option 的子元素。
HTML
CSS
- position: sticky粘性定位:除了文章介绍的之外,左右布局,左sticky时,左边还要设置高度才可生效(如:100vh)
示例代码: .left-container { width: 200px; height: 100vh; position: sticky; top: 0px; bottom: 0; background-color: #ffffff; border-right: solid 1px rgb(233, 233, 233); overflow: auto; }
- ant design Tooltip文字提示的样式设置
- 可以通过设置mouseLeaveDelay控制Tooltip在页面的时间,然后chrome就可以查看元素了;
- 直接用 ant-tooltip- 在页面并无法修改它的样式;
- 通过自定义的类名以及类名下的标签就可以修改其样式,如下所示:
(先给Tooltip添加一个overlayClassName={styles[‘tooltip-custom’]})
例: tooltip 黑色背景改成白色不透明.tooltip-custom { div { div { &:first-child { display: none; } &:last-child { padding: 0px; background-color: rgba(255, 255, 255, 1); } } } }
- css全局作用域(:global)和局部作用域(:local)
:local(.title) { color: red; } //上面这种写法相当于 .title{ color: red; } :global(.title) { color: green; }
<!-- 修改antd样式 --> :global{ .ant-select-selection{ background-color: grey; //设置颜色 } } :global(.has-error .ant-form-explain){ position: absolute; }
- CSS Modules 用法教程
- React行内calc的使用:
style={ { width: 'calc(100% - 80px)' } }
- AntD Table列配置相关问题
- 有固定列,因表头各列字数不等,头部不对齐问题,可固定表头高度:给Column添加 className: styles[‘custom_height’]
{ key: item.fieldName, title: 'Title', width: 120, className: styles['custom_height'], dataIndex: item.fieldName, sorter: (a, b) => a[item.fieldName] - b[item.fieldName], sortOrder: sortedInfo.columnKey === item.fieldName && sortedInfo.order, }
//自定义头部高度 th.custom_height { height: 60px !important; }
- 自定义某些列颜色:条件判断,给某些column添加className:styles[‘custom_bg_color’]
th.custom_bg_color, td.custom_bg_color { color: #ffffff !important; background-color: #f85a27 !important; }
- 列的左中右对齐方式,除了可以使用上条方法设置样式之外,还可以通过Column的
align
属性来实现,可选值有'left' | 'right' | 'center'
默认left
。
- 有固定列,因表头各列字数不等,头部不对齐问题,可固定表头高度:给Column添加 className: styles[‘custom_height’]
- AntD Select mode=”multiple” 超出滚动样式
<Select
allowClear
mode="multiple"
placeholder="请选择调整类型..."
value={value}
onChange={this.change}
style={ { width: '260px' } }
>
{Options.map(item => (
<Select.Option key={item.id} value={item.value}>
{item.name}
</Select.Option>
))}
</Select>
/* 通过选择器定位ant-select-selection类或者类所在div,设置如下样式:*/
/* 无法居中时,可能需要设置父级display: flex; */
.ant-select-selection {
overflow: auto;
height: 32px;
}
其他
- Chrome浏览器百度云倍速播放:
videojs.getPlayers("video-player").html5player.tech_.setPlaybackRate(1.5)
其他视频倍速参考:
document.getElementById('#video').playbackRate = 2
-
百度网盘直链下载助手(亲测有效)
- 查看整个项目的代码行数
- 打开终端,用cd命令定位到工程所在的目录,然后调用以下命名即可把每个源代码文件行数及总数统计出来(适用于前端项目,只要改文件后缀即可):
find . "(" -name "*.m" -or -name "*.mm" -or -name "*.cpp" -or -name "*.h" -or -name "*.rss" ")" -print | xargs wc -l
代码规范/规约
- 打开终端,用cd命令定位到工程所在的目录,然后调用以下命名即可把每个源代码文件行数及总数统计出来(适用于前端项目,只要改文件后缀即可):
- EditorConfig: 当多人团队进行一个项目开发时,每个人可能喜欢的编辑器不同,有人喜欢Webstrom、有人喜欢sublime、还有人喜欢Hbuilder。这个时候,问题便迎面而来,如何使使用不同编辑器的开发者能够轻松惬意的遵守最基本的代码规范呢?
EditorConfig helps maintain consistent coding styles for multiple developers working on the same project across various editors and IDEs. - ESLint | Prettier
个人学习规划/学习视频书籍目录整理
通用课程(数据结构、算法、网络)
- 快速上手Linux 玩转典型应用
- 慕课Java就业班
- 专为程序员设计的线性代数课程
- 学习算法思想 修炼编程内功
- 玩转数据结构 从入门到进阶
- 玩转算法面试 从真题到思维全面提升算法思维
- 慕课算法讲师推荐:liuyubobobo
前端
- Node.js:
- 小程序:
- Javascript:
- HTML/CSS:
- React/Vue/Angular:
- Webpack:
- 新版React Native+Redux打造高质量上线App
- Flutter从入门到进阶 实战携程网App
- Socket网络编程进阶与实战
后端
- Google资深工程师深度讲解Go语言
文章
个人web页面构想(非静态)
- 登录授权隐私内容/非登录
- 图片/游记展示
- 文档/博客/学习笔记展示
- 文档的增/删/改/查
- 爱好展示
- 访问量统计
- 基于jekyll-now的个人博客解决方案