Tina--han 2023-09-26 17:35 采纳率: 0%
浏览 16

v-for循环展示页面结构问题

有个需求实现不了,有没有哪位牛人帮帮我,谢谢。
需求:

img


1.三行数据每一行都可以展开收起。
2.每展开一行数据,都可以看到一个div,div左边展示列表,右边展示折线图,点击左边列表的某一行数据,右边的折线图表就会更新。

难点:右侧折现图部分不知道如何渲染数据了。

下面是我写的demo,carTablle.vue,carTablle2.vue两种方式都有欠缺,求指导。carpng是单个折线图组件。

carTablle.vue

<template>
    <div>
        <div class="part">
            <div class="title">车辆统计</div>
        </div>
        <div v-for="(i, index) in list" :key="index" class="itemBox">
            <div class="top">
                <div class="topLeft">
                    <div class="brand">车辆品牌:{{ i.carName }}</div>
                    <div>最大输出功率:{{ i.carNumber }}KW</div>
                </div>
                <div>
                    <span @click="handleChange(i)" class="fontColor">
                        {{ i.isopen ? '收起' : '展开' }}
                    </span>
                    <span @click="open(i)">详情</span>
                </div>
            </div>
            <div class="bottom" v-show="i.isSubShow" style="">
                <!-- 左边的 -->
                <div class="bottomLeft">
                    <div
                        class="leftContent"
                        v-for="(k, q) in i.data"
                        :key="q"
                        @click="getPlateNumberList(k, i)"
                    >
                        <div>{{ q + 1 }}</div>
                        <div>{{ k.carName }}</div>
                        <div>最大输出功率:{{ k.carNumber }}KW</div>
                    </div>
                </div>
                <!-- 右边的 -->
                <div class="bottomRight" v-if="i == number">
                    <div class="text">{{ total }}辆充电车辆</div>
                    <div class="chart">
                        <div v-for="(png, index) in pngList" :key="index" class="chartItem">
                            <car-png :items="png" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
import carPng from './carPng.vue'
export default {
    components: {
        carPng,
    },
    data() {
        return {
            id: 1,
            total: 0,
            number: '', //控制折线图显示隐藏
            list: [
                {
                    carName: '奔驰',
                    carNumber: '500kw',
                    isopen: false,
                    isSubShow: false,
                    data: [
                        { carName: '奔驰01', carNumber: 500 },
                        { carName: '奔驰02', carNumber: 600 },
                    ],
                },
                {
                    carName: '宝马',
                    carNumber: '500kw',
                    isopen: false,
                    isSubShow: false,
                    data: [
                        { carName: '宝马01', carNumber: 500 },
                        { carName: '宝马02', carNumber: 600 },
                    ],
                },
                {
                    carName: '玛莎拉蒂',
                    carNumber: 500,
                    isopen: false,
                    isSubShow: false,
                },
            ],
            pngList: [],
        }
    },
    methods: {
        getPlateNumberList(k, i) {
            this.number = i
            console.log('111')
            if (k.carName == '奔驰01') {
                this.total = 3
                this.pngList = [
                    {
                        plateNumber: '京123',
                        platedata: [
                            {
                                name: 'Email',
                                type: 'line',
                                stack: 'Total',
                                data: [120, 132, 101, 134, 90, 230, 210],
                            },
                            {
                                name: 'Union Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [220, 182, 191, 234, 290, 330, 310],
                            },
                            {
                                name: 'Video Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [150, 232, 201, 154, 190, 330, 410],
                            },
                            {
                                name: 'Direct',
                                type: 'line',
                                stack: 'Total',
                                data: [320, 332, 301, 334, 390, 330, 320],
                            },
                            {
                                name: 'Search Engine',
                                type: 'line',
                                stack: 'Total',
                                data: [820, 932, 901, 934, 1290, 1330, 1320],
                            },
                        ],
                    },
                    {
                        plateNumber: '京456',
                        platedata: [
                            {
                                name: 'Email',
                                type: 'line',
                                stack: 'Total',
                                data: [100, 100, 100, 100, 100, 100, 210],
                            },
                            {
                                name: 'Union Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [220, 182, 191, 234, 290, 330, 310],
                            },
                            {
                                name: 'Video Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [150, 232, 201, 154, 190, 330, 410],
                            },
                            {
                                name: 'Direct',
                                type: 'line',
                                stack: 'Total',
                                data: [320, 332, 301, 334, 390, 330, 320],
                            },
                            {
                                name: 'Search Engine',
                                type: 'line',
                                stack: 'Total',
                                data: [820, 932, 901, 934, 1290, 1330, 1320],
                            },
                        ],
                    },
                    { plateNumber: '京789' },
                    {
                        plateNumber: '京789',
                    },
                ]
            } else {
                this.total = 2
                this.pngList = []
            }
        },
        handleChange(item) {
            item.isSubShow = !item.isSubShow
            item.isopen = !item.isopen //右侧图标根据内容隐藏或显示进行相应显示
        },
        open() {
            this.$refs.carTypeDetail.show()
        },
    },
}
</script>

