issue
如何关联本地分支和远程分支
- git branch --set-upstream-to=origin/remote_branch your_branch
- upstream是上游,上溯的意思
如何配置绝对路径
- eject后的面目
- 新建.env文件
- NODE_PATH = src/
- 如果没有eject的项目,则安装react-app-rewired,在config-overrides.js中配置
const {injectBabelPlugin} = require('react-app-rewired');
const rewireReactHotLoader = require('react-app-rewire-hot-loader');
const rewireLess = require('react-app-rewire-less'); ------------------------- 引入less插件
const {addWebpackAlias} = require('customize-cra');
const rewireStyledComponents = require('react-app-rewire-styled-components');
const path = require('path');
module.exports = function override(config, env) {
config = injectBabelPlugin(
['import', {libraryName: 'antd', libraryDirectory: 'es', style: true}], ----- 使用less
config,
);
config = rewireLess.withLoaderOptions({ ---------------------------------------- antd主题
modifyVars: {"@primary-color": "#ff9c32"},
javascriptEnabled: true,
})(config, env);
config.module.rules.unshift({
test: /\.(ts|tsx)$/,
loader: require.resolve("tslint-loader"),
enforce: "pre",
});
config = rewireReactHotLoader(config, env);
config = addWebpackAlias({
['utils']: path.resolve(__dirname, 'src', 'utils'),
['src']: path.resolve(__dirname, 'src'), ------------------------------------ 绝对路径
['themed-components']: path.resolve(__dirname, 'src', 'utils', 'themed-components')
})(config);
config = rewireStyledComponents(config, env, {
pure: true,
});
return config;
};
如何使用redux-devtools-extension
import { applyMiddleware, combineReducers, createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
const totalReducers = {
};
const store = createStore(
combineReducers({ ...totalReducers }),
composeWithDevTools(applyMiddleware()),
);
export default store;
antd 在 typescript 中的使用,并按需加载
- yarn add antd
- yarn add react-app-rewired --dev
- yarn add ts-import-plugin --dev
- 也可以直接使用: create-react-app my-project --scripts-version=react-scripts-ts-antd来生成架子
- https://ant.design/docs/react/use-in-typescript-cn
如何在create-react-app typescript 加入 less
注意:这是在eject后的引入less的方法
- 安装less和less-loader yarn add less-loader less -D
- 在eject后的webpack.config.dev.js文件中,找到module对象的rule数组
- https://blog.csdn.net/wu_xiao_qing/article/details/80235359
{
test: /\.css$|\.less/, ------- 修改1
use: [
require.resolve('style-loader'),
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
},
},
{
loader: require.resolve('less-loader'), ------- 修改2
options: {
importLoaders: 1,
},
},
..........
],
},
如何使用git的pre-commit钩子,规范提交代码
- 安装 husky
- 安装 lint-staged (staged是分段,阶梯的意思)
- 在package.json中添加如下代码
- https://github.com/typicode/husky
- lint-staged ( stage 指的是git中的暂存区 )
- lint-staged每次提交只会检查本次提交的内容
- husky实现git hooks钩子
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"test": "node scripts/test.js --env=jsdom",
"lint-staged": "yarn run lint-staged"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{ts,tsx}": [
"tslint --project tsconfig.json"
],
"*.{less}": [
"stylelint *.less"
]
},
(一)泛型
- 为什么要使用泛型?
需求:一个函数,传入什么类型的参数,就要返回什么类型的参数
痛点:如果参数用any类型,返回值也用any类型,则不清楚返回类型
解决:使用泛型,如下
function identity<T>(arg: T): T {
return arg;
}
解析:
1. 函数 identity 叫做泛型函数
2. <T>中的 T 表示 类型变量(类型参数),即T是一个变量,但是只是表示类型,不表示值
3. identity函数的参数 arg 的类型是 T类型
4. identity函数的返回值 也是 T类型
--------------------
上面定义好了一个泛型函数,如何使用?
两种方法:
(1) 传入所有参数,包括类型参数(类型变量)
let output = identity<string>("myString"); // type of output will be 'string'
解析:类型参数是 string,所以根据函数定义时的限制可以确定:传入参数和返回值都要是string类型
(2) 类型推论
let output = identity("myString"); // type of output will be 'string'
解析:即类型参数,形参,返回值都是同一类型,形参是string,那其他两个就是string
- 新需求:我传入的是具有泛型参数类型的数组,而不是直接是泛型值?如何表示?
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
解析:
(1) 表示传入参数是参数类型为T的数组,返回值也是类型为T的数组,而不是直接为T类型
(2) 这可以让我们把泛型变量T当做类型的一部分使用,而不是整个类型,增加了灵活性。
(二) 泛型类型 ----- 泛型函数的类型
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: <T>(arg: T) => T = identity;
解析:myIdentity是一个函数,类型表示为 <T>(arg: T) => T ,值是 identity函数
--------------------------
我们还可以使用带有调用签名的对象字面量来定义泛型函数:
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: {<T>(arg: T): T} = identity;
(三) 泛型接口
interface GenericIdentityFn { -------- 接口
<T>(arg: T): T; ------------------- 一个类型参数为T的,输入参数类型为T,返回值类型为T的函数
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn = identity;
---------------
把泛型参数当作整个接口的一个参数 (!!!!!!!!!)
interface GenericIdentityFn<T> { ------------------ 接口的参数类型
(arg: T): T;
}
function identity<T>(arg: T): T {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
解析:
使用 GenericIdentityFn的时候,
还得传入一个类型参数来指定泛型类型(这里是:number),锁定了之后代码里使用的类型。
(四) 泛型类
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };
(五) 泛型约束
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length); // Now we know it has a .length property, so no more error
return arg;
}
解析:
(1) <T extends Lengthwise> 表示 ( 类型参数T ) 继承了 ( Lengthwise接口 )
(2) Lengthwise接口表示该类型中,有length属性
(1)
scrollTop:
代表在有滚动条时,滚动条向下滚动的距离也就是元素顶部被遮住部分的高度。
在没有滚动条时scrollTop==0恒成立。单位px,可读可设置。
offsetTop:
当前元素顶部距离最近父元素顶部的距离,和有没有滚动条没有关系。
单位px,只读元素。
clientHeight
元素的高度:包括padding,不包括border,margin,滚动条高度。对block元素有效,对inline元素无效
offsetHeight
元素的高度:包括padding,border,滚动条高度,不包括margin高度
scrollHeight
https://www.imooc.com/article/17571
(2) intersectionObserver 自动观察元素是否可见
var io = new IntersectionObserver(callback, option);
// intersection是交叉的意思
(1) intersectionObserver构造函数接受两个参数
- callback :可见性变化时的回调函数
- option :配置参数,可选
(2) 生成的实例有observe,unobserve,disconnect 等方法
// 开始观察
io.observe(document.getElementById('example')); // observer方法的参数是DOM节点
// 停止观察
io.unobserve(element);
// 关闭观察器
io.disconnect();
(3) 实例的observe方法,参数是被观察的DOM节点,如果要观察多个节点,则要多次执行该方法
(4) callback观察器回调函数:
- callback会触发两次,目标元素进入视口和离开视口时都会触发
- callback回调函数的参数是一个数组,成员都是intersectionObserverEntry对象
- IntersectionObserverEntry对象提供目标元素的信息,一共有七个属性。
其中最重要的两个属性:
( intersectionRatio ) 和 ( isIntersecting ) 是用来判断元素是否可见
- intersectionRatio 相交区域和目标元素的比例值
- isIntersecting 目标元素当前是否可见 Boolean值 可见为true
var io = new IntersectionObserver(
entries => {
console.log(entries);
}
);
(5) option配置对象
- root :用于观察的根元素,默认是浏览器的视口,也可以指定具体元素,
指定元素的时候用于观察的元素必须是指定元素的子元素
- threshold :用来指定交叉比例,决定什么时候触发回调函数,是一个数组,默认是[0]。
- rootMargin :用来扩大或者缩小视窗的的大小
const options = {
root: document.querySelector('.box'),
threshold: [0, 0.5, 1],
rootMargin: '30px 100px 20px'
}
实例:
https://www.w3cplus.com/vue/build-an-infinite-scroll-component-using-intersection-observer-api.html
https://www.jianshu.com/p/84a86e41eb2b
https://www.jianshu.com/p/f723f1145764