Hawei

Say Hi.


  • Home

  • About

  • Tags

  • Categories

  • Archives

Object Dstructuring.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

Object Destructuring

Object Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
// before
const data = () => {
return {
a: 1,
b: 2,
c: 3
}
}
var tmp = data();
var first = tmp.a;
var second = tmp.b;
var third = tmp.c;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// after
const data = () => {
return {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5
}
}
var tmp = data();
var {
a: first,
b: second,
c: third,
...fourth
} = data();

Object Assignment Destructuring

1
2
3
4
5
6
7
8
9
10
11
const data = () => {
return {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5
}
}
var first, second;
{first, second} = data();

Object Default Assignment

说到默认值就要惊醒自己,要防止错误, 而防止错误的措施就是, 给数据源默认值

1
2
3
4
5
6
7
8
// before
const data = () => {
return null;
}
var tmp = data() || {};
var first = tmp.a; // Throw Type Error
var second = tmp.b; // Throw Type Error
var third = tmp.c; // Throw Type Error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// after
const data = () => {
return {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5
}
}
var tmp = data();
var {
a: first = 42,
b: second,
c: third,
...fourth
} = data() || {};

Nested Object Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// before
const data = () => {
return {
a: 1,
b: {
c: 2,
d: 3
}
};
}
var tmp = data() || {};
var first = tmp.a;
var second = tmp.b.c;
var third = tmp.b.d;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// after
const data = () => {
return {

a: 1,
b: {
c: 2,
d: 3
}
}
}
var {
a: first = 42,
b: {
c: second,
d: thrid,
},
...fourth
} = data() || {};

params arguments object

1
2
3
4
5
6
7
8
9
10
11
12
function data (tmp = {}) {
var {
a,
b
} = tmp;
}

function data ({
a,
b
} = {}) {
}

Nested Object & Array Destructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var obj = {
a: 1,
b: {
x: 2
},
c: [3, 4]
}

var {
a,
b,
b: {
x: w
},
c: [d, e]
} = obj;

Regular Expressions.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

Regular Expressions

Look Ahead & Behind

后置断言

1
2
3
4
5
6
7
8
9
10
11
12
var msg = 'Hello world';

msg.match(/(l.)/g);
// ['ll', 'ld']
msg.match(/(l.)$/g);
// ['ld']
msg.match(/(l.)(?=o)/g);
// 我要匹配l.的字符串,但是我希望这个字符串后面有'o'
// ['ll']
msg.match(/(l.)(?!o)/g);
// 我要匹配l.的字符串,但是我希望这个字符串后面没有'o'
// ['lo', 'ld']

前置断言

1
2
3
4
5
6
7
8
9

var msg = 'Hello World';

msg.match(/(?<=e)(l.)/g);
// 我要匹配l.的字符串,但是我希望这个字符串前面有'e'
// ['ll']
msg.match(/(?<!e)(l.)/g);
// 我要匹配l.的字符串,但是我希望这个字符串前面没有'e'
// ['lo', 'ld']

Named Capture Groups es2018

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var msg = 'Hello World';

// 使用括号的意思就是,我按这些匹配,但是最后出结果的时候也把我括号内的单独抽离出来, 成为结果之一
msg.match(/.(l.)/);
// ['ell', 'll']
msg.match(/([jkl])o Wor\1/);
// ['lo Worl']
// 让我们用捕获组重新写第一个例子
msg.match(/(?<groupName>l.)/);
// 把输出展开后, 我们得到了以下的内容:
// 0: "ll"
// 1: "ll"
// groups:-> 这个就是我们捕获组的, 自然,在这个下方是我们对捕获组的命名和匹配结果, 真的很实用, 我们的正则不再是一串又一串没有意义的数字了
// groupName: "ll"
// index: 2
// input: "Hello World"
// length: 2
msg.match(/(?<cap>[jkl])o Wor\k<cap>/);
// 对于这个正则,我没看懂的地方就是 \k 表达的是什么?

// 捕获组的应用场景: 替换
// 使用模板语法替换
msg.replace(/(?<cap>l.)/g, '-----------$<cap>----------');
// "He-----------ll----------o Wor-----------ld----------"
// 使用callback函数处理
msg.replace(/(?<cap>l.)/g, function re(...args) {
debugger
var [,,,,{cap}] = args;
return cap.toUpperCase();
});
// "HeLLo WorLD"

