前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)

前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)

    • 前言
    • 定义 Model
    • connect 起来
    • 更新state
    • 拥抱变化
    • 主题切换
    • 更换页面
    • 获取当前设备类型
    • 编写武学选择

前言

www

定义 Model

完成 UI 后,现在开始处理数据和逻辑。
dva 通过 model 的概念把一个领域的模型管理起来,包含同步更新 state 的 reducers,处理异步逻辑的 effects,订阅数据源的 subscriptions 。
上节导航切换时,打印的当前id,现在我们同步更新到model中。
在models文件夹下新建文件bzmain.js,并定义menuId状态,初始化为‘1‘,并在reducers中编写更新state的方法’changeData‘。

export default {
  namespace: 'bzmain',
  state: {
    namespace: 'bzmain',
    menuId: '1',
  },
  effects: {
  },
  reducers: {
    'changeData'(state, {payload}) {
      return {...state, ...payload}
    },
  },
};
  • namespace 表示在全局 state 上的 key
  • state 是初始值,在这里是空数组
  • reducers 等同于 redux 里的 reducer,接收 action,同步更新 state
  • effects 处理异步逻辑

修改index.js,载入这个model

// 3. Model
app.model(require('./models/bzmain').default);

connect 起来

如何将model和component关联起来,dva 提供了 connect 方法,就是 react-redux 的 connect 。
编辑 routes/BzMain.js,修改部分如下:

...
import {connect} from 'dva';
...
...
export default connect(({bzmain}) => ({
  bzmain,
}))(BzMain);
...

更新state

handleMenuSelect方法中,接收到的id,来更新model中的menuId

...
  function handleMenuSelect(id) {
    dispatch({
      type: 'bzmain/changeData',
      payload: {
        menuId: id,
      },
    })
  }
...

拥抱变化

BzMain.js中接收model中的状态

...
const BzMain = ({dispatch, bzmain}) => {
  const {namespace, menuId} = bzmain;
...

并在Content展示当前id

...
      
        
当前的导航id:{menuId}
...

观察效果:
前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)_第1张图片
后面定义不同的子页面的时候,就通过这样来改变Content 中的内容了。

主题切换

依样画葫芦,实现导栏的暗黑风格和亮白风格的切换,bzmain.js定义themeFlag主题标志;BzMain.js接收,定义方法handleSwitchChange,方法中根据接收参数改变bzmain.js的themeFlag,然后将themeFlag和方法传递给子组件BzMenu.js,在BzMenu.js中接收,并增加切换主题的开关,调用此方法,传递当前开关状态,并且还要根据接收的themeFlag开关状态,同步修改各元素的样式或属性,最终实现切换主题,正式项目中也可以多弄几个主题,把开关改成下拉列表进行主题选择。
另外,为了保证刷新页面能保存上次的themeFlag开关状态,我们也将其存在localStorage中,并在组件刷新时从localStorage读取。

bzmain.js

export default {
  namespace: 'bzmain',
  state: {
    namespace: 'bzmain',
    themeFlag: 'true',
    menuId: '1',
  },
  effects: {
  },
  reducers: {
    'changeData'(state, {payload}) {
      return {...state, ...payload}
    },
  },
};

BzMain.js

import React from 'react';
import BzMenu from '../components/BzMenu';
import {Layout} from 'antd';
import style from './BzMain.less';
import {connect} from 'dva';
const {Header, Content, Footer} = Layout;

const BzMain = ({dispatch, bzmain}) => {
  const {namespace, menuId} = bzmain;
  const themeFlag = localStorage.getItem('themeFlag');
  function handleSwitchChange(value) {
    localStorage.setItem('themeFlag', value);
    dispatch({
      type: namespace + '/changeData',
      payload: {
        themeFlag: value,
      },
    })
  }
  function handleMenuSelect(id) {
    dispatch({
      type: namespace + '/changeData',
      payload: {
        menuId: id,
      },
    })
  }
  return (
    
      
当前的导航id:{menuId}
BaoZouApp ©2020 Created by 泡泡糖
) }; // export default BzMain; export default connect(({bzmain}) => ({ bzmain, }))(BzMain);

BzMenu.js:
这里增加了用PropTypes 做数据校验。

import React from 'react';
import {Col, Menu, Row, Switch} from 'antd';
import {AppstoreOutlined, UserOutlined} from '@ant-design/icons';
import style from './BzMenu.less';
import PropTypes from 'prop-types';

const BzMenu = ({onMenuSelect, onSwitchChange, themeFlag}) => {
  const list = [{
    key: '1',
    data: '真元',
  },{
    key: '2',
    data: '基础',
  },{
    key: '3',
    data: '装备',
  },{
    key: '4',
    data: '藏经阁',
  },{
    key: '5',
    data: 'NPC查找',
  },
  ];
  return (
    
      
        {""}
      
      
         onMenuSelect(value.key)}>
          {
            list.map((item) => {
              return (
                } className={style.item}>
                  {item.data}
                
              );
            })
          }
        
      
      
         onSwitchChange(value)} checked={themeFlag}/>
      
      
        
      
    
  );
};
BzMenu.propTypes = {
  onMenuSelect: PropTypes.func.isRequired,
  onSwitchChange: PropTypes.func.isRequired,
  themeFlag: PropTypes.string.isRequired,
};
export default BzMenu;

BzMenu.less

:global {
  .ant-menu-item {
    .anticon-appstore {
      margin-right: calc(~"100vw / 50 - 6px");
    }
  }
  .ant-switch {
    border-color: white;
  }
}
.item {
  padding: 0 calc(~"100vw / 50 - 2px");
}
.menu {
  padding-left: calc(~"100vw / 5 - 60px");
}
.img {
  height: 50px;
  background-color: white;
  padding: 5px;
}

电脑效果:
前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)_第2张图片
手机效果:前端技术学习记录:react+dvajs+ant design实现暴走计算器的页面重构(二)_第3张图片

更换页面

通过Content下隐藏和显示,以此给出用户更换页面的体验。
在routes文件夹下,新建content文件夹,在content文件夹下新建各个子页面,分别为
Basics.js

import React from 'react';
import PropTypes from 'prop-types';

const Basics = ({hiddenFlag}) => {
  return (
    
基础页面
); }; Basics.propTypes = { hiddenFlag: PropTypes.bool.isRequired, }; export default Basics;

Energy.js

import React from 'react';
import PropTypes from 'prop-types

你可能感兴趣的:(学习记录,reactjs,前端,git,webstorm)