vue父组件异步传递prop到子组件echarts画图问题踩坑总结

  效果图:

  大致思路:考虑到5张图都是折线图,所以准备用一个子组件承接echarts画图,然后父组件通过prop传递不同数据来展示不同的图

踩坑问题:

1、引入line子组件,画了5个元素,但是只显示一个

  原因:id重复

  解决方案:prop传递不同id名

2、父组件传递的数据在子组件报错

  这里情况比较特殊,我用父组件数据data里面给demo数据的时候,子组件是拿得到数据的,图片正常显示,所以以为可以了,当换成从后台请求的数据后,发现子组件总是报错,data.count is not a function ,在子组件的mounted里面打印父组件传递过来的prop,发现是空数组。

  刚开始我以为是mounted生命周期的问题,所以改成created阶段去请求后台数据,然后传递给子组件,发现仍然不行。

  这时,我给父组件数据加上默认一些demo数据,然后再created阶段再去请求后台数据,覆盖demo数据。发现子组件mounted阶段打印的还是demo数据,而不是请求的数据,所以知道问题原因就是子组件渲染的时候,在父组件created请求后台数据返回之前就prop传递给了子组件,所以导致子组件获取的都不是从后台请求的数据。

3、刚开始子组件时在mounted里面调用画图方法drawline(),由于这时数据为空,所以报错。我就考虑到是不是不让子组件自身去mounte画图,而是让父组件异步请求到后台数据之后,赋值给prop之后,再通过ref去调用子组件的画图方法drawLine(),这样是不是就可以画图成功了?但是验证还是不行。在drawLine()里面去打印父组件传递的prop,发现还是最初的空或者demo数据。

  所以考虑到父组件传递prop就是渲染时传递,而不是赋值时传递,所以总是传递的data()里面初始化的数据。所以通过父组件去调用子组件方法去画图也行不通。

4、考虑到父组件传递prop就是渲染时传递。

  那么我就可以给子组件加个判断 v-if 条件,当父组件从后台异步取到数据后,并且赋值给prop后,让flag = true再去渲染子组件,那么此时传递给子组件的prop就是异步获取到数据之后的值,图形就正常展示出来了。

5、全部代码:

  miniLine子组件

<template>
    <div :id="myId" :style="{width:‘100%‘,height:‘200px‘}"></div>