dotAll Mode ES2018

MDN内的描述

dotAll 属性表明是否在正则表达式中一起使用”s”修饰符(引入/s修饰符,使得.可以匹配任意单个字符)。dotAll 是一个只读的属性,属于单个正则表达式实例。

简而言之, 我使用了s的修饰符后, .可以匹配到

  1. U+000A 换行符(”\n”)
  2. U+000D 回车符(”\r”)
  3. U+2028 行分隔符(line separator)
  4. U+2029 段分隔符(paragraph separator)

为什么提出这个特性呢?因为历史因素, js中,正则表达式中的‘.’, 是元字符,本来是匹配所有的字符,但是就是不能匹配新的一行.

注意浏览器支持情况, 保留特性,暂时不要使用.

来看个例子:

1
2
3
4
5
6
7
8
9
var msg = `
The quick brown fox
jumps over the
lazy dog`;

msg.match(/brown.*over/);
// null
msg.match(/brown.*over/s);
// ["brown fox↵jumps over", index: 11, input: "↵The quick brown fox↵jumps over the↵lazy dog", groups: undefined]

Iterators & Generators.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

Iterators & Generators

Iterators

一个迭代器对象 ,知道如何每次访问集合中的一项, 并跟踪该序列中的当前位置。在 JavaScript 中 迭代器是一个对象,它提供了一个next() 方法,用来返回序列中的下一项。这个方法返回包含两个属性:done和 value。
迭代器对象一旦被创建,就可以反复调用next()

