vue3封装公共组件——模块标题-包括点击事件、背景图片、插槽、下方内容区

本文展示了如何在Vue中封装一个公共组件`titleHeader`,包含标题点击事件、背景图片、插槽和装饰线功能。组件在不同场景下被使用,如无装饰线的简略版、带有静态数据的详细版以及结合ECharts接口数据的详细版。通过插槽`mark`实现了自定义内容,并且在详细版中展示了动态加载ECharts图表,分别呈现了去年和今年的全网最大负荷对比及各省历史与昨日最大负荷数据。
摘要由CSDN通过智能技术生成

封装公共组件——模块标题-包括点击事件、背景图片、插槽、下方内容区

1、效果

在这里插入图片描述

2、封装的代码

src/components/header/titleHeader.vue

<script lang="ts" setup>
import icon from '@/assets/yfdd-bs/right/title/titleyuansu.png'
const props = defineProps({
  src: {
    type: String,
    required: true,
    default: ''
  },
  needLine: {
    type: Boolean,
    required: false,
    default: false
  },
  lineWidth: {
    type: Array as () => Array<number>,
    required: false,
    default: () => []
  }
})

// 展示弹框
const emit = defineEmits(['is-dialog'])
const isDialog = () => {
  emit('is-dialog', '')
}
</script>

<template>
  <div class="header-container">
    <div
      class="title"
    >
        <!--两斜杠图标-->
      <img
        style="margin-right: 20px"
        :src="icon"
      >
        <!-- title文字图片 -->
      <img
        @click="isDialog"
        class="header"
        :src="props.src"
      >
         <!-- 长装饰线 -->
      <div
        class="line1"
        :style="{ width: props.lineWidth[0] + 'px' }"
        v-if="props.needLine"
      />
         <!-- 短装饰线 -->
      <div
        class="line2"
        :style="{ width: props.lineWidth[1] + 'px' }"
        v-if="props.needLine"
      />
    </div>
    <div class="mark">
      <slot
        name="mark"
      />
    </div>
  </div>
</template>

<style lang="scss" scoped>
.header-container {
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 93px;
  font-size: 24px;
  .title {
    height: 100%;
    flex-grow: 1;
    display: flex;
    justify-content: start;
    align-items: center;
    height: 93px;
    font-size: 24px;
      padding-left: 34px;
      .header{
        cursor: pointer;
      }
      .line1 {
        margin-left: 40px;
        height: 26px;
        border-bottom: 1px solid #FEFEFE;
      }
      .line2 {
        margin-left: 10px;
        height: 26px;
        border-bottom: 1px solid #C9E9FD;
      }

  }
  .mark{
    position: absolute;
    right: 45px;
    top: 20px;
  }
}
</style>
3、页面使用
3.1、简略版

效果-无装饰线

在这里插入图片描述

index.vue

<script lang="ts" setup>
import titleHeader from '../header/titleHeader.vue'
import img from '@/assets/yfdd-bs/left/title/zysx.png'
</script>

<template>
  <div class="container">
    <titleHeader
      :src="img"
      :need-line="true"
      :line-width="[210, 24]"
    />
      <!-- 下方内容区 -->
    <div class="content">
      666
    </div>
  </div>
</template>

<style lang="scss" scoped>
  .container{
      background-image: url(@/assets/yfdd-bs/right/back2.png);
      background-repeat: no-repeat;
      background-size: 100% 100%;
      .content{
          height: calc(100% - 110px);
      }
  }
</style>
3.2、详细版-静态数据

效果-有插槽

在这里插入图片描述

index.vue

<script lang="ts" setup>
import titleHeader from '../header/titleHeader.vue'
// 引入echarts
import * as echarts from 'echarts'
import { onMounted } from 'vue'

import img from '@/assets/yfdd-bs/main/left/qwfh.png'

onMounted(() => { // 需要获取到element,所以是onMounted的Hook
  const myChart = echarts.init(document.getElementById('myChart123'))
  // 绘制图表
  myChart.setOption({
    // title: {
    //   text: 'Stacked Line'
    // },
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      top: '20px',
      left: '70px',
      right: '50px',
      bottom: '40px'
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: ['11-15', '11-16', '11-17', '11-18', '11-19', '11-20', '11-21', '11-22', '11-23', '11-24', '11-25', '11-26', '11-27', '11-28'],
      axisLabel: {
        show: true,
        textStyle: {
          color: '#ffffff'
        }
      },
      axisLine: {
        lineStyle: {
          color: '#ffffff'
        }
      }
    },
    yAxis: [
      {
        type: 'value',
        name: '',
        axisLabel: {
          textStyle: {
            color: '#ffffff'
          }
        }
      }
    ],
    color: ['#ff552c', '#ffe879'],
    series: [
      {
        name: '去年全网最大负荷',
        type: 'line',
        stack: 'Total',
        smooth: true, // 设置折线图平滑
        data: [150, 232, 201, 154, 190, 330, 410, 150, 232, 201, 154, 190, 330, 410]
      },
      {
        name: '今年全网最大负荷',
        type: 'line',
        stack: 'Total',
        smooth: true, // 设置折线图平滑
        data: [320, 332, 301, 334, 390, 330, 320, 320, 332, 301, 334, 390, 330, 320]
      }
    ]
  })
  window.onresize = function () { // 自适应大小
    myChart.resize()
  }
})
</script>