<style lang="less" scoped>
.part {
    height: 40px;
    background: white;
    display: flex;
    justify-content: space-between;
    padding: 20px;
    .title {
        font-size: 18px;
    }
}
.itemBox {
    padding: 10px 20px;
    .top {
        display: flex;
        justify-content: space-between;
        .topLeft {
            display: flex;
            img {
                width: 50px;
                height: 50px;
                margin-right: 20px;
            }
            .brand {
                margin-right: 50px;
            }
        }
        .fontColor {
            color: #1890ff;
            margin-right: 10px;
        }
    }
    .bottom {
        width: 100%;
        display: flex;
        .bottomLeft {
            width: 30%;
            border: 1px solid #000;
            .leftContent {
                display: flex;
                justify-content: space-around;
                align-items: center;
                border-bottom: 1px solid #000;
                height: 40px;
            }
        }
        .bottomRight {
            width: 70%;
            margin-left: 10px;
            .text {
                text-align: left;
            }
            .chart {
                display: flex;
                width: 100%;
                flex-wrap: wrap;
                .chartItem {
                    width: 46%;
                    height: 200px;
                    border: 1px solid red;
                    margin: 10px;
                }
            }
        }
    }
}
</style>

carTable2.vue

<template>
    <div>
        <div class="part">
            <div class="title">车辆统计</div>
        </div>
        <div v-for="(i, index) in list" :key="index" class="itemBox">
            <div class="top">
                <div class="topLeft">
                    <div class="brand">车辆品牌:{{ i.carName }}</div>
                    <div>最大输出功率:{{ i.carNumber }}KW</div>
                </div>
                <div>
                    <span @click="handleChange(i, index)" class="fontColor">
                        {{ i.isopen ? '收起' : '展开' }}
                    </span>
                    <span @click="open(i)">详情</span>
                </div>
            </div>
            <div class="bottom" v-show="i.isSubShow" style="">
                <!-- 左边的 -->
                <div class="bottomLeft">
                    <div
                        class="leftContent"
                        v-for="(k, q) in i.data"
                        :key="q"
                        @click="getPlateNumberList(k, q)"
                    >
                        <div>{{ q + 1 }}</div>
                        <div>{{ k.carName }}</div>
                        <div>最大输出功率:{{ k.carNumber }}KW</div>
                    </div>
                </div>
                <!-- 右边的 -->
                <div class="bottomRight">
                    <div class="text">{{ list[parentIndex].data[flagNum].total }}辆充电车辆
                    </div>
                    <div class="chart">
                        <div
                            v-for="(png, index) in list[parentIndex].data[flagNum].pngList"
                            :key="index"
                            class="chartItem"
                        >
                            <car-png :items="png" />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import carPng from './carPng.vue'
