后端仔的前端问题
  • 5
  • 新人请关照

有人搞定了iview-admin的柱状图数据获取到了但是未渲染的问题吗

主页面引用封装好的柱状图组件:

<chart-bar style="height: 300px;" :value="stores.bar.data" :text="$t('devicedistributedregion')"/>

已经成功从接口获取到数据,并绑定到了stores.bar.data,但是柱状图还是没有渲染,如下图:
image.png

封装好的子组件源码:

<template\>

<div ref\="dom" class\="charts chart-bar"\></div\>

</template\>

<script\>

import echarts from 'echarts'

import tdTheme from './theme.json'

import { on, off } from '@/libs/tools'

echarts.registerTheme('tdTheme', tdTheme)

export default {

name: 'ChartBar',

props: {

value: Object,

text: String,

subtext: String

},

data () {

return {

dom: null

}

},

methods: {

resize () {

this.dom.resize()

}

},

mounted () {

this.$nextTick(() \=> {

let xAxisData \= Object.keys(this.value)

let seriesData \= Object.values(this.value)

let option \= {

title: {

text: this.text,

subtext: this.subtext,

x: 'center'

},

xAxis: {

type: 'category',

data: xAxisData

},

yAxis: {

type: 'value'

},

series: \[{

data: seriesData,

type: 'bar'

}\]

}

this.dom \= echarts.init(this.$refs.dom, 'tdTheme')

this.dom.setOption(option)

on(window, 'resize', this.resize)

})

},

beforeDestroy () {

off(window, 'resize', this.resize)

}

}

</script\>

之前我开发饼图的时候,也遇到过类似的问题,把封装好的饼图组件修改成如下则成功解决:

<template>
  <div ref="dom" class="charts chart-pie"></div>
</template>

<script>
import echarts from 'echarts'
import tdTheme from './theme.json'
import { on, off } from '@/libs/tools'
echarts.registerTheme('tdTheme', tdTheme)
export default {
  name: 'ChartPie',
  props: {
    value: Array,
    text: String,
    subtext: String
  },
  data () {
    return {
      dom: null
    }
  },
  methods: {
    resize () {
      this.dom.resize()
    },

    drawPie(){
        this.$nextTick(() => {
        let legend = this.value.map(_ => _.name)
        let option = {
          title: { 
            text: this.text,
            subtext: this.subtext, 
            x: 'center'
          },
          tooltip: {  
            trigger: 'item',
            formatter: '{a} <br/>{b} : {c} ({d}%)',
          },
          legend: { 
            orient: 'vertical',
            left: 'left',  
            data: legend
          },
          series: [
            {
              name: this.subtext,
              type: 'pie',  
              radius: '55%', 
              center: ['50%', '60%'],
              data: this.value, 
              itemStyle: { 
                emphasis: {
                  shadowBlur: 10, 
                  shadowOffsetX: 0, 
                  shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
              }
            }
          ]
        }
        this.dom = echarts.init(this.$refs.dom, 'tdTheme')
        this.dom.setOption(option)
        on(window, 'resize', this.resize)
      })
    }
  },
  mounted () {
    this.drawPie();
  },

  beforeDestroy () {
    off(window, 'resize', this.resize)
  },

  watch: {
      value () {
          this.drawPie();
      }
  }

}
</script>

之后我依照修改饼图的经验,修改封装的柱状图组件,如下:

<template>
  <div ref="dom" class="charts chart-bar"></div>
</template>

<script>
import echarts from 'echarts'
import tdTheme from './theme.json'
import { on, off } from '@/libs/tools'
echarts.registerTheme('tdTheme', tdTheme)
export default {
  name: 'ChartBar',
  props: {
    value: Object,
    text: String,
    subtext: String
  },
  data () {
    return {
      dom: null
    }
  },
  methods: {
    resize () {
      this.dom.resize()
    },

    drawBar(){
      this.$nextTick(() => {
        let xAxisData = Object.keys(this.value)
        let seriesData = Object.values(this.value)
        let option = {
          title: {
            text: this.text,
            subtext: this.subtext,
            x: 'center'
          },
          xAxis: {
            type: 'category',
            data: xAxisData
          },
          yAxis: {
            type: 'value'
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {            // 坐标轴指示器,坐标轴触发有效
                type: 'shadow'        // 默认为直线,可选为:'line' | 'shadow'
            }
          },
          series: [{
            data: seriesData,
            type: 'bar'
          }]
        }
        this.dom = echarts.init(this.$refs.dom, 'tdTheme')
        this.dom.setOption(option)
        on(window, 'resize', this.resize)
      })
    }
  },

  mounted () {
    this.drawBar();
  },
  beforeDestroy () {
    off(window, 'resize', this.resize)
  },

  watch: {
    value(){
      this.drawBar();
    }
  }
}
</script>

这时候没成功,百度了下,大概是因为此时value是对象,要监听对象的变化不能这样写,需要用到深度监听,于是我把watch改成如下:

value:{
      handle(newVal,oldVal) {
        if(JSON.stringify(newVal)===JSON.stringify(oldVal)){
          console.log('value not change');
          return
        }
        console.log('value change');

        this.init();
        console.log('after resize');
      },
      deep:true,
    }

但是还是没成功,我懵了,不知道该如何整了?有大神用过iview-admin的柱状图吗?求指教!!!

原来的iview-admin好像不维护了,后端boy临时接手这么个东西还要加入数据可视化的模块真的难受啊。
阅读 345
评论
    2 个回答
    后端仔的前端问题
    • 5
    • 新人请关照

    迫不得已,采取了偷懒的方法,其实副标题subtext对我来说无所谓,于是我就改变监听策略,放弃监听Object的value,而是直接监听String的subtext,自然而然也就没有深度监听的问题了。

    修改封装的柱状图组件的watch方法如下:

    watch: {
        subtext(){
          this.drawBar();
        }
      }

    这种方式的一个问题是在主页面调用时必须得变更subtext的值。

    不知道大家还有没有更好的方法,其实更好的方法我觉得还是直接监听value,可惜我搞不定。

    评论 赞赏
      Ciao
      • 69

      更改数据时使用 this.$set 好像就可以了

      评论 赞赏