来看个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function makeIterator(array){
var nextIndex = 0;
return {
next: function(){
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
};
}
// 初始化后, next方法可以用来依次访问对象中的key
var it = makeIterator(['yo', 'ya']);
console.log(it.next().value); // 'yo'
console.log(it.next().value); // 'ya'
console.log(it.next().done); // true

来看Kyle的例子

1
2
3
4
5
6
7
8
var str = 'Hello';
var world = ['W', 'o', 'r', 'l', 'd'];

var it1 = str[Symbol.iterator]();
var it2 = world[Symbol.iterator]();

it1.next(); // {value: 'H', done: false}, 到最后一个的时候 {value: undefined, done: true}
it2.next(); // {value: 'W', done: false}

Declarative Iterators

1
2
3
4
5
6
7
8
var str = 'Hello';

for(let it = str[Symbol.iterator](), v, result;
(result = it.next()) &&
!result.done &&
(v = result.value || true); ) {
console.log(v);
}

在ES6我们新增了for-of循环, 替换上面的结构:

1
2
3
4
5
6
7
8
9
10
var str = 'Hello';
var it = str[Symbol.iterator]();

for(let v of it) {
console.log(v);
}

for(let v of str) {
console.log(v)
}

这里说一个解构小知识, …运算符运用了iterator

1
2
3
4
var str = 'Hello';

var letters = [...str];
console.log(letters);

自定义迭代器让我们定义自己的迭代规则。这种结构特别适用于我们自己创建的数据结构。

Data Structure without lterators

不是所有的数据结构都有iterator, 比如对象

1
2
3
4
5
6
7
8
9
10
11
var obj = {
a: 1,
b: 2,
c: 3
}

for (let v of obj) {
console.log(v);
} // Type Error

[...obj] // Type Error

在这种情况下, 我们可以自定义自己的iterator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var obj = {
a: 1,
b: 2,
c: 3,
[Symbol.iterator]: function() {
var keys = Object.keys(this);
var index = 0;

return {
// 在这里使用箭头函数的原因是因为, 需要使用到this关键字取到对象本身
next: () => (index < keys.length) ?
{done: false, value: this[keys[index++]]}:
{done: true, value: undefined}
}
}
};

[...obj] // [1, 2, 3]

Generators

虽然自定义的迭代器是一个有用的工具,但由于需要显式地维护其内部状态,因此需要谨慎地创建。Generators提供了一个强大的选择:它允许你定义一个包含自有迭代算法的函数, 同时它可以自动维护自己的状态。
GeneratorFunction 是一个可以作为迭代器工厂的特殊函数。当它被执行时会返回一个新的Generator对象。 如果使用function*语法,则函数将变为GeneratorFunction。

来看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function* idMaker(ids = []) {
let len = ids.length;
if(len) {
for(let i = 0; i < len; i++) {
yield i;
}
} else {
yield undefined;
}
}

let gen = idMaker([0, 1, 2]);

console.log(gen.next().value); // 0
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
// ...

OK, 我们来看一下Kyle的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function *main () {
yield 1;
yield 2;
yield 3;
return 0;
}
// 明确一点, 当我们调用Generator的时候,其实就是实例化了一个iterators实例, 他的行为和我们上面说的iterator很像。只不过我们在iterator上再写一层语法糖, 就是generator
var it = main();
it.next(); // {value: 1, done: false}
it.next(); // {value: 2, done: false}
it.next(); // {value: 3, done: false}
it.next(); // {value: 0, done: true}

[...main()]

好的, 我们用Generator重写一次上面obj没有默认iterator的例子

1
2
3
4
5
6
7
8
9
10
11
12
var obj = {
a: 1,
b: 2,
c: 3,
*[Symbol.iterator]() {
for(let key of Object.keys(this)) {
yield this[key];
}
}
}

[...obj]; // [1, 2, 3]

Strings.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

String

Template Strings

  1. 字符串模板改变了链接字符串的方式
    • 使用方式: ``符号
    • 在字符串中插入变量${}
    • 字符串模板函数
    • 会保留字符串内的空格, 换行, 但是如果设计到转义字符,必须要使用\

Tagged Templates

劫持原有的字符渲染,由函数接管渲染。

1
2
3
4
5
6
7
8
9
10
11
12

const sum = 12.5;
const msg = format`sum is: ${sum}`;
console.log(msg);
// 然后解读一下入参:
// str: 非变量分割的字符串数组, 在这个例子中为['sum is: ', '']
// ...value: 变量以数组的形式传入第二个参数
function format (str, ...value) {
debugger
// 这里返回的就是最终的字符串了
return `${str[0]}$${value[0]}`;
}

知道吗, 这个函数最大的作用就是国际化.在我们$t(‘sayHi’)这样的国际化里, 其实本质上也是一个函数,这个函数通过检测用户语言,然后根据翻译字典去显示对应的内容.

还有就是金额格式化.

Applying Tagged Templates

  1. 定制log函数, 检测字符串变量, 如果是object就把他转成json字符串
  2. 写一个正则表达式的翻译工具, 允许换行和切分正则,最后使用tagged tamplates转成符合格式的正则即可。增加正则的可读性。
  3. 所以,在你的模板字符串里, 你可以写任意你像写的语法,使用好tagged templates就想当于有一个小型的模板引擎。

String padding and String Trimming—–ES2017/ES2019

  1. String padding
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var str = 'Hello';

    str.padStart(5);
    str.padStart(8);
    str.padStart(8, '-');
    str.padStart(8, '*');

    str.padEnd(5);
    str.padEnd(8);
    str.padEnd(8, '-');
    str.padEnd(8, '*');
  2. String trim
    1
    2
    3
    4
    var str = '  Hello    ';
    str.trim();
    str.trimStart();
    str.trimEnd();

js.md

Posted on 2020-04-12 | In fcc

数组扁平化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 我有个问题, 扁平化数组我这样写 没办法控制住depth
// 求一个优雅的方案, 解决扁平化数组时depth层级API问题
const flat = (arr, depth = 1) => {
while(depth > 0) {
arr = arr.reduce((sum, cur) => {
if(isType(cur) === 'Array') {
// 主要是这一段, 如果不使用递归, 那么就是根据depth控制, 扁平化的深度
sum = sum.concat(flat(cur))
} else {
sum.push(cur)
}
return sum
}, [])
depth--
}
return arr
}


const isType = (value) => {
return Object.prototype.toString.call(value).match(/(?<= )\w+/)[0]
// String Number Null Undefined Object Date RegExp Symbol Boolean Function Array
}

flat([1, 2, 3, [1]], 1)

数组根据Number分片

1
2
3
4
5
6
7
8
9
10
11
function chunkArrayInGroups(arr, size) {
// Break it up.
return arr.reduce((sum, cur, index) => {
if(index % size === 0) {
sum.push([cur])
} else {
sum[sum.length - 1].push(cur)
}
return sum
}, [])
}

constructor 属性可以被重写,作为判定父级的方法并不可靠.

isPrototypeOf: 判断原型链来自哪里?

注意,当我们使用原型的继承时, 我们要注意, 往prototype上面不可以使用字面量的方式去增加属性,但是你可以自己写一个方法, 以字面量作为参数传入.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Animal() { }
Animal.prototype.eat = function() { console.log("nom nom nom"); };

function Dog() { }

// 请把你的代码写在这条注释以下
Dog.prototype = Object.create(Animal.prototype)
Dog.prototype.constructor = Dog
Dog.prototype.bark = () => {
console.log('Woof!')
}
// 请把你的代码写在这条注释以下

let beagle = new Dog();

beagle.eat(); // 应该输出 "nom nom nom"
beagle.bark(); // 应该输出 "Woof!"

css.md

Posted on 2020-04-12 | In fcc

相应式布局设计
vw:如 10vw的意思是视窗宽度的 10%。
vh:如 3vh的意思是视窗高度的 3%。
vmin:如 70vmin的意思是视窗中较小尺寸的 70% (高度 VS 宽度)。
vmax:如 100vmax的意思是视窗中较大尺寸的 100% (高度 VS 宽度)。

react基础.md

Posted on 2020-04-12 | In fcc
  1. 插值表达式 {}

  2. 在插值表达式中,可以使用js与jsx语法混用.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // write your code here
    const JSX = <div>
    <h1>{'h1'}</h1>
    <p>{'p'}</p>
    <ul>{ [1, 2, 3].map(item => {
    return <li>{item}</li>
    })}
    </ul>
    </div>;
  3. jsx注释 {/* */}

  4. 渲染 HTML 元素为 DOM 树
    使用reactRender(jsx组件, dom节点)

1
ReactDOM.render(JSX, document.getElementById('challenge-node'))
  1. react定义Html中的class属性, 不可以使用class, 只能使用className(class在js中为关键字)

  2. jsx中, 都存在自闭合标签, 就是不需要关闭标签 类似

    1
    <br />
  3. 好了, 在jsx语法中,也只能有一个父级标签

  4. 无状态组件

    1
    2
    3
    4
    5
    const mycomponent = () => {
    return (
    <div>some</div>
    )
    }
  5. 基于class语法创建一个 React 组件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <h1>Hi</h1>
    );
    // change code above this line
    }
    };
  6. 用组合的方式创建一个 React 组件: z(x) = f(g(x))

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    const child = () => {
    return (
    <div>
    { 'Hello child.' }
    </div>
    )
    }

    class MyComponent extends React.Component {
    constructor(props) {
    // 这个东西很关键
    super(props);
    }
    render() {
    // change code below this line
    return (
    <div>
    <child></child>
    </div>
    );
    // change code above this line
    }
    };
  7. React 渲染嵌套组件
    没啥,也就组件嵌套组件.

  8. 渲染 class 组件为 Dom 树