<template>
  <div class="duty-container">
    <titleHeader
      :src="img"
      :need-line="true"
      :line-width="[790, 24]"
      class="father"
    >
      <template #mark>
        <div class="mark">
          <span class="color a" />去年全网最大负荷
          <span class="color b" />今年全网最大负荷
        </div>
      </template>
    </titleHeader>
    <div
      id="myChart123"
      :style="{width: '100%', height: '200px'}"
    />
  </div>
</template>

<style scoped lang="scss">
.duty-container {
  grid-area: a;
  background: url(@/assets/yfdd-bs/main/left/back1.png) no-repeat;
  background-size: 100% 100%;
  .father{
    position: relative;
    .mark{
      display: flex;
      align-items: center;
      height: 30px;
      line-height: 30px;
      font-size: 20px;
      .color{
        display: inline-block;
        width: 15px;
        height: 15px;
        margin: 10px;
        border-radius: 50%;
      }
      .a{
        background-color: #FF552E;
      }
      .b{
        margin-left: 50px;
        background-color: #FFE778;
      }
    }
  }
}
</style>
3.3、详细版-接口数据

效果-含接口数据和插槽

在这里插入图片描述

index.vue

<script lang="ts" setup>
import titleHeader from '../header/titleHeader.vue'
// 引入echarts
import * as echarts from 'echarts'
import { onMounted } from 'vue'

import img from '@/assets/yfdd-bs/main/left/gsj.png'
import { getLoadList } from '@/api/yfdd-bs/PowerLoad'

const provinceArr:Array<string> = [] // 省份
const yesterdayArr:Array<string> = [] // 昨天最大负荷
const historyArr:Array<string> = [] // 历史最大负荷
/**
 * 加载列表数据
 */
const loadList = async () => {
  try {
    const res = await getLoadList()
    res.forEach((item:Object) => {
      provinceArr.push(item.provinceName)
      yesterdayArr.push(item.yesterdayMaxLoad)
      historyArr.push(item.historyMaxLoad)
    })
    // 需要获取到element,所以是onMounted的Hook
    const myChart = echarts.init(document.getElementById('myChart'))
    // 绘制图表
    myChart.setOption(option)
    window.onresize = function () { // 自适应大小
      myChart.resize()
    }
  } catch (err) {
  }
}

const option = {
  tooltip: {
    // trigger: 'axis',
    axisPointer: {
      type: 'shadow'
    }
  },
  grid: {
    top: '20px',
    left: '70px',
    right: '50px',
    bottom: '40px'
  },
  xAxis: [
    {
      type: 'category',
      data: provinceArr,
      axisLabel: {
        show: true,
        color: '#ffffff'
      },
      axisLine: {
        lineStyle: {
          color: '#ffffff'
        }
      }
    }
  ],
  yAxis: [
    {
      type: 'value',
      name: '',
      axisLabel: {
        color: '#ffffff'
      }
    }
  ],
  series: [
    {
      name: '历史最大负荷',
      type: 'bar',
      barWidth: '20px',
      data: historyArr,
      itemStyle: {
        normal: {
          color: '#FFE778'
        }
      }
    },
    {
      name: '昨日最大负荷',
      type: 'bar',
      barWidth: '20px',
      data: yesterdayArr,
      itemStyle: {
        normal: {
          color: '#FF552E',
          label: {
            show: true, // 开启显示
            position: 'top', // 在上方显示// 数值样式
            color: '#ffffff',
            fontSize: 16
          }
        }
      }
    }
  ]
}

onMounted(() => {
  // 调用数据接口
  loadList()
})
</script>

<template>
  <div class="duty-container">
    <titleHeader
      :src="img"
      :need-line="true"
      :line-width="[790, 24]"
      class="father"
    >
      <template #mark>
        <div class="mark">
          <span class="color a" />各省历史最大负荷
          <span class="color b" />各省昨日最大负荷
        </div>
      </template>
    </titleHeader>
    <div
      id="myChart"
      :style="{width: '100%', height: 'calc(100% - 110px)'}"
    />
  </div>
</template>

<style scoped lang="scss">
.duty-container {
  grid-area: c;
  background: url(@/assets/yfdd-bs/main/left/back1.png) no-repeat;
  background-size: 100% 100%;
  #myChart{
    color: white;
  }
  .father{
    position: relative;
    .mark{
      display: flex;
      align-items: center;
      height: 30px;
      line-height: 30px;
      font-size: 20px;
      .color{
        display: inline-block;
        width: 15px;
        height: 15px;
        margin: 10px;
      }
      .a{
        background-color: #FFE778;
      }
      .b{
        margin-left: 50px;
        background-color: #FF552E;
      }
    }
  }

}
</style>

接口方法

src/api/yfdd-bs/PowerLoad.ts

/**
 * 请求各省级电网负荷数据
 */
export const getLoadList = () => {
  return request({
    method: 'GET',
    url: '/yfddprovincepowerload/selectAll'
  })
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值