(create-react-app-typescript中使用 ts,husky,lint-stage,antd,less,redux,router ),ts泛型,(offsetTop和scro...

issue

如何关联本地分支和远程分支

  1. git branch --set-upstream-to=origin/remote_branch your_branch
  2. upstream是上游,上溯的意思

如何配置绝对路径

  • eject后的面目
  1. 新建.env文件
  2. 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

  1. https://github.com/zalmoxisus/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 中的使用,并按需加载

  1. yarn add antd
  2. yarn add react-app-rewired --dev
  3. yarn add ts-import-plugin --dev
  4. 也可以直接使用: create-react-app my-project --scripts-version=react-scripts-ts-antd来生成架子
  5. https://ant.design/docs/react/use-in-typescript-cn

如何在create-react-app typescript 加入 less

注意:这是在eject后的引入less的方法

  1. 安装less和less-loader yarn add less-loader less -D
  2. 在eject后的webpack.config.dev.js文件中,找到module对象的rule数组
  3. 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钩子,规范提交代码

  1. 安装 husky
  2. 安装 lint-staged (staged是分段,阶梯的意思)
  3. 在package.json中添加如下代码
  4. 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,只读元素。


scrollTop

offsetTop

clientHeight

元素的高度:包括padding,不包括border,margin,滚动条高度。对block元素有效,对inline元素无效

offsetHeight

元素的高度:包括padding,border,滚动条高度,不包括margin高度

scrollHeight

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容