1
ReactDOM.render(<componentName>, document.getElementById('challenge-node'))
  1. props传递

    1
    2
    3
    <App>
    <Welcome user={如果是变量的化} />
    </App>
  2. 默认的props-defaultProps

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const ShoppingCart = (props) => {
    return (
    <div>
    <h1>Shopping Cart Component{props.items}</h1>
    </div>
    )
    };
    // change code below this line
    ShoppingCart.defaultProps = {
    items: 0
    }
  3. React:使用 PropTypes 来定义你期望的 Props // 限制props的类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 使用 PropTypes
    const Items = (props) => {
    return <h1>Current Quantity of Items in Cart: {props.quantity}</h1>
    };

    // change code below this line
    Items.propTypes = {
    quantity: PropTypes.number.isRequired
    }
    // change code above this line

    Items.defaultProps = {
    quantity: 0
    };
  4. 访问props
    状态组件使用this关键字: this.props
    无状态组件使用入参props

  5. 创建带自身状态的组件: state

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class StatefulComponent extends React.Component {
constructor(props) {
super(props);
// initialize state here
this.state = {
// describe your state here
name: 'fuck'
}
}
render() {
return (
<div>
<h1>{this.state.name}</h1>
</div>
);
}
};
  1. 在render函数的return语句前可以放任意的js, 那么意味着我们可以在渲染之前, 对state进行处理.

  2. 原则: 改变组件状态必须要使用 this.setState

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'Initial State'
    };
    this.handleClick = this.handleClick.bind(this);
    }
    handleClick() {
    // change code below this line
    this.setState({
    name: 'React Rocks!'
    });
    // change code above this line
    }
    render() {
    return (
    <div>
    <button onClick={this.handleClick}>Click Me</button>
    <h1>{this.state.name}</h1>
    </div>
    );
    }
    };
  3. 在react组件里, 组件里的方法是访问不到组件的this的, 这个时候就要我们手动去修复这个问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    itemCount: 0
    };
    // change code below this line
    this.addItem = this.addItem.bind(this)
    // change code above this line
    }
    addItem() {
    this.setState({
    itemCount: this.state.itemCount + 1
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    <button onClick={this.addItem}>Click Me</button>
    { /* change code above this line */ }
    <h1>Current Item Count: {this.state.itemCount}</h1>
    </div>
    );
    }
    };
  4. input框数据双向绑定(万年问题)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class ControlledInput extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    input: 'xxx'
    };
    // change code below this line
    this.assignText = this.assignText.bind(this)
    // change code above this line
    }
    // change code below this line
    assignText(e) {
    this.setState({
    input: e.target.value
    })
    }
    // change code above this line
    render() {
    return (
    <div>
    { /* change code below this line */}
    <input type='text' value={this.state.input} onChange={this.assignText}/>
    { /* change code above this line */}
    <h4>Controlled Input:</h4>
    <p>{this.state.input}</p>
    </div>
    );
    }
    };
  5. 将 State 作为 Props 传递给子组件—-父子数据传递
    遵循两个原则:

  • 单向数据流
  • 最小状态组件原则
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 父子数据传递
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    name: 'CamperBot'
    }
    }
    render() {
    return (
    <div>
    <Navbar name={this.state.name} />
    </div>
    );
    }
    };

    class Navbar extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h1>Hello, my name is: {this.props.name} </h1>
    </div>
    );
    }
    };
  1. 父级向子集传递的不只是state, 也可以是function
    传递function的原因是, 给子组件一个修改state的机会.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    class MyApp extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    inputValue: ''
    }
    this.handleChange = this.handleChange.bind(this);
    }
    handleChange(event) {
    this.setState({
    inputValue: event.target.value
    });
    }
    render() {
    return (
    <div>
    { /* change code below this line */ }
    {this.state.inputValue}
    <GetInput input={this.state.inputValue} handleChange={this.handleChange}/>

    <RenderInput input={this.state.inputValue} />

    { /* change code above this line */ }
    </div>
    );
    }
    };

    class GetInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Get Input:</h3>
    <input
    value={this.props.input}
    onChange={this.props.handleChange}/>
    </div>
    );
    }
    };

    class RenderInput extends React.Component {
    constructor(props) {
    super(props);
    }
    render() {
    return (
    <div>
    <h3>Input Render:</h3>
    <p>{this.props.input}</p>
    </div>
    );
    }
    };
  2. 使用生命周期方法Overview

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    componentWillMount()
    // 即将挂载
    componentDidMount()
    // 挂载后
    componentWillReceiveProps()
    // 将要接收props
    shouldComponentUpdate()
    // 组件更新
    componentWillUpdate()
    // 组件即将更新
    componentDidUpdate()
    // 组件更新后
    componentWillUnmount()
    // 组件卸载
  3. componentDidMount — 组件装载到 DOM 后会调用
    这个生命周期:

  • 一般是放数据请求.请求后把数据放入模板, 再进行渲染.类似我们vue会把请求初始化放到created()
  • 挂载浏览器事件(特指全局的哦, 比如按回车然后, 执行某些搜索, 我们在componentDidMount周期里挂载, 在componentWillUnmount里卸载这个事件)
  1. componentWillReceiveProps — 组件接收到props或者props更新就会触发: 入参默认为该次传入的props

  2. componentDidUpdate — 组件再次重新渲染会触发: 入参默认为该次传入的props

  3. componentWillMount/componentDidMount — 首次渲染, 首次卸载会触发

  4. shouldComponentUpdate — 该生命周期控制组件是否需要更新, 入参默认为nextProps, nextState, 出参必须要一个boolean值, 告诉react是否需要更新该组件,因为, react的行为是, 如果传入了props那么无论怎样都会去更新组件, 触发渲染.(这个生命周期是作为一个优化提出的)

  5. react中的内联样式
    在react使用样式的方式有两种

  • 正常导入
  • 使用内联样式
    1
    <div style={{color: "yellow", fontSize: 16}}>Mellow Yellow</div>
    要点: 1. style中只接受对象 2. 不识别连字符, 要使用驼峰命名
  1. React:在 React Render 方法中使用 JavaScript
    在render函数的return语句之前,我们可以使用任意的js
  1. 使用 If/Else 条件进行渲染
    记住, 这种判断一般都抽离出来成为一个逻辑,不要再jsx中写入太多逻辑.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    let content
    if(this.state.toggleDisplay) {
    content = <h1>Hello</h1>
    } else {
    content = ''
    }
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {content}
    </div>
    );
    }
    };
  2. 使用 && 获得更简洁的条件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class MyComponent extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    display: true
    }
    this.toggleDisplay = this.toggleDisplay.bind(this);
    }
    toggleDisplay() {
    this.setState({
    display: !this.state.display
    });
    }
    render() {
    // change code below this line
    return (
    <div>
    <button onClick={this.toggleDisplay}>Toggle Display</button>
    {this.state.display && <h1>markup</h1>}
    </div>
    );
    }
    };
  3. 使用三元表达式进行条件渲染

    1
    2
    3
    4
    5
    const buttonOne = <button onClick={this.submit}>Submit</button>;
    const buttonTwo = <button>You May Enter</button>;
    const buttonThree = <button>You Shall Not Pass</button>;

    this.state.input === '' ? buttonOne : (this.state.userAge >= 18 ? buttonTwo : buttonThree)
  4. 服务端渲染(待续)

