先来看下实现效果
思路
组件化开发,也就是说复用的代码整合成公共的模块,供需要时使用
也可以理解为当多组功能相同的对象,有不同的表现形式,即功能一样,但是不同的表现形式(比如说是柱状图中不同的数据展现,或者是颜色样式等等)
- 上图中,柱状图为子组件,子组件中封装好了一个画出柱状图的方法,需要传入一些值便可以使用
在这里,传值是重要的操作,子组件去接收父组件传来的值以后,重绘这个柱状图,监听也是很重要的操作
直接上代码:
柱状图子组件.vue
<template>
<div class="bar" id="bar">
</div>
</template>
<script>
export default {
name : "Bar",
//接收从父组件传回的值
props: ["getData"],
data() {
return {};
},
//实时监听父组件传过来的值,进而执行drawBar方法,重绘柱状图
watch:{
getData:{
handler(value){
this.drawBar(value)
},
deep: true
}
},
mounted() {
this.drawBar();
},
methods: {
drawBar({
textTitle = "",
nameTitle = "",
nameArray = [],
dataArray = [],
colorArray = []
} = {}) {
let barBox = this.$echarts.init(document.getElementById("bar"));
let option = {
title: {
text : textTitle,
left : "center",
top : 20,
textStyle: {
color: "#000"
}
},
tooltip: {
trigger : "axis",
axisPointer: {
type: "shadow"
}
},
xAxis: [
{
type : "category",
data : nameArray,
axisTick: {
alignWithLabel: true
}
}
],
yAxis: [
{
type: "value"
}
],
series: [
{
name : nameTitle,
type : "bar",
barWidth : "60%",
data : dataArray,
itemStyle: {
normal: {
color: function(params) {
var colorList = colorArray;
return colorList[params.dataIndex];
}
}
}
}
]
};
barBox.setOption(option, true);
}
}
};
</script>
<style scoped>
</style>
下面是调用这个子组件的父组件
父组件.vue
<template>
<div class="About">
<div class="print_box">
<div class="input_some">
<span>输入标题:</span><input
style = "width:300px;"
type = "text"
v-model = "objectData.textTitle"
placeholder = "请输入标题"
>
</div>
<div class="input_some">
<span>输入数据描述:</span><input
style = "width:300px;"
type = "text"
v-model = "objectData.nameTitle"
placeholder = "请输入数据描述,默认为‘数据类型’"
>
</div>
<div class="input_some">
<div class="text_weight">选择颜色后点击添加按钮</div>
<span>选择颜色:</span><input
type = "color"
v-model = "colorData"
placeholder = "请输入数据描述,默认为‘数据类型’"
>
<button @click="addColorClick">addColor</button>
{{objectData.colorArray}}
</div>
<div class="input_some">
<div class="text_weight">选择颜色后点击添加按钮</div>
<input
style = "width:180px;"
type = "text"
v-model = "leftData"
placeholder = "请输入数据"
>
<input
style = "width:180px;"
type = "text"
v-model = "rightData"
placeholder = "请输入数据对应字段"
>
<button @click=addDataClick()>addData</button>
<div>数据为:{{objectData.dataArray}}</div>
<div>字段为:{{objectData.nameArray}}</div>
</div>
<div class="input_some">
<button @click="clearAll()">清空所有数据</button>
</div>
</div>
<Bar
class = "about_bar"
:get-data = "objectData"
></Bar>
</div>
</template>
<script>
import Bar from "./template/Bar";
export default {
name: "About",
data() {
return {
objectData: {
textTitle : "",
nameTitle : "",
nameArray : [],
dataArray : [],
colorArray: []
},
leftData : "",
rightData: "",
colorData: "#000000"
};
},
components: {
Bar
},
mounted() {},
methods: {
addDataClick() {
this.objectData.dataArray.push(this.leftData);
this.objectData.nameArray.push(this.rightData);
},
addColorClick() {
this.objectData.colorArray.push(this.colorData);
},
clearAll() {
for (const key in this.objectData) {
const element = this.objectData[key];
if (typeof element == "string") {
this.objectData[key] = "";
}else if (typeof element == "object") {
this.objectData[key] = [];
}
}
}
}
};
</script>
<style scoped>
.about_bar {
width : 100%;
height: 300px;
}
.print_box {
width : 90%;
height : 300px;
padding: 20px;
}
.input_some {
margin-top: 5px;
border-top: 1px solid #ccc;
}
.text_weight {
font-size : 22px;
font-weight: 800;
}
</style>
输入框只是为了模拟传入的数据,最主要的就是把父组件中的objectData传入子组件即可
实际开发中,ajax请求到数据后,处理完成,赋值给objectData即可,子组件中因为有watch监听这个objectData,所以,会实时刷新柱状图
一个简单粗暴的柱状图小组件,优化完善的地方还有很多,不过这个例子足以表达组件化开发是怎么样实现的,之前有前辈说可以用vuex,不过我觉得组件传值就够了,杀鸡焉用牛刀?
插一嘴,main.js中引入Echarts代码👇
import Vue from 'vue'
import App from './App.vue'
import store from './store'
import router from './router'
import Echarts from 'echarts'
Vue.config.productionTip = false
Vue.prototype.$echarts = Echarts
new Vue({
store,
router,
render: h => h(App)
}).$mount('#app')
这里卿洋
愿喜❤️