- reducers
- actions
- index(store)
// todo.js
import produce from 'immer'
import { TODO_ADD,TODO_STATUS,TODO_DEL,TODO_EDIT } from '../actions'
const initState = {
list:[
{id:1,status:0,task:'吃饭'},
{id:2,status:0,task:'睡觉'},
{id:3,status:1,task:'游戏'},
{id:4,status:1,task:'打豆豆'}
]
}
export default (state=initState,{type,payload})=>{
// console.log('有信号来了', type, payload)
return produce(state,state=>{
switch(type){
case TODO_ADD:
state.list.push(payload)
break
case TODO_STATUS:
state.list.map(ele=>{
payload === ele.id && (ele.status = (ele.status+1)%2)
})
break
case TODO_DEL:
state.list = state.list.filter(ele=>payload !== ele.id)
break
case TODO_EDIT:
state.list.map(ele=>{
ele.id === payload.id && (ele.task = payload.task)
})
break
}
})
}
// todoAjax.js
import produce from 'immer'
import { TODO_LIST,TODO_COUNT } from '../actions'
const initState = {
list:[],
//监听TODO_COUNT 消息 count一改变 就重新请求数据
count:1
}
export default (state=initState,{type,payload})=>{
// console.log('有信号来了', type, payload)
return produce(state,state=>{
switch(type){
case TODO_LIST:
state.list = payload
break
case TODO_COUNT:
state.count ++
break
}
})
}
// actions.js
import { fetchTodoList,fetchTodoAdd,fetchTodoDel,fetchTodoEdit,fetchTodoStatus } from '@/api'
// actions 生成器
export const CHANGE_NUM = 'CHANGE_NUM'
export const changeNum = (num) =>{
return { type: CHANGE_NUM, payload: num }
}
export const TODO_COUNT = 'TODO_COUNT'
export const TODO_ADD = 'TODO_ADD'
export const addTodo = (task) =>{
return { type: TODO_ADD, payload: {id:Math.random(),status:0,task} }
}
export const TODO_STATUS = 'TODO_STATUS'
export const statusTodo = (id) =>{
return { type: TODO_STATUS, payload: id }
}
export const TODO_DEL = 'TODO_DEL'
export const delTodo = (id) =>{
return { type: TODO_DEL, payload: id }
}
export const TODO_EDIT = 'TODO_EDIT'
export const editTodo = (payload) =>{
return { type: TODO_EDIT, payload }
}
export const TODO_LIST = 'TODO_LIST'
// 这里我们使用了thunk 做处理 你实现了异步请求
export function listTodo(params) {
return function(dispatch) {
// 调接口(redux默认不支持异步的action)
fetchTodoList(params).then(res=>{
// 把后端api数据派发到store
// console.log('res', res.data)
dispatch({ type: TODO_LIST, payload:res.data })
})
}
}
export function toAddTodo(msg) {
return function(dispatch) {
fetchTodoAdd({msg}).then(()=>{
// 添加todo成功
// dispatch(listTodo())
dispatch({type:'TODO_COUNT'})
})
}
}
export function toDelTodo(id) {
return function(dispatch) {
fetchTodoDel({id}).then(()=>{
// dispatch(listTodo())
dispatch({type:'TODO_COUNT'})
})
}
}
export function toEditTodo({id,msg,isdone}) {
return function(dispatch) {
fetchTodoEdit({id,msg,isdone}).then(()=>{
// dispatch(listTodo())
dispatch({type:'TODO_COUNT'})
})
}
}
export function toStatusTodo({msg,isdone}) {
return function(dispatch) {
fetchTodoStatus({msg,isdone}).then(()=>{
// dispatch(listTodo())
dispatch({type:'TODO_COUNT'})
})
}
}
import { fetchLogin,
fetchUserInfo,
fetchAddMenu,
fetchMenuList,
fetchAddRole,
fetchRoleList,
fetchRoleInfo,
fetchEditRole,
fetchAddUser,
fetchGetUpdUser,
fetchGetUserList
} from '@/api'
// react_admin
// 登录逻辑
export const ADMIN_LOGIN = 'ADMIN_LOGIN'
export const ADMIN_LOGINOUT = 'ADMIN_LOGINOUT'
export const ADMIN_USER_INFO = 'ADMIN_USER_INFO'
export const ADMIN_MENU_LIST = 'ADMIN_MENU_LIST'
export const ADMIN_DONE = 'ADMIN_DONE'
export const ADMIN_RESET = 'ADMIN_RESET'
export const ADMIN_ROLE_LIST = 'ADMIN_ROLE_LIST'
export const ADMIN_ROLE_Info = 'ADMIN_ROLE_Info'
export const ADMIN_USER_LIST = 'ADMIN_USER_LIST'
export function login(data){
return dispatch=>{
fetchLogin(data).then(res=>{
console.log(res);
if(res.token){
dispatch({type:ADMIN_LOGIN,payload:res.token})
}
})
}
}
export function loginOut(){
return {type:ADMIN_LOGINOUT,payload:''}
}
export function getUserInfo(data){
return dispatch=>{
fetchUserInfo(data).then(res=>{
dispatch({type:ADMIN_USER_INFO,payload:res})
})
}
}
export function addMenu(data){
return dispatch=>{
fetchAddMenu(data).then(()=>{
dispatch({type:ADMIN_DONE,payload:''})
})
}
}
export function getMenuList(){
return dispatch=>{
fetchMenuList({}).then((res)=>{
console.log(res);
dispatch({type:ADMIN_MENU_LIST,payload:res})
})
}
}
export function addRole(data){
data.menus = data.auths.join(';')
console.log(data);
return dispatch=>{
fetchAddRole(data).then((res)=>{
console.log(res);
dispatch({type:ADMIN_DONE,payload:''})
})
}
}
export function editRole(data){
data.menus = data.auths.join(';')
return dispatch=>{
fetchEditRole(data).then(()=>{
dispatch({type:ADMIN_DONE,payload:''})
})
}
}
export function getRoleList(){
return dispatch=>{
fetchRoleList().then((res)=>{
dispatch({type:ADMIN_ROLE_LIST,payload:res.list})
})
}
}
export function getRoleInfo(id){
console.log(id);
return dispatch=>{
fetchRoleInfo(id).then((res)=>{
let roleInfo = res.res[0];
roleInfo.auths = roleInfo.menus.split(';').filter(ele=>ele)
// console.log(roleInfo);
dispatch({type:ADMIN_ROLE_Info,payload:roleInfo})
})
}
}
export function addUser(data){
return dispatch=>{
fetchAddUser(data).then((res)=>{
console.log(res);
dispatch({type:ADMIN_DONE,payload:''})
})
}
}
export function getUserList(data){
return dispatch=>{
fetchGetUserList(data).then((res)=>{
console.log(res);
dispatch({type:ADMIN_USER_LIST,payload:res.userlist})
})
}
}
export function updStatus(data){
return dispatch=>{
fetchGetUpdUser(data).then(()=>{
dispatch({type:ADMIN_DONE,payload:''})
})
}
}
export function reset(){
return {type:ADMIN_RESET,payload:''}
}
// index.js
// 怎么学习? “三” 个 三
// createStore、 combineReducers 、 applyMiddleware
// 单一数据源 store是只读的 使用reducer(一个工具)纯函数修改store
// 三个概念 : State Action Reducer
import { createStore,combineReducers,applyMiddleware,compose } from 'redux'
// 解决异步问题
import thunk from 'redux-thunk'
import study from './reducers/study'
import todo from './reducers/todo'
import todoAjax from './reducers/todoAjax'
import admin from './reducers/admin'
import logger from 'redux-logger'
// 合并子store
const reducer = combineReducers({study,todo,admin,todoAjax})
const store = createStore(
reducer,
compose(
applyMiddleware(thunk),
applyMiddleware(logger)
)
)
export default store
// 页面 todo.jsx
import { useSelector,useDispatch } from 'react-redux'
import { useState,useMemo } from 'react'
import { addTodo,statusTodo,delTodo,editTodo } from '../../store/actions'
import './style.css'
const TodoPanel = props => {
const { title,list,status } = props
const dispatch = useDispatch()
console.log(list);
return (
<div className="panel">
<div className="panel_title">
<span>{ title }</span>
<span>{ list.length }</span>
</div>
{
list.map(ele=>(
<div className={`panel_list ${status?'panel_list-done':''}`} key={ele.id}>
<span onClick={()=>dispatch(statusTodo(ele.id))}></span>
<span>
{
status
? <input
value={ele.task}
disabled
/>
: <input
value={ele.task}
onChange={(e)=>dispatch(editTodo({id:ele.id,task:e.target.value}))}
/>
}
</span>
<span onClick={()=>dispatch(delTodo(ele.id))}></span>
</div>
))
}
</div>
)
}
export default () => {
const list = useSelector(state=>state.todo.list)
const dispatch = useDispatch()
const [list1, list2] = useMemo(()=>{
const list1 = list.filter(ele=>!ele.status)
const list2 = list.filter(ele=>ele.status)
return [list1, list2]
}, [list])
const [task,setTask] = useState('')
// 处理添加todo
const confirm = (e) => {
if(e.keyCode === 13){
dispatch(addTodo(task))
setTask('')
}
}
return (
<div className='app'>
<div className="app_bar">
<div>
<span>TODOS</span>
<input
type="text"
value={task}
onChange={e=>setTask(e.target.value)}
onKeyUp={e=>{confirm(e)}}
placeholder="添加todos" />
</div>
</div>
<TodoPanel list={list1} title='正在进行' />
<TodoPanel list={list2} title='已经完成' status />
<div className="app_bot">此TODO由GP7班制作完成</div>
</div>
)
}