完结撒花

further destructuring.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

further destructuring

Named Arguments

像之前翻译的文章里提到的命名函数参数。里面使用了python的命名参数的例子。在ES6中,我们可以通过解构来实现这个命名函数参数.

1
2
3
4
5
6
7
8
function sum ({
a = 1,
b = 2
}) {
return a + b;
}

sum({b: 3});

建议:

  1. 如果函数超过三个参数,那么我们应该一直使用对象传参
  2. 形成习惯:如果你的参数是callback=>cb, array=> arr, value => v

Destructuring & Restructuring

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
var default = {
url: 'http://some.base.url/api',
method: 'post',
headers: [
'Content-Type: text/plain'
]
}

console.log(default);
var setting = {
url: 'http://some.base.url/api/1',
data: 42,
callback: funciton() {}
}

// 合并两个对象,带默认值
// 但是这样的作法存在问题
// 1. 依赖外部库
// 2. 需要文档才能看得懂
// 我们可以使用解构重构这部分的代码
ajax( _.extend({}, default, setting));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function ajaxOption({
url = 'http://some.base.url/api',
methods = 'post',
data,
callback,
headers: [
header0 = 'Content-Type: text/plain',
...otherHeaders
] = []
} = {}) {
return {
url, method, data, callback,
headers: [
header0,
...otherHeaders
]
}
}

