Vue开发系列——自定义组件开发

目录

一、组件开发优势

二、组件开发步骤

步骤1、编写组件代码

[步骤2、 子组件注册](#步骤2、 子组件注册)

局部注册

全局注册

步骤3、父组件给自定义的组件传参并调用

三、总结


一、组件开发优势

组件化开发允许你构建可重用、可维护的代码模块,这些模块可以单独测试和组合使用。

二、组件开发步骤

步骤1、 编写组件代码

步骤2、注册组件(全局注册、局部注册)

步骤3、使用组件

步骤1、编写组件代码

组件的.vue文件中,可以定义模板、脚本和样式。 例如,开发一个显示柱状图的组件。其中,X轴数据、Y轴数据由父组件传入,子组件主要负责画出如下的柱状图:

子组件定义位置 serviceCompents/Course/chart.vue,定义的内容如下:

javascript 复制代码
<template>
  <div>
    <el-button type="primary" @click="startGenEcharts()">刷新图表</el-button>
    <div class="echart" id="mychart" :style="myChartStyle"></div>
  </div>
</template>
<script>

import * as echarts from 'echarts';

export default {
    name: 'CourseChart',
    props: {
        dataX: {
            type: Array
          },
        dataY: {
          type: Array
        }
    },
    data(){
        return {
          myChartStyle: { float: "left", width: "100%", height: "300px" }, //图表样式
        }
    },
    methods: {
      startGenEcharts() {
        let dataX = this.dataX;
        let dataY =  this.dataY;

        let colorList = ['#0CB500', '#FFD634', '#01DAE2', '#FF5555', '#03B8DE', '#4AE879', '#FF8800', '#DBDBDB', '#ABEAFF'];
       var  myoption = {
          fontSize: 8,
            tooltip: {
            trigger: 'axis'
          },
          grid: {
            left: 0, //左边距
              right: 0, //走边距
              top: 15, //上边距
              bottom: 0, //下边距
              containLabel: true
          },
          xAxis: {
            name: '不及格率',//x轴名称
            nameLocation: 'middle', // 控制名字的位置,如 'start' 或 'middle'
            nameGap: 20,
            nameTextStyle: {
              fontSize: 15,
              color: 'red'
            },
            type: 'category',
            boundaryGap: [0, '30%'],
            //坐标轴斜着显示
              axisLabel: {
              interval: 0,
                rotate: 20,
                fontSize: 18
            },
            axisLine: {
              //x轴
              show: false, //线条隐藏
                lineStyle: {
                //文字颜色
                color: '#333'
              }
            },
            axisTick: {
              //y轴刻度线
              show: false
            },
            data: dataX
          },
          yAxis: {
            name: '平均分', // 直接在 yAxis 配置中设置 name,显示在坐标轴旁边(对于 category 类型)或下方(对于 value 类型)
            nameTextStyle: { // 定制坐标轴名称的样式
              color: 'red',
              fontSize: 15,
              fontWeight: 'bold'
            },
            nameLocation: 'start', // 可以是 'start' 或middle 'end',表示名称在坐标轴的开始或结束位置
            nameRotate: 0, //0或90 旋转角度,默认是水平方向,如果想让名称垂直显示可以设置旋转角度
            nameGap: 15, // 名称与坐标轴线之间的距离
            type: 'value',
              boundaryGap: [0, '30%'],
              axisLine: {
              //y轴
              show: false, //线条隐藏
                lineStyle: {
                //文字颜色
                color: '#333'
              }
            },
            axisLabel: {
              fontSize: 18
            },
            //网格线颜色
            splitLine: {
              show: true,
                lineStyle: {
                color: ['#307DCB'],
                  width: 1,
                  type: 'solid'
              }
            },
            axisTick: {
              //y轴刻度线
              show: false
            }
          },
          series: [
            {
              name: '平均成绩',
              data: dataY,
              type: 'bar',
              itemStyle: {
                normal: {
                  color: function (params) {
                    return colorList[params.dataIndex];
                  },
                  label: {
                    show: true, //开启显示
                    position: 'top', //在上方显示
                    textStyle: {
                      //数值样式
                      color: '#333',
                      fontSize: 18
                    }
                  }
                }
              }
            }
          ]
        };
        this.myChart = echarts.init(document.getElementById("mychart"));
        this.myChart.setOption(myoption);
        //随着屏幕大小调节图表
        window.addEventListener("resize", () => {
          this.myChart.resize();
        });
      }

    },
    mounted(){
      this.startGenEcharts();
    }
}
</script>
<style scoped>
.run-box{
    margin-bottom: -1px;
    padding: 4px 8px;
    border: 1px solid #dcdfe6;
    border-radius: 3px;
}

</style>

注意:

1、 使用Props传递数据到组件。比如示例中有如下定义,表示将从外部向组件传入dataX, dataY两个Array类型的数据

复制代码
props: {
    dataX: {
        type: Array
      },
    dataY: {
      type: Array
    }
}

步骤2、 子组件注册

注册组件(全局注册、局部注册)

局部注册

父组件.vue文件中:

import CourseChart from '@src/serviceComponents/Course/chart';//子组件定义位置

export default {

name: "courseScoreOverviewList",

components: {
CourseChart
},

data() {

return {

...此时省略内容

全局注册

import Vue from 'vue';

import App from './App.vue';

import CourseChart from '.@src/serviceComponents/Course/chart';// 具体路径添加上.vue也可以Vue.component('CourseChart', CourseChart);

new Vue({

render: h => h(App),

}).$mount('#app');

步骤3、父组件给自定义的组件传参并调用

注意: 通过props在父组件和子组件之间传递数据.++实际上用于父组件给子组件传递数据++

父组件.vue文件内容:

javascript 复制代码
<el-dialog title="成绩分析" :visible.sync="dialogVisibleForEcharts" fullscreen>
  <div style="margin-left: 80px; margin-bottom: 60px;">
    <CourseChart :dataY="this.list.map(item => toFixed(item.avgStuScores),2)" :dataX="this.list.map(item => toFixed(item.totalFailStuScoresRate,2))"></CourseChart>
  </div>

</el-dialog>


import CourseChart from '@src/serviceComponents/Course/chart';//子组件定义位置

export default {
  name: "courseScoreOverviewList",
  components: {
     CourseChart
  },
  data() {
    return {
...此时省略内容

注意:在子组件中,你可以使用$emit触发事件,并在父组件中监听这些事件。

三、总结

1、 子组件可以继续组合形成更大的子组件来使用

2、 父组件可以通过props给子组件传递数据。 数据的类型可以多种多样.比如,

  • 当父组件通过props给子组件传递Array数据时,子组件声明:
复制代码
props: {
    dataX: {
        type: Array
      },
    dataY: {
      type: Array
    }
}
  • 当父组件通过props给子组件传递字符串、整形等基本数据时,子组件声明:
复制代码
props: ['productId', 'taskId', 'resultId']
  • 当父组件通过props给子组件传递Object数据时,子组件声明:

props: {

dataX: {

type: Object

}

}

相关推荐
Lethehong3 分钟前
简历优化大师:基于React与AI技术的智能简历优化系统开发实践
前端·人工智能·react.js·kimi k2·蓝耘元生代·蓝耘maas
华仔啊11 分钟前
还在用 WebSocket 做实时通信?SSE 可能更简单
前端·javascript
鹏北海33 分钟前
多标签页登录状态同步:一个简单而有效的解决方案
前端·面试·架构
_AaronWong37 分钟前
基于 Vue 3 的屏幕音频捕获实现:从原理到实践
前端·vue.js·音视频开发
孟祥_成都1 小时前
深入 Nestjs 底层概念(1):依赖注入和面向切面编程 AOP
前端·node.js·nestjs
let_code1 小时前
CopilotKit-丝滑连接agent和应用-理论篇
前端·agent·ai编程
Apifox1 小时前
Apifox 11 月更新|AI 生成测试用例能力持续升级、JSON Body 自动补全、支持为响应组件添加描述和 Header
前端·后端·测试
木易士心1 小时前
深入剖析:按下 F5 后,浏览器前端究竟发生了什么?
前端·javascript
在掘金801101 小时前
vue3中使用medium-zoom
前端·vue.js
xump2 小时前
如何在DevTools选中调试一个实时交互才能显示的元素样式
前端·javascript·css