</template>
<script type="ecmascript-6">
export default {
    data(){
        return {
            series:[]
        }
    },
    props:[‘myId‘,‘lineDime‘,‘lineSeries‘],
    methods:{
        drawLine(){
            let myLine = this.$echarts.init(document.getElementById(this.myId));
            let option = {
                color:[‘#1CA6F1‘,‘#C1D534‘,‘#C6504D‘],
                tooltip: {
                    trigger: ‘axis‘
                },
                legend: {
                    icon:‘stack‘
                },
                grid: {
                    left: ‘3%‘,
                    right: ‘3%‘,
                    bottom: ‘3%‘,
                    top:‘15%‘,
                    containLabel: true
                },
                xAxis: [{
                    type: ‘category‘,
                    axisTick: {
                        alignWithLabel: true,
                        show:false
                    },
                    axisLabel:{
                        show:true,
                        formatter: function (value, index) {
                            return value.split(‘ ‘)[1];
                        }
                    }
                }],
                yAxis: [{
                    type: ‘value‘,
                    axisTick: {
                        show: false
                    },
                    splitLine:{
                        show:true
                    }
                }],
                dataset:{
                       dimensions:this.lineDime,
                    source:this.lineSeries
                },
                series: this.series
            };
            myLine.setOption(option);
            window.addEventListener("resize", () => { myLine.resize();});
        }
    },
    mounted(){
        let _obj = {
            type:‘line‘
        }
        this.series.length = this.lineDime.length - 1
        this.series.fill(_obj)
        this.drawLine()
    }
}
</script>
<style scoped lang="stylus" rel="stylesheet">
</style>

  monitor父组件

<template>
<el-main>
    <el-row class="dbInfo">
        <el-col :span="6">
            <div class="panel-body">
                <img src="../../assets/images/postgreSQL.jpg" height="60">
                <p>{{dbInfo.version}}</p>
            </div>
        </el-col>
        <el-col :span="6">
            <div class="panel-body">
                <p>Rows fetched/returned</p>
                <div class="content" :style="{color:‘#C1D534‘}">{{dbInfo.fetchper}}<span>%</span></div>
            </div>
        </el-col>
        <el-col :span="6">
            <div class="panel-body">
                <p>Database capacity</p>
                <div class="content" :style="{color:‘#1CA6F1‘}">{{parseInt(dbInfo.dbsize)}}<span>MB</span></div>
            </div>
        </el-col>
        <el-col :span="6">
            <div class="panel-body">
                <p>Max connections in use</p>
                <div class="content" :style="{color:‘#C6504D‘}">{{dbInfo.conper}}<span>%</span></div>
            </div>
        </el-col>
    </el-row>
    <div class="query">
        <el-date-picker
        v-model="datetimerange"
        type="datetimerange"
        range-separator="至"
        start-placeholder="开始时间"
        end-placeholder="结束时间"
        size="mini">
        </el-date-picker>
        <i class="el-icon-refresh" @click="refresh"></i>
    </div>
    <el-row :gutter="20">
        <el-col :span="12">
            <moniLine v-if="flag" :my-id="ids[0]" :line-dime="dimensions[0]" :line-series="monitorData"></moniLine>
        </el-col>
        <el-col :span="12">
            <moniLine v-if="flag" :my-id="ids[1]" :line-dime="dimensions[1]" :line-series="monitorData"></moniLine>
        </el-col>
    </el-row>
    <el-row :gutter="20">
        <el-col :span="8">
            <moniLine v-if="flag" :my-id="ids[2]" :line-dime="dimensions[2]" :line-series="monitorData"></moniLine>
        </el-col>
        <el-col :span="8">
            <moniLine v-if="flag" :my-id="ids[3]" :line-dime="dimensions[3]" :line-series="monitorData"></moniLine>
        </el-col>
        <el-col :span="8">
            <moniLine v-if="flag" :my-id="ids[4]" :line-dime="dimensions[4]" :line-series="monitorData"></moniLine>
        </el-col>
    </el-row>
    <el-tabs v-model="activeName" type="border-card">
        <el-tab-pane label="Sessions" name="first">
            <el-table :data="sessions" size="mini">
                <el-table-column prop="pid" label="Pid" width="60" align="center"></el-table-column>
                <el-table-column prop="datname" label="Database" width="80" align="center"></el-table-column>
                <el-table-column prop="usename" label="User" width="80" align="center"></el-table-column>
                <el-table-column prop="application_name" label="Application" align="center"></el-table-column>
                <el-table-column prop="client_addr" label="Client" width="140" align="center"></el-table-column>
                <el-table-column prop="backend_start" label="Backend start" width="150" align="center"></el-table-column>
                <el-table-column prop="state" label="State" width="70" align="center"></el-table-column>
                <el-table-column prop="wait_event" label="Wait Event" align="center"></el-table-column>
                <el-table-column prop="blocking_pids" label="Blocking PIDs" width="90" align="center"></el-table-column>
            </el-table>
        </el-tab-pane>
        <el-tab-pane label="Locks" name="second">
            <el-table :data="locks" size="mini">
                <el-table-column prop="pid" label="Pid" width="60"></el-table-column>
                <el-table-column prop="datname" label="Database" width="70"></el-table-column>
                <el-table-column prop="locktype" label="Lock type" width="70"></el-table-column>
                <el-table-column prop="relation" label="Target relation"></el-table-column>
                <el-table-column prop="page" label="Page" width="50"></el-table-column>
                <el-table-column prop="tuple" label="Tuple" width="50"></el-table-column>
                <el-table-column prop="virtualxid" label="vXID(target)"></el-table-column>
                <el-table-column prop="objsubid" label="XID(target)"></el-table-column>
                <el-table-column prop="classid" label="Class" width="50"></el-table-column>
                <el-table-column prop="objid" label="ObjectID" width="65"></el-table-column>
                <el-table-column prop="transactionid" label="vXID(owner)" width="90"></el-table-column>
                <el-table-column prop="mode" label="Mode"></el-table-column>
                <el-table-column prop="granted" label="Granted" width="65">
                    <template slot-scope="scope">{{scope.row.granted ? ‘是‘ :‘否‘}}</template>
                </el-table-column>
            </el-table>
        </el-tab-pane>
        <el-tab-pane label="Prepared Transactions" name="third">
            <el-table :data="transactions" size="mini">
                <el-table-column prop="gid" label="Name"></el-table-column>
                <el-table-column prop="database" label="Database"></el-table-column>
                <el-table-column prop="owner" label="Owner"></el-table-column>
                <el-table-column prop="transaction" label="XID"></el-table-column>
                <el-table-column prop="prepared" label="Prepared at"></el-table-column>
            </el-table>
        </el-tab-pane>
        <el-tab-pane label="Configuration" name="fourth">
            <el-table :data="configs" size="mini">
                <el-table-column prop="name" label="Name"></el-table-column>
                <el-table-column prop="category" label="Category"></el-table-column>
                <el-table-column prop="setting" label="Setting"></el-table-column>
                <el-table-column prop="unit" label="Unit" width="50"></el-table-column>
                <el-table-column prop="short_desc" label="Description"></el-table-column>
            </el-table>
        </el-tab-pane>
    </el-tabs>
</el-main>
</template>
<script type="ecmascript-6">
import moniLine from ‘./moniLine‘
import {getMonitorApi,getPgSessionsApi,getPgLocksApi,getPgPretransApi,getPgConfigsApi,getPgDbinfosApi} from ‘@/apis‘
export default {
    data(){
        return {
            flag:false,
            ids:[‘myLine1‘,‘myLine2‘,‘myLine3‘,‘myLine4‘,‘myLine5‘],
            dimensions:[
                [‘snap_time‘,‘active‘,‘idle‘,‘total‘],
                [‘snap_time‘,‘commits‘,‘rollbacks‘,‘transactions‘],
                [‘snap_time‘,‘inserts‘,‘updates‘,‘deletes‘],
                [‘snap_time‘,‘fetched‘,‘returned‘],
                [‘snap_time‘,‘reads‘,‘hits‘]
            ],
            monitorData:[],
            activeName:‘first‘,
            sessions:[],
            locks:[],
            transactions:[],
            configs:[],
            dbInfo:{},
            datetimerange:[]
        }
    },
    components:{
        moniLine
    },
    created(){
        this.fetchData()
    },
    methods:{
        fetchData(){
            getMonitorApi().then(res => {
                if(res.status === 200){
                    this.monitorData = res.data
                    this.flag = true
                }
            })
            getPgSessionsApi().then(res => {
                if(res.status === 200){
                    this.sessions = res.data
                }
            })
            getPgLocksApi().then(res => {
                if(res.status === 200){
                    this.locks = res.data
                }
            })
            getPgPretransApi().then(res => {
                if(res.status === 200){
                    this.transactions = res.data
                }
            })
            getPgConfigsApi().then(res => {
                if(res.status === 200){
                    this.configs = res.data
                }
            })
            getPgDbinfosApi().then(res => {
                if(res.status === 200){
                    this.dbInfo = res.data
                }
            })
        },
        refresh(){
            this.fetchData()
        }
    }
}
</script>
<style scoped lang="stylus" rel="stylesheet">
@import ‘../../assets/css/index.styl‘
.el-row{
    margin-bottom 20px
}
.query{
    margin 10px
    i{
        font-weight 1000
        color #A0A0A6
    }
    & i:hover{
        color #1CA6F1
        cursor pointer
    }
}
.el-table{
    font-size 10px
}
.el-tabs__nav .el-tabs__item{
    font-size 12px
}
.dbInfo{
    text-align center
    p{
        margin 0px
        font-size 12px
    }
    .panel-body{
        margin 10px 20px
        min-height 82px
        .content{
            font-size 50px
            font-weight 500
            span{
                font-size 30px
            }
        }
    }
}
</style>

原文地址:https://www.cnblogs.com/goloving/p/9114236.html

时间: 2024-10-04 16:57:44

vue父组件异步传递prop到子组件echarts画图问题踩坑总结的相关文章

Vue 路由跳转传递参数,子组件页面刷新后数据不丢失

原文地址:https://www.cnblogs.com/yscec/p/12408492.html

初识vue 2.0(13):子组件使用watch监听父组件变化

子组件使用created或者mounted通常只能在组件初始化的时候,获取父组件传过来的props数据. 父组件props数据发生变化,子组件默认无法感知,因此需要手动实现子组件监听父组件变化的功能. 一般的值类型数据,可以直接使用watch监听: watch: { msg(newVal, oldVal){//对引用类型的值无效 console.info('value changed ', newVal) } } 引用类型,普通watch方法,无法监听到引用类型内部的变化. 解决此问题,可以在父

vue--父组件向子组件传参--父组件定义v-bind:参数名--子组件接收props----子组件调用父组件的方法(子组件向父组件传参)父组件@事件名称--子组件接收this.$emit

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" con

vue-父组件传递参数到子组件

案例: 父组件 <template> <div id="app"> <h1>vuex</h1> <h3>count:{{count}}</h3> <button @click="count++">+1</button> <button @click="count--">-1</button> <!--父组件向子组件传递参数

vue 通过Prop向子组件传递数据

如何使用 第一步父组件App.vue中 <template> <div id="app"> <Users :users="users"></Users> </div> </template> <script> import Users from './components/Users' export default { name: 'App', data: function () {

Vue 组件&amp;组件之间的通信 之 子组件向父组件传值

子组件向父组件传值:子组件通过$.emit()方法以事件形式向父组件发送消息传值: 使用步骤: 定义组件:现有自定义组件com-a.com-b,com-a是com-b的父组件: 准备获取数据:父组件com-a要获取子组件data中的height属性: 在子组件com-b中,需要用$.emit()方法将数据以事件的形式发送,$.emit('sendData', data, data…),红色的部分事件名可自定义,数据可传递多个: 在父组件中使用子组件的地方 <com-b @自定义事件名='getD

vue.js组件之间通讯--父组件调用子组件的一些方法,子组件暴露一些方法,让父组件调用

<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Title</title></head><body><div id="app"></div></body><script src="node_modules/vue/

Vue 父组件循环使用refs调用子组件方法出现undefined的问题

1. 背景 最近前端项目遇到一个问题,我在父组件中使用了两个相同的子组件child,分别设置ref为add和update.其中A组件的功能是新增,也就是说在页面上A页面只有一个.而update组件是放在表格里的,表格中的每一行数据都有update组件.跟update组件并列还有一个删除按钮,每次删除完都会重新获取数据. 2.问题描述 界面第一次加载时我对表格的组件B进行操作的时候是没问题的,但是当我删除某一行的数据之后再点击B组件,出现了update组件变为undefined的问题. <el-t

react父子组件通讯-----&gt;下面用到的ref属性调用子组件的方法,可以实现子组件往父组件传递参数,可以通过在父组件的方法中调用子组件的方法,通过返回值来拿到值,也可以在子组件中,对数据处理完后,调用父组件传给子组件的参数或者方法,来实现传参,

<scripttype="text/babel"> var Child =React.createClass({ getInitialState: function() { return {color:"",childMsg:"我是子组件的信息"}; }, changeColor: function(e) { this.setState({color:e.target.getAttribute("data-color&quo