array destructuring.md

Posted on 2020-04-12 | In JavaScript_The Recent Parts

array destructuring

destructuring

decomposing a structure into its individual parts

解构解决了两件事

  1. 从结构化的数据批量提取对应的数据, 并且直接把值赋予变量(在我们处理接口返回值的时候尤为好用)
  2. 便捷的给我们的数据赋予初始值, 不用再写类似这样的三元表达式了: a = a === undefiend ? defaultValue: value;
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var [
    {
    name: firstname,
    email: firstemil = 'nobody@none.com'
    },
    {
    name: secondname,
    email: secondemil = 'nobody@none.com'
    }
    ] = getSomeRecords();

Refactoring Code Using Destructuring

1
2
3
4
5
6
7
// before
var getData = () => [1, 2, 3];
var data = getData()

let a = data[0];
let b = data[1];
let c = data[2];
1
2
3
4
5
// after
var getData = () => [1, 2, 3];
var data = getData()

let [a, b, c] = [...data];

Spread Operator & Declaring Destrutured

…运算符解决了什么问题?我们不需要去管我们没有显式的指示出来的变量。只要它传了, 那么剩下的我都用…运算符去收集和处理。把不确定性可以更好的管理起来。

1
2
3
4
5
6
7
// before
var getData = () => [1, 2, 3];
var data = getData()

let a = data[0];
let b = data[1];
let c = data[2];
1
2
3
4
5
6
7
// after
var getData = () => [1, 2, 3];
var data = getData();

let temp;
// 先把data-> temp -> 执行解构
let [a, b, c] = temp = [...data];

Declaration & Assignment

