alt

  • 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>
  )
}