echarts中resize事件监控实例入门redux

背景

项目背景是通过react+redux完成不同组件之间的通信。
左侧导航栏有收缩时候右侧内容中echarts图表能监测到此动作,并做resize动作,具体实现效果
在这里插入图片描述
我们知道监听echartsresize()方法可以通过window的窗口监听事件

window.addEventListener('resize', this.chartResize)

但是这里可以看出,窗口大小是没有变化的,只是图表局部DOM的宽度发生了变化,所以window的窗口监听事件并不生效。可以通过监听当前图表DOM的宽高来实现,或者我们从侧边的导航来着手。
这里导航和echarts是两个不同的组件,且不是直接的父子组件的关系,因此考虑使用redux来实现

实现

redux,react-redux

下载所需依赖包

npm i redux react-redux

actions

从名字看的出来,actions就是为了存储我们的动作类型
./src目录下新建./src/actions/index.js,内容

// actions/index.js
export const MenuCollapse = 'MenuCollapse'

用来存储所有可能派发(dispatch)的类型(type)。

reducer

./src目录下新建./src/reducers/index.js

import { MenuCollapse } from '../actions'

const initState = {
  collapseVal: false
}

const AppReducer = (state=initState, action) => {
  switch (action.type) {
    case MenuCollapse: {
      return {
        collapseVal: action.value
      }
    }
    default: {
      return state
    }
  }
}

export default AppReducer

store

从名字我们看出,store就是用来存储的,存储什么呢?存储我们的state
./src目录下新建./src/store/index.js

import { createStore } from 'redux'
import AppReducer from '../reducers'

const store = createStore(AppReducer)

export default store

这里可以模拟一下createStore源码来更清晰的理解一下store的作用

// 以下代码示例来自redux官方教程
const createStore = (reducer) => {
  let state;
  let listeners = [];
  // 用来返回当前的state
  const getState = () => state;
  // 根据action调用reducer返回新的state并触发listener
  const dispatch = (action) => {
      state = reducer(state, action);
      listeners.forEach(listener => listener());
    };
  /* 这里的subscribe有两个功能
   * 调用 subscribe(listener) 会使用listeners.push(listener)注册一个listener
   * 而调用 subscribe 的返回函数则会注销掉listener
   */
  const subscribe = (listener) => {
      listeners.push(listener);
      return () => {
        listeners = listeners.filter(l => l !== listener);
      };
    };

  return { getState, dispatch, subscribe };
};

这里我的项目内容比较简单,所以reducer我只写了一个文件,如果你需要写多个reducer模块,参考下面这种store内容

import { createStore, combineReducers } from 'redux'
import xxxReducer from '../reducers/xxx.js'
import kkkReducer from '../reducers/kkk.js'

const reducer = combineReducers({ 
	xxx: xxxReducer,
	kkk: kkkReducer
})
// 这里需要对象的形式

const store = createStore(reducer)

export default store

store注入项目

index.js文件中,引入我们的store

import { Provider } from 'react-redux'
import store from './store'

ReactDOM.render(
  <Provider store={store}>
     <Router>
       <App />
     </Router>
  </Provider>,
  document.getElementById('root')
)

派发事件dispatch

在导航组件app-menu.js中,在发生收缩动作时派发事件

import store from '../../store'
import { MenuCollapse } from '../../actions'

/* 是否收起菜单栏 */
 menuToLeft = () => {
   store.dispatch({type: MenuCollapse, value: false})
   this.setState({ menuWidth: 0 })
 }
 menuToRight = () => {
   store.dispatch({type: MenuCollapse, value: true})
   this.setState({ menuWidth: '220px' })
 }

或者我们用connect

import { connect } from 'react-redux'
import { MenuCollapse } from '../../actions'

menuToLeft = () => {
  this.props.menuCollapseDispatch(false)
  this.setState({ menuWidth: 0 })
}
menuToRight = () => {
  this.props.menuCollapseDispatch(true)
  this.setState({ menuWidth: '220px' })
}


const mapStateToProps = () => { return {} }
// 从名字也能看出来就是将dispatch映射到了props上
const mapDispatchToProps = dispatch => {
  return {
    menuCollapseDispatch: value => dispatch({type: MenuCollapse, value})
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(AppMenu)

监听store中值

此时我们收缩导航store里面的值已经发生变化了,我们可以在其他组件中通过

store.getState()

来得到,但是这里我们是需要监听这个值发生变化做下一步操作,用到的是subscribe()
在图表组件line-bar-show.js文件中

componentDidMount () {
    window.addEventListener('resize', this.chartResize)
    store.subscribe(() => {
      // store.subscribe用来监听store中state
      // 菜单动画有300ms,所以延迟器时长必须大于等于这个时间
      this.chartResize()
    })
  }
  chartResize = () => {
    this.echartResizeTimer = setTimeout(() => {
      this.echartsObj && this.echartsObj.resize()
    }, 300)
  }
  componentWillUnmount () {
    window.removeEventListener('resize', this.chartResize)
    this.echartResizeTimer = null
    this.loopTooltipTimer = null
  }

注意: 这里需要注意的菜单收缩动画时间为300ms,但是值的变化时瞬间的,所以需要在监听到值变化以后延迟300ms再resize图表。
这里的几个变量我都没有定义在组件的state中,而是直接定义在组件上,跟state平级,所以这里是通过=来赋值的,而不是通过setState()来赋值。

版本号

"echarts": "^4.7.0",
"redux": "^4.0.5",
"react-redux": "^7.2.2",
问题: .echartsecharts.resize不起作用 回答: 当在Vue同时引入两个以上的echarts组件时,使用window.onresize方法只会对最后一个组件的图表产生效果。这是因为组件加载顺序导致的\[2\]。为了解决这个问题,可以将window.onresize监听放到父组件执行,并调用子组件的方法来重新调整图表的大小\[2\]。另外,还有一种常见的情况是,echarts图表无法自适应浏览器宽高。解决这个问题的方法是,不能给echarts的容器设置固定的宽高,而是要使用百分比和vh来设置宽度和高度,并配合使用resize方法来实现根据浏览器大小而改变大小的功能\[3\]。 #### 引用[.reference_title] - *1* *2* [vue使用echartsresize无效的3种情况分析及解决办法](https://blog.csdn.net/weixin_42038290/article/details/125864346)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [EChartsresize失效原因以及使用方法](https://blog.csdn.net/weixin_43606158/article/details/96457167)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值