1
2
3
4
5
6
7
8
9
// before
var getData = () => [1, 2, 3];
var data = getData()

var o = {};

o.a = data[0];
o.b = data[1];
o.c = data[2];
1
2
3
4
5
6
7
8
// after
var getData = () => [1, 2, 3];
var data = getData();

let temp;
var o = {};
// 先把data-> temp -> 执行解构
[o.a, o.b, o.c] = temp = [...data];

comma separation

解决的问题是: 我需要跳过其中一个元素,完成解构

1
2
3
4
5
6
7
// before
var getData = () => [1, 2, 3];
var data = getData()

let a = data[0];
// let b = data[1];
let c = data[2];
1
2
3
4
5
6
7
// after
var getData = () => [1, 2, 3];
var data = getData();

let temp;
// 先把data-> temp -> 执行解构
let [a, , c] = temp = [...data];

交换两个元素的值

1
2
3
4
5
6
7
8
9
//before
var x = 10;
var y = 20;

{
let temp = x;
x = y;
y = temp;
}
1
2
3
4
var x = 10;
var x = 20;

[y, x] = [x, y];

Parameter Arrays

解构同样可以使用在函数的参数中, 当然,在ES6中,直接支持了函数参数的默认值

1
2
3
4
5
6
7
8
// before
function data (tmp = []) {
var [
first,
second,
third
] = tmp;
}
1
2
3
4
// before
function data ([first, second, third] = []) {

}

Nested Array Destructuring

使用解构赋值的时候,一定要注意,是否会触发类型错误, 给一个默认值是一个很棒的方法。

1
2
3
4
5
6
7
8
9
// before
var getData = () => [1, [2, 3], 4];
var data = getData() || [];
var data2 = data[1]

let a = data[0];
let b = data2[0];
let c = data2[1];
let b = data[2];
1
2
3
// after
var getData = () => [1, [2, 3], 4];
var data = getData()

sass.md

Posted on 2020-04-12 | In fcc
  1. 变量

    1
    2
    3
    4
    5
    6
    7
    // 定义
    $main-fonts: Arial, sans-serif;
    $secound-color: ;
    // 使用
    p {
    color: $headings-color;
    }
  2. 嵌套这个很简单就不说了。但是记得&符号

  3. Mixin:可重用代码段

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 定义
    @mixin box-shadow($x, $y, $blur, $c){
    -webkit-box-shadow: $x, $y, $blur, $c;
    -moz-box-shadow: $x, $y, $blur, $c;
    -ms-box-shadow: $x, $y, $blur, $c;
    box-shadow: $x, $y, $blur, $c;
    }
    // 使用
    div {
    @include box-shadow(0px, 0px, 4px, #fff)
    }
  4. if-else分支语句
    该分支语句只能用在mixin里

而这个最大的作用就是控制主题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@mixin make-bold($bool) {
@if $bool == true {
font-weight: bold;
}
}

@mixin text-effect($val) {
@if $val == danger {
color: red;
}
@else if $val == alert {
color: yellow;
}
@else if $val == success {
color: green;
}
@else {
color: black;
}
}
  1. for循环

    1
    2
    3
    4
    // scss网格布局
    @for $i from 1 through 12 {
    .col-#{$i} { width: 100%/12 * $i; }
    }
  2. each循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // 迭代数组
    @each $color in blue, red, green {
    .#{$color}-text {color: $color;}
    }

    @each $color in blue,black,red {
    .#{$color}-bg {background: $color;}
    }

    // 迭代类对象
    $colors: (color1: blue, color2: red, color3: green);

    @each $key, $color in $colors {
    .#{$color}-text {color: $color;}
    }
  3. while循环

    1
    2
    3
    4
    5
    $x: 1;
    @while $x< 13 {
    .col-#{$x} { width: 100%/12 * $x;}
    $x: $x + 1;
    }
  4. 命名规范
    使用下划线命名: _mixin.scss

    1
    2
    // 引入
    @import 'mixin'
  5. extend 元素重用样式

1
2
3
4
5
6
7
8
9
10
11
.panel{
background-color: red;
height: 70px;
border: 2px solid green;
}

.big-panel{
@extend .panel;
width: 150px;
font-size: 2em;
}
<123…7>

Hawei

Fullstack Engineer

61 posts
16 categories
3 tags
RSS
© 2022 Hawei
Powered by Hexo
|
Theme — NexT.Muse v5.1.4