用到知识点:具名插槽设置默认值,具名插槽,插槽作用域,数组循环,对象循环
实现原理: 如果父组件不传结构子组件就是默认结构,如果父组件传结构,子组件可以提供数据到父组件,父组件根据子组件传的数据传不同的结构进来
设计思路:
(1):mytable.vue作为一个通用模板(子组件)
(2)tablelist.vue调用子组件,传入行数据(data)和页面需要渲染的列数组(headercol)
(3)在子组件里面的逻辑
循环行数据:<tr v-for="(item, index) in data" :key="index">
循环页面需要渲染的列: <template v-for="(item1,index1) in headercol" :key="index1">
在循环每个数据对象里面的每一列:<template v-for="(item2, key2, index2) in item" :key="index2">
如果循环到的当前列名和数据对象的某一个列相等,就取当前数据对象的这一列的值,赋默认值给当前列的具名插槽,通过插槽作用域将值传递到父组件,方便父组件拿到数据做自定义结构的传递:
<template v-if="item1.field==key2">
<td><slot :name="key2" :[key2]="item2">{{item2}}</slot></td>
</template>
</template>
<!--如果列渲染传入了操作,就定义对应的操作栏,并定义对应的插槽,将将当前行的数据提供给父组件-->
<template v-if="item1.field=='操作'">
<td>
<slot name="chaozuo" :rowdata="item">
</slot>
<!-- 默认插槽,如果父组件没有指定名称就会调用呢个插槽 -->
<slot>
</slot>
</td>
</template>
</template>
</tr>
(4)父组件就可以进行在调用组件的时候就可以调用插槽,传入结构
<mytable :data="list" :headercol="column">
<template #no="{no}">
<span style="color:red;">{{no}}</span>
</template>
<template #sex="{sex}">
<span v-if="sex==1">男</span>
<span v-if="sex==0">女</span>
</template>
<template #chaozuo="{rowdata}">
<button type="button" @click="Remove(rowdata.id)">删除</button>
</template>
<!-- 此处没有指定插槽名称,就调用默认插槽,调用mytable里面没有指定名称得slot -->
<button type="button" >详情</button>
</mytable>
(5):注意:这里的#chaozuo="{rowdata}"就是 v-slot:chaozuo="{rowdata}"的简写,rowdata就是子组件插槽提供的数据,呢里提供的是行数据,操作最好提供行数据,列渲染最好只提供列数据
以下是完代码实现:
1:父组件代码建一个tablelist.vue
<template>
<mytable :data="list" :headercol="column">
<template #no="{no}">
<span style="color:red;">{{no}}</span>
</template>
<template #sex="{sex}">
<span v-if="sex==1">男</span>
<span v-if="sex==0">女</span>
</template>
<template #chaozuo="{rowdata}">
<button type="button" @click="Remove(rowdata.id)">删除</button>
</template>
<!-- 此处没有指定插槽名称,就调用默认插槽,调用mytable里面没有指定名称得slot -->
<button type="button" >详情</button>
</mytable>
</template>
<script>
import mytable from "./mytable.vue";
export default {
name: "App",
data() {
return {
list: [],
column: [
{ field: "name", title: "名字", width: 180 },
{ field: "no", title: "编号", width: 180 },
{ field: "sex", title: "性别", width: 180 },
{ field: "操作", title: "操作", width: 180 },
],
};
},
components: {
mytable,
},
created() {
this.getDataGet();
},
methods: {
getDataGet() {
var api = "/Test/ToJson";
var param = new URLSearchParams();
param.append("id1", "111");
param.append("name1", "666");
this.$Http
.get(api, { params: param })
.then((response) => {
this.list = response.data;
})
.catch((err) => {
alert(err);
});
},
Remove(id) {
this.list = this.list.filter((m) => m.id != id);
},
},
};
</script>
2:子组件代码新建一个mytable.vue
<template>
<table style="width: 300px;margin-left:40%;">
<thead>
<tr>
<th v-for="(item, index) in headercol" :key="index">
{{ item.title }}
</th>
</tr>
</thead>
<tbody>
<!-- 循环数据行 -->
<tr v-for="(item, index) in data" :key="index">
<!-- 循环页面需要渲染得列 -->
<template v-for="(item1,index1) in headercol" :key="index1">
<!-- 循环每个数据行结构 -->
<template v-for="(item2, key2, index2) in item" :key="index2">
<!-- 将要渲染得列一个一个拿到数据行结构里面做循环对比,如果相等,就渲染当前数据结构里面得数据-->
<template v-if="item1.field==key2">
<!-- 用到知识点(具名插槽赋默认值,具名插槽,插槽作用域)-->
<!--实现原理: 如果父组件不传结构给子组件就是默认结构,如果父组件传结构,子组件可以提供数据到父组件,父组件根据子组件传的数据传不同的结构进来 -->
<td>
<slot :name="key2" :[key2]="item2">
{{item2}}
</slot>
</td>
</template>
</template>
<template v-if="item1.field=='操作'">
<td>
<slot name="chaozuo" :rowdata="item">
</slot>
<!-- 默认插槽,如果父组件没有指定名称就会调用呢个插槽 -->
<slot>
</slot>
</td>
</template>
</template>
</tr>
</tbody>
</table>
</template>
<script>
export default {
name: "MyTable",
props: {
data: {
type: Array,
required: true,
default() {
return [];
},
},
headercol: {
type: Array,
required: true,
default() {
return [];
},
},
},
data() {
return {};
},
components: {},
methods: {},
};
</script>
3:后端api
[Route("/api/Test")]
[ApiController]
public class TestController : ControllerBase
{
[Route("ToJson")]
[HttpGet]
public string ToJson(string id1, string name1)
{
List<people> peoples = new List<people>() {
new people() { name="zhangsan",no="111",id="1",sex="0"} ,
new people() { name="zhangsan1",no = "222" ,id="2",sex="0"},
new people() { name="zhangsan2",no="333",id="3",sex="1"} ,
new people() { name="zhangsan3",no = "444" ,id="4",sex="1"}
};
string ListJson = JsonConvert.SerializeObject(peoples);
return ListJson;
}
}
public class people
{
public string id { get; set; }
public string name { get; set; }
public string no { get; set; }
public string sex { get; set; }
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现