起因是我在做项目的时候,遇到了许多样式一样,但是展示数据不一样的页面。如:
或者
可以看到,这两组页面的样式、方法、数据结构都是一样的,只是具体数据不一样。 所以若把其一样的部分抽成一个数据可变的组件,复用性就会很强。
(ps:组件除了复用性高,还有减少耦合度,除此以外,只能通过组件提供的公共接口来操作数据,可以提高代码安全性,可靠性)
今天就来分享一下如何基本的实现数据可变的组件,在此之前,要先了解一个知识:
父传子-prop引用类型值传递
- 在父组件传子组件中,若prop是对象(引用类型),子组件中改变prop内属性的值,那么父组件的值也会随之改变,如:
- 父组件
let prop = {
dataTypes,
value,
tableData,
dataHeight,
total,
changeVal, //函数
text: "仓库"
}
- 子组件
let prop = defineProps(["prop"]);
let value = prop.prop.value;
let dataTypes = prop.prop.dataTypes;
let tableData = prop.prop.tableData;
... ...
//子组件里的这些变量是对父组件里变量的引用
在这里,改变子组件里对父组件引用的值,父组件里的值也会改变。
因为我的页面子组件改变父组件数据并无影响,且有好处,所以我用了这种方式。
但若你不希望子组件能改变父组件的传值(如弹窗),你可以使用JSON.parse(JSON.stringify(data))来实现深拷贝
组件实现
- 父组件传给子组件的信息有
1. 数据类型(名称)
ex: 通过对象遍历数据类型去更精准获取数据
let dataTypes = {
id: "仓库号",
name:"货品名称",
ware: "仓库",
source: "货品来源",
total: "总库存",
g: "单位",
date: "保质期"
};
2. 具体数据
let tableData:dataType[] = reactive([]);
for(let i = 0;i<value.value;i++) {
let obj:dataType ={
id: "20230"+i,
name: 'Tom',
ware: "仓库"+i,
source: "来源"+i,
total: i*10+5+3*i,
g: "单位",
date: "2023-06-"+i,
}
tableData.push(obj)
}
3. api方法
(重新设置宽度与数据数量)
function changeVal(val: number):number {
if(val<15) {
dataHeight.value = false;
}else {
dataHeight.value = true;
}
tableData.length = 0;
for(let i = 0;i<value.value;i++) {
let obj:dataType ={
id: "20230"+i,
name: 'Tom',
ware: "仓库"+i,
source: "来源"+i,
total: i*10+5+3*i,
g: "单位",
date: "2023-06-"+i,
}
tableData.push(obj)
}
return value.value;
}
- 然后把他们都放进prop里,传给子组件,就可以使用啦
//父组件
<template>
<div class="ware">
<tablePart :prop="prop"></tablePart> //子组件
</div>
</template>
import tablePart from "子组件地址"
let prop = {
dataTypes,
value,
tableData,
dataHeight,
total,
changeVal,
text: "仓库"
}
- 子组件里的具体用法
//子组件
//把api->changeVal直接使用
<el-select v-model="value" class="m-2" size="small" @change="changeVal">
//el组件,data传入总数据,然后在colum里遍历数据类型(对象遍历),通过key可以获取每一组数据里的每个数据
<el-table :data="tableData" style="height: 100%;" :border="true" :header-cell-style="{ background: '#34C9A3', color: '#ffffff' }" size="default" default-expand-all>
<el-table-column :prop="key" :label="label" v-for="(label, key) in dataTypes" :key="key"/>
</el-table>
这样子就只需要通过传递相应的数据类型,实现一样的样式与功能啦。
如有问题,尽请评论 qq:2473506690