export default {
    components: {
        carPng,
    },
    data() {
        return {
            id: 1,
            total: 0,
            list: [
                {
                    carName: '奔驰',
                    carNumber: '500kw',
                    isopen: false,
                    isSubShow: false,
                    data: [
                        { carName: '奔驰01', carNumber: 500 },
                        { carName: '奔驰02', carNumber: 600 },
                    ],
                },
                {
                    carName: '宝马',
                    carNumber: '500kw',
                    isopen: false,
                    isSubShow: false,
                    data: [
                        { carName: '宝马01', carNumber: 500 },
                        { carName: '宝马02', carNumber: 600 },
                    ],
                },
                {
                    carName: '玛莎拉蒂',
                    carNumber: 500,
                    isopen: false,
                    isSubShow: false,
                },
            ],
            flagNum: 0,
            parentIndex: 0,
        }
    },
    methods: {
        getPlateNumberList(k, q) {
            this.flagNum = q
            console.log(this.flagNum, 'this.flagNum')
            console.log(this.list[this.parentIndex], 'this.list[this.parentIndex]')
            console.log(
                this.list[this.parentIndex].data[q],
                'this.list[this.parentIndex].data[q]'
            )
            const str = this.list[this.parentIndex].data[q]
            str.total = 0
            str.pngList = []
            if (k.carName == '奔驰01') {
                str.total = 3
                str.pngList = [
                    {
                        plateNumber: '京123',
                        platedata: [
                            {
                                name: 'Email',
                                type: 'line',
                                stack: 'Total',
                                data: [120, 132, 101, 134, 90, 230, 210],
                            },
                            {
                                name: 'Union Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [220, 182, 191, 234, 290, 330, 310],
                            },
                            {
                                name: 'Video Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [150, 232, 201, 154, 190, 330, 410],
                            },
                            {
                                name: 'Direct',
                                type: 'line',
                                stack: 'Total',
                                data: [320, 332, 301, 334, 390, 330, 320],
                            },
                            {
                                name: 'Search Engine',
                                type: 'line',
                                stack: 'Total',
                                data: [820, 932, 901, 934, 1290, 1330, 1320],
                            },
                        ],
                    },
                    {
                        plateNumber: '京456',
                        platedata: [
                            {
                                name: 'Email',
                                type: 'line',
                                stack: 'Total',
                                data: [100, 100, 100, 100, 100, 100, 210],
                            },
                            {
                                name: 'Union Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [220, 182, 191, 234, 290, 330, 310],
                            },
                            {
                                name: 'Video Ads',
                                type: 'line',
                                stack: 'Total',
                                data: [150, 232, 201, 154, 190, 330, 410],
                            },
                            {
                                name: 'Direct',
                                type: 'line',
                                stack: 'Total',
                                data: [320, 332, 301, 334, 390, 330, 320],
                            },
                            {
                                name: 'Search Engine',
                                type: 'line',
                                stack: 'Total',
                                data: [820, 932, 901, 934, 1290, 1330, 1320],
                            },
                        ],
                    },
                    { plateNumber: '京789' },
                    {
                        plateNumber: '京789',
                    },
                ]
                console.log(str.pngList, 'str.pngList')
            } else {
                str.total = 2
                str.pngList == []
            }
        },
        handleChange(item, parentIndex) {
            this.parentIndex = parentIndex
            item.isSubShow = !item.isSubShow
            item.isopen = !item.isopen //右侧图标根据内容隐藏或显示进行相应显示
        },
        open() {
            this.$refs.carTypeDetail.show()
        },
    },
}
</script>

