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,子組件mounted階段就是渲染時傳遞,而不是賦值時傳遞的,所以總是傳遞的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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM