首页
统计
墙纸
留言
Search
1
PVE8优化
13 阅读
2
Debian 12 / Ubuntu 22.04 使用源安装 LAMP 教程
12 阅读
3
内核版本 4.9 以上的 Linux 系统开启/关闭 BBR 的方法
10 阅读
4
CSS动画
10 阅读
5
jenkins根据分支、文件夹打包
9 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicada
累计撰写
161
篇文章
累计收到
57
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
152
篇与
的结果
2019-05-24
table表头固定
HTML部分<div style="width: 800px;"> <div class="table-head"> <table> <colgroup> <col style="width: 80px;" /> <col /> </colgroup> <thead> <tr><th>序号</th><th>内容</th></tr> </thead> </table> </div> <div class="table-body"> <table> <colgroup><col style="width: 80px;" /><col /></colgroup> <tbody> <tr><td>1</td><td>我只是用来测试的</td></tr> <tr><td>2</td><td>我只是用来测试的</td></tr> <tr><td>3</td><td>我只是用来测试的</td></tr> <tr><td>4</td><td>我只是用来测试的</td></tr> <tr><td>5</td><td>我只是用来测试的</td></tr> <tr><td>6</td><td>我只是用来测试的</td></tr> <tr><td>7</td><td>我只是用来测试的</td></tr> <tr><td>8</td><td>我只是用来测试的</td></tr> <tr><td>9</td><td>我只是用来测试的</td></tr> <tr><td>10</td><td>我只是用来测试的</td></tr> <tr><td>11</td><td>我只是用来测试的</td></tr> <tr><td>12</td><td>我只是用来测试的</td></tr> <tr><td>13</td><td>我只是用来测试的</td></tr> <tr><td>14</td><td>我只是用来测试的</td></tr> <tr><td>15</td><td>我只是用来测试的</td></tr> </tbody> </table> </div> </div>Css部分.table-head{padding-right:17px;background-color:#999;color:#000;} .table-body{width:100%; height:300px;overflow-y:scroll;} .table-head table,.table-body table{width:100%;} .table-body table tr:nth-child(2n+1){background-color:#f2f2f2;}
2019年05月24日
0 阅读
0 评论
0 点赞
2019-05-13
TypeScript多态和抽象类
多态父类定义的一个方法不去实现, 让继承的子类去实现.(多态属于继承)class Person{ name:string; run():void{} } Class Mi extends Person{ super('小米'); run():string{ return this.name+'手机' } } new Mi().run()抽象类typescript中的抽象类: 它是提供给其它类继承的基类, 不直接实例化.用abstract关键字定义抽象类和抽象方法. 抽象类中的抽象方法不包含具体实现并必须在派生类中实现.abstract抽象方法只能放在抽象类中.abstract class Person{ name:string; abstract run():void; } Class Mi extends Person{ super('小米'); run():string{ return this.name+'手机' } } new Mi().run()
2019年05月13日
1 阅读
0 评论
0 点赞
2019-04-22
typescript学习笔记二
函数返回值的类型定义fu(): void{}函数的参数必须定义类型fu(name: string, age: number){}函数的默认值fu(name: string = "小米", age: number = 9) {}接口接口的作用: 在面向对象的编程中, 接口是一种规范的定义, 它定义了行为和动作的规范, 在程序设计里面,接口起定义标准的作用.接口的可选属性, 在属性的名的后面添加一个问号(?).只读属性, 在属性名前添加一个readonly.只读数组类型, readonly Array<数组元素类型>. 注意把一个普通数组赋值给readonlyArray后普通数组也只可读.interface Job { type: string; jobTime?: string; description(): string; } class Mi implements Job { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description() { return this.type + '工作' + this.jobTime + "小时;" } } console.log(new Mi("小米").description());函数类型接口, 用来定义函数的参数列表,和返回值的类型的定义.参数列表使用小括号():返回值的类型. 如:(height:string,width:string):boolean;interface Job { (jobTime: string, type?: string): string; } class Mi { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description: Job = (jobTime: string, type: string) => { this.jobTime = jobTime; return this.type + '工作' + this.jobTime + "小时;"; } } console.log(new Mi("小米").description("9"));可索引的类型, 它具有一个索引签名, 签名的类型只有两种(number,string). 还有相应的索引返回值类型.如:readonly [index:number]:string. (只读索引)interface Job { [index: string]: string; } class Mi { readonly type: string; jobTime: string; constructor(type: string, jobTime: string = "8") { this.type = type; this.jobTime = jobTime; } description(jobTime: string, type?: string): object { this.jobTime = jobTime; let obj: Job = { type: this.type, jobTime: this.jobTime } return obj } } console.log(new Mi("小米").description("9"));
2019年04月22日
0 阅读
0 评论
0 点赞
2019-04-22
typescript 学习笔记一
typescript环境的搭建安装环境npm install -g typescript配置typescript 在项目的更目录下新建一个tsconfig.json 配置如下{ "compilerOptions": { "target": "es5", "noImplicitAny": false, "module": "commonjs", "removeComments": true, "sourceMap": false, "outDir": "Golang/TypeScript/" } //"include":[ // "ts" // ], //"exclude": [ // "js" // ] } // target:编译之后生成的JavaScript文件需要遵循的标准。有三个候选项:es3、es5、es2015。 // noImplicitAny:为false时,如果编译器无法根据变量的使用来判断类型时,将用any类型代替。为true时,将进行强类型检查,无法推断类型时,提示错误。 // module:遵循的JavaScript模块规范。主要的候选项有:commonjs、AMD和es2015。为了后面与node.js保持一致,我们这里选用commonjs。 // removeComments:编译生成的JavaScript文件是否移除注释。 // sourceMap:编译时是否生成对应的source map文件。这个文件主要用于前端调试。当前端js文件被压缩引用后,出错时可借助同名的source map文件查找源文件中错误位置。 // outDir:编译输出JavaScript文件存放的文件夹。 // include、exclude:编译时需要包含/剔除的文件夹。编译ts执行tsc -w 会自动检查变化并自动编译typescript类型约束typescript 是超javascript有着类型的检测 let str :string; //这里定义str必须为一个字符串类型,否则会报错 str = '小米' console.log(str) //数组的类型定义 let arr :number[];//在[]前面定义数组元素的类型 arr = [1,2] console.log(arr) //第二种方式是使用数组泛型,Array<元素类型>: let list: Array<number> = [1, 2, 3]; //第三种方式是使用数组泛型,any类型 let list: any[] = [1, 2, 3]; //元组 let arr :[string,number,boolean]; arr = ['min',2,true] console.log(arr) //any let flag :any = null;//any类型可以赋值任何类型 //vold 某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是 void: fn():vold{ alert("TS") } //never never类型表示的是那些永不存在的值的类型。 例如, never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型; 变量也可能是 never类型,当它们被永不为真的类型保护所约束时。 // 返回never的函数必须存在无法达到的终点 function error(message: string): never { throw new Error(message); } // 推断的返回值类型为never function fail() { return error("Something failed"); } // 返回never的函数必须存在无法达到的终点 function infiniteLoop(): never { while (true) { }接口接口的定义 interfaceinterface Person { firstName: string; lastName: string; }接口的作用:用来检测类型function allname(str:Person){ //str必须是Person的类型(接口一般配合类使用) console.log(str.firstName+str.lastName) } allname({firstName:"小",lastName:"米"})类类的定义classclass Name{ //类名必须大写 age:number;//类型必须提前定义 constructor(public firstName, public lastName){ this.age=18 } }接口和类的结合使用interface Person { firstName: string; lastName: string; } class Name{ age:number; constructor(public firstName, public lastName){ this.age=18 } } function allname(str:Person){ console.log(str) } allname(new Name('',''))枚举enum Color {Red, Green=0, Blue}; let ColorName:string = Color[0]; console.log(ColorName);使用enum定义默认是从0开始可以手动指定枚举值也可以通过枚举值获得它的名字Any类型Any类型及任何类型,在编译过程中不会检测类型.知道部分类型比如:let arr:Any[] = ["小米"];类型断言使用尖括号方式//("小米").indexOf('小');as方式//("小米" as string).indexOf('米');总结接口: 用来检测类型.类: 用来生成实例.多类型定义使用 | 隔开.
2019年04月22日
0 阅读
0 评论
0 点赞
2019-04-09
vue-cli集成TypeScript
1- 安装ts-loader和typescriptnpm install --save-dev ts-loader@3 typescriptvue-cle@2.9使用的webpack为3, 所以必须使用ts-loader@32- 修改webpack.base.conf.js配置文件修改webpack.base.conf.js下的entry>app为'./src/main.ts' extensions: ['.js', '.vue', '.json', '.ts', '.tsx']//添加'.ts', '.tsx' 文件引入不用写后缀 rules: [ { test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], } },//添加tsloader加载器 ...其他 ]3- 在src目录下新建一个文件vue-shims.d.ts,用于识别单文件vue内的ts代码declare module "*.vue" { import Vue from "vue"; export default Vue; }4- 在项目根目录下建立TypeScript配置文件tsconfig.json{ "compilerOptions": { "strict": true, "module": "es2015", "moduleResolution": "node", "target": "es5", "allowSyntheticDefaultImports": true, "lib": [ "es2017", "dom" ] } } //"jsx": "preserve" jsx支持5- 修改main.js后缀改为ts, 添加引入文件的的后缀.6- 修改router.js后缀改为ts.7- 测试//下面可以测试是否集成成功,编辑src/components/Hello.vue文件,修改 <script lang="ts"> import Vue, {ComponentOptions} from 'vue' export default { name: 'hello', data() { return { msg: 'this is a typescript project now' } } } as ComponentOptions<Vue> </script>8- 配置官方推荐的,vue-class-component修改ts配置文件,增加以下两项配置"allowSyntheticDefaultImports": true,"experimentalDecorators": true,使用vue-class-component后,初始数据可以直接声明为实例的属性,而不需放入data() {return{}}中,组件方法也可以直接声明为实例的方法,如官方实例,更多使用方法可以参考其官方文档import Vue from 'vue' import Component from 'vue-class-component' // @Component 修饰符注明了此类为一个 Vue 组件 @Component({ // 所有的组件选项都可以放在这里 template: '<button @click="onClick">Click!</button>' }) export default class MyComponent extends Vue { // 初始数据可以直接声明为实例的属性 message: string = 'Hello!' // 组件方法也可以直接声明为实例的方法 onClick (): void { window.alert(this.message) } }问题1- ts 无法识别 requireyarn add @types/webpack-env -D
2019年04月09日
2 阅读
0 评论
0 点赞
2019-04-03
Dart基础一
一、常量与变量运算符:~/ 取整赋值运算符: ??= 无值赋值常用属性:isNaN(是否是非数字)、isEven(是否是偶数)、isOdd(是否是奇数常用方法:abs()(取绝对值)、round()(四舍五入)、floor()(大于它的最小整数)、ceil()(小于它的最大整数)、toInt()(变成整型)、toDouble()(变成浮点型)二、字符串字符串创建:可以使用三个单引号或者三个双引号创建多行字符串、使用r创建raw原始的字符串.字符串操作:字符串也可以进行+ * == [],分别为字符串相加,乘以倍数,是否相等,取某个字符.插值表达式:${expression}常用属性:length、isEmpty、isNotEmpty常用方法:三、布尔型表示:bool四、ListList中的元素可以是有不同的类型创建List :var list=[1,2,3];创建不可变得List:var list = const[1,2,3]构造创建:var list=new List();//在dart2 中已经去掉了new关键字五、Map创建map:var user={"name":"zoey","age":18}创建不可变的map:var user=const {"name":"zoey","age":18}构造创建var user=new Map();var map1={"first":"dart",1:true};//key还可以不是字符串??六、dynamic可以理解为泛型七、关系运算符判断内容是否相同使用==,而在java中==表示的是判断两个引用是否相等,判断内容相当用的是equals八、可选参数可选命名参数:{param1,param2,...}必填的参数不用写参数名,可选的参数必须要写参数名,而且可以跳过一些参数,不按顺序传,只要参数名对得上就可以了,这种方式用得比较多可选位置参数:[param1,param2,...]根据参数的位置,默认的进行传参,但不能跳过某个参数可选参数必须在必选参数后面八、构造函数当想在对象上执行多个操作时可以使用级联操作符(..)//链式调用私有属性使用(_)开头实例变量: 如果在定义实例变量时设置它的值,而不是在构造函数或其他函数中赋值,则赋值操作发生在构造函数和初始化列表执行之前如果父类没有无名无参数的默认构造函数,则子类必须手动调用一个父类构造函数。在:后面构造函数体之前指定要调用的父类构造函数class Person { Person.fromJson(Map data) { print('in Person'); } } class Employee extends Person { // Person 没有默认构造函数 // 所以必需指定 super.fromJson(data) 构造函数 Employee.fromJson(Map data) : super.fromJson(data) { print('in Employee'); } }重定向构造函数: 有些构造函数只是调用同一个类中的另外一个构造函数class Point { num x; num y; Point(this.x, this.y); // 该类的主要构造函数 Point.alongXAxis(num x) : this(x, 0); // 调用主要构造函数 }常量构造函数: 如果类生成从来不改变的对象,则可以把这些对象定义为编译器常量。用一个const构造函数赋值为实例变量,并将实例变量设置为final来实现class ImmutablePoint { final num x; final num y; const ImmutablePoint(this.x, this.y); static final ImmutablePoint origin = const ImmutablePoint(0, 0); }工厂构造函数: 如果一个构造函数并不总是要创建新的对象(或从缓存中返回实例),可以用factory关键字修饰构造函数class Logger { final String name; bool mute = false; // _cache is library-private, thanks to the _ in front of its name. static final Map<String, Logger> _cache = <String, Logger>{}; factory Logger(String name) { if (_cache.containsKey(name)) { return _cache[name]; } else { final logger = new Logger._internal(name); _cache[name] = logger; return logger; } } Logger._internal(this.name); void log(String msg) { if (!mute) { print(msg); } } }九、类型测试操作符操作符 描述as Typecase(类型转换)is 如果对象是该类型,则返回trueis! 如果对象是该类型,则返回falseassert语句只在检测模式下有效,在生产模式下无任何效果使用assert语句检测执行条件。如果条件是false,则中断执行并抛出异常(AssertionError)
2019年04月03日
2 阅读
0 评论
0 点赞
2019-04-03
Flutter基础一(基本结构)
import 'package:flutter/material.dart';Material是一种标准的移动端和web端的视觉设计语言。 Flutter提供了一套丰富的Material widgets。main函数使用了(=>)符号, 这是Dart中单行函数或方法的简写。该应用程序继承了 StatelessWidget,这将会使应用本身也成为一个widget。 在Flutter中,大多数东西都是widget,包括对齐(alignment)、填充(padding)和布局(layout)Scaffold 是 Material library 中提供的一个widget, 它提供了默认的导航栏、标题和包含主屏幕widget树的body属性。widget树可以很复杂。widget的主要工作是提供一个build()方法来描述如何根据其他较低级别的widget来显示自己。import 'package:flutter/material.dart'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( title: 'Welcome to Flutter', home: new Scaffold( appBar: new AppBar( title: new Text('Welcome to Flutter'), ), body: new Center( child: new Text('Hello World'), ), ), ); } }
2019年04月03日
1 阅读
0 评论
0 点赞
2019-04-01
Web worker
Web workerWeb Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。Web Worker 有以下几个使用注意点。(1)同源限制分配给 Worker 线程运行的脚本文件,必须与主线程的脚本文件同源。(2)DOM 限制Worker 线程所在的全局对象,与主线程不一样,无法读取主线程所在网页的 DOM 对象,也无法使用document、window、parent这些对象。但是,Worker 线程可以navigator对象和location对象。(3)通信联系Worker 线程和主线程不在同一个上下文环境,它们不能直接通信,必须通过消息完成。(4)脚本限制Worker 线程不能执行alert()方法和confirm()方法,但可以使用 XMLHttpRequest 对象发出 AJAX 请求。(5)文件限制Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。基本用法1 主线程主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程。var worker = new Worker('work.js');Worker()构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。然后,主线程调用worker.postMessage()方法,向 Worker 发消息。worker.postMessage('Hello World');worker.postMessage({method: 'echo', args: ['Work']});worker.postMessage()方法的参数,就是主线程传给 Worker 的数据。它可以是各种数据类型,包括二进制数据。接着,主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。worker.onmessage = function (event) { console.log('Received message ' + event.data); doSomething(); } function doSomething() { // 执行任务 worker.postMessage('Work done!'); }上面代码中,事件对象的data属性可以获取 Worker 发来的数据。Worker 完成任务以后,主线程就可以把它关掉。worker.terminate();2 Worker 线程Worker 线程内部需要有一个监听函数,监听message事件。self.addEventListener('message', function (e) { self.postMessage('You said: ' + e.data); }, false);上面代码中,self代表子线程自身,即子线程的全局对象。因此,等同于下面两种写法。// 写法一this.addEventListener('message', function (e) { this.postMessage('You said: ' + e.data); }, false);// 写法二addEventListener('message', function (e) { postMessage('You said: ' + e.data); }, false);除了使用self.addEventListener()指定监听函数,也可以使用self.onmessage指定。监听函数的参数是一个事件对象,它的data属性包含主线程发来的数据。self.postMessage()方法用来向主线程发送消息。根据主线程发来的数据,Worker 线程可以调用不同的方法,下面是一个例子。self.addEventListener('message', function (e) { var data = e.data; switch (data.cmd) { case 'start': self.postMessage('WORKER STARTED: ' + data.msg); break; case 'stop': self.postMessage('WORKER STOPPED: ' + data.msg); self.close(); // Terminates the worker. break; default: self.postMessage('Unknown command: ' + data.msg); }; }, false);上面代码中,self.close()用于在 Worker 内部关闭自身。3 Worker 加载脚本Worker 内部如果要加载其他脚本,有一个专门的方法importScripts()。importScripts('script1.js');该方法可以同时加载多个脚本。importScripts('script1.js', 'script2.js');4 错误处理主线程可以监听 Worker 是否发生错误。如果发生错误,Worker 会触发主线程的error事件。worker.onerror(function (event) { console.log([ 'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message ].join('')); });// 或者worker.addEventListener('error', function (event) { // ...});Worker 内部也可以监听error事件。5 关闭 Worker使用完毕,为了节省系统资源,必须关闭 Worker。// 主线程worker.terminate();// Worker 线程self.close();API1 主线程浏览器原生提供Worker()构造函数,用来供主线程生成 Worker 线程。var myWorker = new Worker(jsUrl, options);Worker()构造函数,可以接受两个参数。第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS 脚本,否则会报错。第二个参数是配置对象,该对象可选。它的一个作用就是指定 Worker 的名称,用来区分多个 Worker 线程。// 主线程var myWorker = new Worker('worker.js', { name : 'myWorker' });// Worker 线程self.name // myWorkerWorker()构造函数返回一个 Worker 线程对象,用来供主线程操作 Worker。Worker 线程对象的属性和方法如下。Worker.onerror:指定 error 事件的监听函数。Worker.onmessage:指定 message 事件的监听函数,发送过来的数据在Event.data属性中。Worker.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。Worker.postMessage():向 Worker 线程发送消息。Worker.terminate():立即终止 Worker 线程。2 Worker 线程Web Worker 有自己的全局对象,不是主线程的window,而是一个专门为 Worker 定制的全局对象。因此定义在window上面的对象和方法不是全部都可以使用。Worker 线程有一些自己的全局属性和方法。self.name: Worker 的名字。该属性只读,由构造函数指定。self.onmessage:指定message事件的监听函数。self.onmessageerror:指定 messageerror 事件的监听函数。发送的数据无法序列化成字符串时,会触发这个事件。self.close():关闭 Worker 线程。self.postMessage():向产生这个 Worker 线程发送消息。self.importScripts():加载 JS 脚本。实例:Worker 线程完成轮询有时,浏览器需要轮询服务器状态,以便第一时间得知状态改变。这个工作可以放在 Worker 里面。function createWorker(f) { var blob = new Blob(['(' + f.toString() +')()']); var url = window.URL.createObjectURL(blob); var worker = new Worker(url); return worker; } var pollingWorker = createWorker(function (e) { var cache; function compare(new, old) { ... }; setInterval(function () { fetch('/my-api-endpoint').then(function (res) { var data = res.json(); if (!compare(data, cache)) { cache = data; self.postMessage(data); } }) }, 1000) }); pollingWorker.onmessage = function () { // render data } pollingWorker.postMessage('init');上面代码中,Worker 每秒钟轮询一次数据,然后跟缓存做比较。如果不一致,就说明服务端有了新的变化,因此就要通知主线程。
2019年04月01日
0 阅读
0 评论
0 点赞
2019-02-18
2018总结来的晚了些
过去的2018 2018在工作上有着长足的进步, 有独立构建VUE大型项目的能力. 对项目有着自己的看法并且实施. 温习React并有开发小中型项目的能力. 获得公司年度优秀员工称号! 个人方面, 有时间和合适的天气就去锻炼身体. 也是接下来一年的较为重要的事. 现在的2019解决个人问题.(第一位)恢复健康身体.(亚健康)对未来转型的考虑.多用时间学习看书.对国内的经济形势有所了解(危机)
2019年02月18日
0 阅读
0 评论
0 点赞
2018-12-12
React 16 生命周期函数
1.constructor(props)react组件的构造函数在挂载之前被调用。在实现React.Component构造函数时,需要先在添加其他内容前,调用super(props),用来将父组件传来的props绑定到这个类中,使用this.props将会得到。官方建议不要在constructor引入任何具有副作用和订阅功能的代码,这些应当在componentDidMount()中写入。constructor中应当做些初始化的动作,如:初始化state,将事件处理函数绑定到类实例上,但也不要使用setState()。如果没有必要初始化state或绑定方法,则不需要构造constructor,或者把这个组件换成纯函数写法。当然也可以利用props初始化state,在之后修改state不会对props造成任何修改,但仍然建议大家提升状态到父组件中,或使用redux统一进行状态管理。constructor(props) { super(props); this.state = { color: props.initialColor }; }2.static getDerivedStateFromProps(nextProps, prevState)getDerivedStateFromProps在组件实例化后,和接受新的props后被调用。他返回一个对象来更新状态,或者返回null表示新的props不需要任何state的更新。如果是由于父组件的props更改,所带来的重新渲染,也会触发此方法。调用steState()不会触发getDerivedStateFromProps()。3. componentWillMount() / UNSAFE_componentWillMount()componentWillMount()将在react未来版本中被弃用。UNSAFE_componentWillMount()在组件挂载前被调用,在这个方法中调用setState()不会起作用,是由于他在render()前被调用。为了避免副作用和其他的订阅,官方都建议使用componentDidMount()代替。这个方法是用于在服务器渲染上的唯一方法。4.render()render()方法是必需的。当他被调用时,他将计算this.props和this.state,并返回以下一种类型:React元素。通过jsx创建,既可以是dom元素,也可以是用户自定义的组件。字符串或数字。他们将会以文本节点形式渲染到dom中。Portals。react 16版本中提出的新的解决方案,可以使组件脱离父组件层级直接挂载在DOM树的任何位置。null,什么也不渲染布尔值。也是什么都不渲染,通常后跟组件进行判断。当返回null,false,ReactDOM.findDOMNode(this)将会返回null,什么都不会渲染。render()方法必须是一个纯函数,他不应该改变state,也不能直接和浏览器进行交互,应该将事件放在其他生命周期函数中。 如果shouldComponentUpdate()返回false,render()不会被调用。Fragments你也可以在render()中使用数组,如:(不要忘记给每个数组元素添加key,防止出现警告)render() { return [ <li key="A">First item</li>, <li key="B">Second item</li>, <li key="C">Third item</li>, ]; } ```` 换一种写法,可以不写key(v16++)render() { return (<React.Fragment> <li>First item</li> <li>Second item</li> <li>Third item</li> </React.Fragment>);}**5.componentWillReceiveProps()**/ UNSAFE_componentWillReceiveProps(nextProps) 官方建议使用getDerivedStateFromProps函数代替componentWillReceiveProps()。当组件挂载后,接收到新的props后会被调用。如果需要更新state来响应props的更改,则可以进行this.props和nextProps的比较,并在此方法中使用this.setState()。 如果父组件会让这个组件重新渲染,即使props没有改变,也会调用这个方法。 react不会在组件初始化props时调用这个方法。调用this.setState也不会触发。 **6.shouldComponentUpdate(nextProps, nextState)** 调用shouldComponentUpdate使react知道,组件的输出是否受state和props的影响。默认每个状态的更改都会重新渲染,大多数情况下应该保持这个默认行为。 在渲染新的props或state前,shouldComponentUpdate会被调用。默认为true。这个方法不会在初始化时被调用,也不会在forceUpdate()时被调用。返回false不会阻止子组件在state更改时重新渲染。 如果shouldComponentUpdate()返回false,componentwillupdate,render和componentDidUpdate不会被调用。 在未来版本,shouldComponentUpdate()将会作为一个提示而不是严格的指令,返回false仍然可能导致组件的重新渲染。 官方并不建议在shouldComponentUpdate()中进行深度查询或使用JSON.stringify(),他效率非常低,并且损伤性能。 **7.UNSAFE_componentWillUpdate(nextProps, nextState)** 在渲染新的state或props时,UNSAFE_componentWillUpdate会被调用,将此作为在更新发生之前进行准备的机会。这个方法不会在初始化时被调用。 不能在这里使用this.setState(),也不能做会触发视图更新的操作。如果需要更新state或props,调用getDerivedStateFromProps。 **8.getSnapshotBeforeUpdate()** 在react render()后的输出被渲染到DOM之前被调用。它使您的组件能够在它们被潜在更改之前捕获当前值(如滚动位置)。这个生命周期返回的任何值都将作为参数传递给componentDidUpdate()。 **9.componentDidUpdate(prevProps, prevState, snapshot)** 在更新发生后立即调用componentDidUpdate()。此方法不用于初始渲染。当组件更新时,将此作为一个机会来操作DOM。只要您将当前的props与以前的props进行比较(例如,如果props没有改变,则可能不需要网络请求),这也是做网络请求的好地方。 如果组件实现getSnapshotBeforeUpdate()生命周期,则它返回的值将作为第三个“快照”参数传递给componentDidUpdate()。否则,这个参数是undefined。 **10.componentWillUnmount()** 在组件被卸载并销毁之前立即被调用。在此方法中执行任何必要的清理,例如使定时器无效,取消网络请求或清理在componentDidMount()中创建的任何监听。 **11.componentDidCatch(error, info)** 错误边界是React组件,可以在其子组件树中的任何位置捕获JavaScript错误,记录这些错误并显示回退UI,而不是崩溃的组件树。错误边界在渲染期间,生命周期方法以及整个树下的构造函数中捕获错误。 如果类组件定义了此生命周期方法,则它将成为错误边界。在它中调用setState()可以让你在下面的树中捕获未处理的JavaScript错误,并显示一个后备UI。只能使用错误边界从意外异常中恢复;不要试图将它们用于控制流程。详细
2018年12月12日
2 阅读
0 评论
0 点赞
1
...
6
7
8
...
16