自言自语
感觉中大型公司用的技术栈都是偏向React,可能Vue比较适合入门以及小项目吧。
相信以后我也会知道React的好处的,努力学习!
本日简短总结
- 找出自己的JS的知识盲点
- 通过井字棋DEMO了解React
- 学习React核心概念
- 看了一下Ant Design Mobile
明日安排
- 看导师给的材料
丑陋的知识盲区
导师给了我一份题目去做,了解一下我前端的基础,得分是35/50。
主要有以下几点不牢固:
- 变量提升
- 我记住了变量声明后会被提升到顶端,但我忘记了此时变量是undefined,要定义。
- 数据类型转换
- Math.floor,负数要向下取整,比如说-45.01/-45.05要变成46
- NaN == NaN是false,NaN是不确定数字,两个不确定数字不可能相等
- isNaN判断传入的参数是否为数字,为数字返回false,否则返回falsetrue
- 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值。
- window.onload
- 所有东西加载完成(包括js等资源)才执行
- 而不是DOM加载完成后
React学习
-
JSX
- 踩坑点
- 带有“-”的css属性要用驼峰命名法
- 踩坑点
-
React组件需要继承React.Component
- 继承的类中需要重写render方法
- 该方法返回一个React组件(JSX)
- React.createElement(标签名, payload) = <标签名>(JSX)
- 继承的类中需要重写render方法
-
React类中声明方法可以通过this调用
-
插值表达式从Vue的{{ }}变成{}
-
组件列表要加key,方便DOM树更新以及防止报错
-
ES6补充
- 类构造器constructor,与继承React组件一起用
- 调用父类构造函数super
- 类构造器constructor,与继承React组件一起用
// constructor示例
constructor(props) {
super(props)
// 响应式数据请往里面塞
this.state = {
value: null
}
}
-
使用this.setState({ 属性: '值‘ }) 可以改变state中的数据,并且是响应式的
-
生命周期
- componentDidMount()
- componentWillUnmount()
本日学习代码(井字棋)
拓展功能:
在游戏历史记录列表显示每一步棋的坐标,格式为 (列号, 行号)。√
在历史记录列表中加粗显示当前选择的项目。√
使用两个循环来渲染出棋盘的格子,而不是在代码里写死(hardcode)。√
以下是未完成的拓展功能(我觉得上面的练习已经够了所以没必要)
添加一个可以升序或降序显示历史记录的按钮。
每当有人获胜时,高亮显示连成一线的 3 颗棋子。
当无人获胜时,显示一个平局的消息。
function Square(props) {
let style = {};
console.log(props)
if(props.index == props.now) {
style = {'fontWeight': 'bold'};
}
return (
<button
className="square"
onClick={props.onClick}
style={style}
>
{props.value}
</button>
);
}
class Board extends React.Component {
renderSquare(i) {
return (
<Square
key={i}
value={this.props.squares[i]}
onClick={() => this.props.onClick(i)}
now={this.props.now}
index={i}
/>
);
}
render() {
let board = [];
let createList = (initIndex) => {
let arr = [];
for(let i = initIndex; i < initIndex + 3 ; i ++){
arr.push(this.renderSquare(i));
}
return (
<div key={initIndex} className="board-row">{arr}</div>
)
}
for(let i = 0; i < 3; i ++){
board.push(createList(i*3));
}
return (
<div>
{board}
</div>
);
}
}
class Game extends React.Component {
constructor(props) {
super(props);
this.state = {
history: [
{
squares: Array(9).fill(null),
now: null
}
],
stepNumber: 0,
xIsNext: true
};
}
handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
if (calculateWinner(squares) || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? "X" : "O";
this.setState({
history: history.concat([
{
squares: squares,
now: i
}
]),
stepNumber: history.length,
xIsNext: !this.state.xIsNext
});
}
jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0
});
}
render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => {
const desc = move ?
'Go to move #' + move :
'Go to game start';
return (
<li key={move}>
<button onClick={() => this.jumpTo(move)}>{desc}</button>
</li>
);
});
let status;
if (winner) {
status = "Winner: " + winner;
} else {
status = "Next player: " + (this.state.xIsNext ? "X" : "O");
}
return (
<div className="game">
<div className="game-board">
<Board
squares={current.squares}
onClick={i => this.handleClick(i)}
now={current.now}
/>
</div>
<div className="game-info">
<div>{status}</div>
<ol>{moves}</ol>
</div>
<div>{'Now: ' + parseInt(current.now/3) + ',' + current.now%3 }</div>
</div>
);
}
}
// ========================================
ReactDOM.render(<Game />, document.getElementById("root"));
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
for (let i = 0; i < lines.length; i++) {
const [a, b, c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}