<style lang="less" scoped>
.part {
    height: 40px;
    background: white;
    display: flex;
    justify-content: space-between;
    padding: 20px;
    .title {
        font-size: 18px;
    }
}
.itemBox {
    padding: 10px 20px;
    .top {
        display: flex;
        justify-content: space-between;
        .topLeft {
            display: flex;
            img {
                width: 50px;
                height: 50px;
                margin-right: 20px;
            }
            .brand {
                margin-right: 50px;
            }
        }
        .fontColor {
            color: #1890ff;
            margin-right: 10px;
        }
    }
    .bottom {
        width: 100%;
        display: flex;
        .bottomLeft {
            width: 30%;
            border: 1px solid #000;
            .leftContent {
                display: flex;
                justify-content: space-around;
                align-items: center;
                border-bottom: 1px solid #000;
                height: 40px;
            }
        }
        .bottomRight {
            width: 70%;
            margin-left: 10px;
            .text {
                text-align: left;
            }
            .chart {
                display: flex;
                width: 100%;
                flex-wrap: wrap;
                .chartItem {
                    width: 46%;
                    height: 200px;
                    border: 1px solid red;
                    margin: 10px;
                }
            }
        }
    }
}
</style>

carPng.vue

<template>
  <div>
    <div class="title">
      <div>{{ items.plateNumber }}</div>
      <div @click="showDetails" class="color">详情</div>
    </div>
    <div>
      <div ref="echarts" :class="big ? 'more' : 'main'"></div>
    </div>
    <charge-record-details ref="chargeRecordDetails" />
  </div>
</template>

<script>
import chargeRecordDetails from './chargeRecordDetails'
import * as echarts from 'echarts'
export default {
  props: ['items', 'big'],
  components: {
    chargeRecordDetails,
  },
  mounted() {
    this.showImg()
    console.log(this.items, 'items')
    console.log(this.items.platedata, '222')
  },
  methods: {
    showImg() {
      // var chartDom = document.getElementById('main')
      var chartDom = this.$refs.echarts
      var myChart = echarts.init(chartDom)
      var option = {
        tooltip: {
          trigger: 'axis',
        },
        legend: {
          left: '5%',
          data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'],
        },
        grid: {
          top: '10%',
          left: '8%',
          right: '8%',
          bottom: '7%',
          containLabel: true,
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
        yAxis: {
          type: 'value',
        },
        series: this.items.platedata,
      }
      myChart.setOption(option)
    },
    showDetails() {
      this.$refs.chargeRecordDetails.show()
    },
  },
}
</script>

<style lang="less" scoped>
.title {
  display: flex;
  justify-content: space-between;
  padding: 0px 20px;
  height: 40x;
  border-bottom: 1px solid #000;
}
.main {
  width: 300px;
  height: 200px;
}
.more {
  width: 200px;
  height: 200px;
}
.color {
  color: rgba(24, 144, 255, 1);
}
</style>

运行结果:

img

img

  • 写回答

2条回答 默认 最新

  • 余大雷 2023-09-27 10:24
    关注

    左右联动的效果就是点击左边列表来做到右边echarts更新视图,那就在左边点击列表的同时拿到点击的对象,根据这个对象去获取右边视图索要更新的数据,v-for你是可以拿到每个点击对象的索引,拿到索引就知道点击了那个列表中的哪条数据,这样你就更好的去区分。当然不建议这样做,最后是将数据结构改变成树形结构才更直观的去操作

    评论

报告相同问题?

问题事件

  • 修改了问题 9月26日
  • 创建了问题 9月26日

悬赏问题

  • ¥15 网友们我该怎么办啊,急
  • ¥15 混合键合键合机对准标识
  • ¥100 现在不懂的是如何将当前的相机中的照片,作为纹理贴图,映射到扫描出的模型上
  • ¥15 目标跟踪,计算机视觉
  • ¥15 魔霸ROG7 pro,win11.息屏后会显示黑屏,如图,如何解决?(关键词-重新启动)
  • ¥15 有没有人知道这是哪里出了问题啊?要怎么改呀?
  • ¥200 C++表格文件处理-悬赏
  • ¥15 Windows Server2016本地登录失败
  • ¥15 复合卡卡号轨道写入芯片卡
  • ¥20 基于MATLAB的TDOA