# react
# 起步
npm i creat-react-app -g
cerate-react-app demo
# 基本写法
import React, { Component,Fragment } from 'react'
class App extends Component {
render() {
return (
<Fragment>
<ul className="my-list">
<li>1</li>
<li>2</li>
</ul>
<div>1</div>
</Fragment>
)
}
}
export default App
# Fragment
相当于vue的template
# state
相当于vue data
在class中写
不可以直接改变this.state.xx的值,会有性能问题
改变
this.setState({
xx: xx
})
# innerhtml
dangerouslySetInnerHTML={{__html:item}}
# label for
htmlFor
# 组件通信
<Item content={item} index={index} delList={this.delList} />
this.props.xx接收
直接将方法传过去 不用发送事件
# props校验
import PropTypes from 'prop-types'
item为组件名
item.propTypes = {
name: PropTypes.string.isRequired,
content: PropTypes.string,
index: PropTypes.number,
delList: PropTypes.func
}
item.defaultProps= {
name: 'dd'
}
# ref
<input
value={this.state.inputValue}
onChange={this.inputChange.bind(this)}
ref={(input) => { this.input = input}}
/>
然后直接this.input使用即可 获取到了dom元素
# 优化更新
shouldComponentUpdate(nextProps,nextState){
if(nextProps.content !== this.props.content){
return true
}else{
return false
}
}
# transition
npm install react-transition-group --save
import { CSSTransition } from 'react-transition-group'
# dom
<CSSTransition
in={this.state.isShow} //用于判断是否出现的状态
timeout={2000} //动画持续时间
classNames="boss-text" //className值,防止重复
unmountOnExit //动画结束删除元素
>
<div>BOSS级人物-孙悟空</div>
</CSSTransition>
# css
.boss-text-enter{
opacity: 0;
}
.boss-text-enter-active{
opacity: 1;
transition: opacity 2000ms;
}
.boss-text-enter-done{
opacity: 1;
}
.boss-text-exit{
opacity: 1;
}
.boss-text-exit-active{
opacity: 0;
transition: opacity 2000ms;
}
.boss-text-exit-done{
opacity: 0;
}
多个
<TransitionGroup>
{
this.state.list.map((item, index) => {
return (
<CSSTransition
timeout={1000}
classNames='boss-text'
unmountOnExit
appear={true}
key={index + item}
>
<Item
content={item}
index={index}
deleteItem={this.delList.bind(this)}
/>
</CSSTransition>
)
})
}
</TransitionGroup>
# Redux
# ant-design
npm i antd
# 建store文件夹
index.js
import {createStore} from 'redux'
import reducer from './reducer'
const store = createStore(reducer)
export default store
reducer.js
import { CHANGE_INPUT, ADD_LIST, DEL_LIST} from './actionTypes'
const defaultState = {
inputValue: 'write something',
data: [
'早8点开晨会,分配今天的开发工作',
'早9点和项目经理作开发需求讨论会',
'晚5:30对今日代码进行review'
]
}
export default (state = defaultState, action) => {
console.log(state, action)
if (action.type === CHANGE_INPUT) {
let newState = JSON.parse(JSON.stringify(state))
newState.inputValue = action.value
return newState
} else if (action.type === ADD_LIST) {
let newState = JSON.parse(JSON.stringify(state))
newState.data.unshift(action.value)
newState.inputValue = ''
return newState
} else if (action.type === DEL_LIST) {
let newState = JSON.parse(JSON.stringify(state))
newState.data.splice(action.value, 1)
return newState
}
return state
}
actionTypes.js
export const CHANGE_INPUT = 'changeInput'
export const ADD_LIST = 'addList'
export const DEL_LIST = 'delList'
actionCreator.js
import { CHANGE_INPUT, ADD_LIST, DEL_LIST} from './actionTypes'
export const changeInputAction = value => ({
type: CHANGE_INPUT,
value
})
export const addList = value => ({
type: ADD_LIST,
value
})
export const delList = value => ({
type: DEL_LIST,
value
})
在需要的组件中
import store from './store'
import { changeInputAction, addList, delList } from './store/actionCreators'
this.state = store.getState()
// 订阅
store.subscribe(this.storeChange)
storeChange () {
this.setState(store.getState())
}
# 点击事件
clickBtn () {
store.dispatch(changeInputAction(value))
}
# ui分离
ui
import React from 'react';
import 'antd/dist/antd.css'
import { Input , Button , List } from 'antd'
const TodoListUI = (props) => {
return (
<div style={{margin:'10px'}}>
<div>
<Input
placeholder={props.inputValue}
style={{ width:'250px', marginRight:'10px'}}
onChange={props.inputChange}
value={props.inputValue}
/>
<Button
type="primary"
onClick={props.clickBtn}
>增加</Button>
</div>
<div style={{margin:'10px',width:'300px'}}>
<List
bordered
dataSource={props.data}
renderItem={(item, index)=>(<List.Item onClick={() => {props.deleteItem(index)}}>{item}</List.Item>)}
/>
</div>
</div>
);
}
export default TodoListUI;
js
render() {
return (
<TodoListUI
inputValue={this.state.inputValue}
inputChange={this.inputChange}
clickBtn={this.clickBtn}
data={this.state.data}
deleteItem={this.deleteItem}
/>
);
}
# axios存数据
在生命周期获取后dispatch然后reducre接收改变即可
# redux-thunk
npm i redux-thunk
import thunk from 'redux-thunk'
const store = createStore(
reducer,
applyMiddleware(thunk)
)
export const getTodoList = () => {
return (dispatch) => {
axios.get('http://rap2api.taobao.org/app/mock/243469/list').then(res => {
dispatch(getList(res.data.list))
})
}
}
store.dispatch(getTodoList())
# sage
不想整
# react-redux
provider包裹
组件connect一下
# react-router
npm i react-router-dom
# AppRouter.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import Index from './Pages/Index'
import List from './Pages/List'
function AppRouter() {
return (
<Router>
<ul>
<li><Link to="/">首页</Link></li>
<li><Link to="/list/111">列表</Link></li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/:id" component={List} />
</Router>
)
}
export default AppRouter
# 获取值
this.props.match中
# 重定向
this.props.history.push("/home/")
import { Link , Redirect } from "react-router-dom"; <Redirect to="/home/" />
# react-hooks
import React, { useState } from 'react';
function App() {
const [count, setCount] = useState(0)
return (
<div>
<p>click {count}</p>
<button onClick={() => {setCount(count+1)}}>click</button>
</div>
)
}
export default App;
# yarn
npm install -g yarn
yarn --version
Yarn 淘宝源安装,分别复制粘贴以下代码行到黑窗口运行即可
yarn config set registry https://registry.npm.taobao.org -g
yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sass -g
https://blog.csdn.net/idomyway/article/details/88411836
# next.js
yarn global add create-next-app
create-next-app my-project
cd my-project
yarn dev
# 支持引入css
yarn add @zeit/next-css
根目录新建next.config.js
const withCss = require('@zeit/next-css')
if(typeof require !== 'undefined'){
require.extensions['.css']=file=>{}
}
module.exports = withCss({})
# 导航
标签方式
import Link from 'next/link'
<Link href="/index">
<a><span className="header-logo">小小前端儿</span></a>
</Link>
js方式
import Router from 'next/router'
const handleClick = (e) => {
console.log(e)
if (e.key == 0) {
Router.push('/index')
} else {
Router.push('/blogList?id=' + e.key)
}
}
<Menu
mode="horizontal"
onClick={handleClick}
>
{
navArray.map((item) => {
return (
<Menu.Item key={item.Id}>
<Icon type={item.icon} />
{item.typeName}
</Menu.Item>
)
})
}
</Menu>
# 动态引入
import dynamic from 'next/dynamic'
import '../public/style/pages/index.css'
const DynamicRibbon = dynamic(
import('../assets/ribbon'),
{
ssr: false //这个要加上,禁止使用 SSR
}
)
<DynamicRibbon/>