自研国产零依赖前端UI框架实战005封装第一个表格组件

Python私教 2024-12-30 11:53:21
前言

之前我们已经实现了随机用户数据的生成, 渲染, 格式化美化, 已经具备了基本的功能.

而且我们还封装了一个random随机模块和table样式模块, 能够更好的复用于后面的项目和案例.

接下来我们做些什么呢?

这里我的想法是对表格数据渲染进行封装,封装一个组件,这个组件接收表格的头部信息和内容信息,自动对数据进行提取和渲染.

那么我们开始做吧!!!

实践出真知!!!

简单的组件封装

接下来, 我们直接创建一个zdp_table1.vue, 然后把之前的App.vue中的代码复制过去, 稍微调整一下引入的地址, 代码如下:

<script setup>import {onMounted, ref} from "vue";import random from "../js/random.js";import "../css/table.css";let users = ref(random.users(8))</script><template>  <div>    <table>        <td>{{ index + 1 }}</td>        <td>{{ user.name }}</td>        <td>{{ user.age }}</td>      </tr>      </tbody>    </table>  </div></template>

然后, 在App.vue中引入这个组件就行了, 代码如下:

<script setup>import zdp_table1 from "./zdpui/components/zdp_table1.vue";</script><template>  <div>    <zdp_table1/>  </div></template>

此时的项目结构如下:

在这里插入图片描述

浏览器访问: http://localhost:5173/

在这里插入图片描述

可以发现效果还是和之前一样, 并没有变化, 说明我们封装得很成功.

新的想法

这个时候我们就需要进一步封装了, 那么有没有什么新的想法呢?

我的想法是传递一个columns作为头部数据进行, 再传递一个data作为表格数据进来, 但是这两个参数都不是必传的, 如果这两个参数都没有传, 那么我们还是使用原来的随机生成的用户数据.

如果传递了,则使用新的数据替代.

那么这个该怎么玩呢?

我来想一想步骤:

1.在zdp_table1中定义属性,接收columns和data作为参数2.直接给这两个参数分别赋值默认值, 如果没有传就使用默认值3.根据columns和data动态渲染表格

那么我们继续开搞!!!

定义表格的属性

首先是columns:

columns:{    type:Array,    default:function(){      return [        {          title:"序号",          key:"id",          width:80,          align:"center"        },        {          title:"姓名",          key:"name",          width:100,          align:"center"        },        {          title:"年龄",          key:"age",          width:100,          align:"center"        }      ]    }  }

然后是数据:

data: {  type: Array,    default: function (){      return random.users(8)    }}

接下来表头应该根据columns动态的进行渲染:

在这里插入图片描述

此时页面的渲染效果如下:

在这里插入图片描述

可以发现已经生效了, 但是表的内容没有跟随传进来的表头的内容, 所以这个代码还得继续改造一下.

首先见tbody改造如下:

<tbody><tr v-for="(v, k) in props.data" :key="k">  <template v-for="(vv,kk) in props.columns" :key="kk">    <td>      {{ v[vv.key]}}    </td>  </template></tr></tbody>

这样我们就能够实现数据是从columns里面动态的取出来的, 此时观察一下页面, 确保页面还是正常的.

然后我们接着开搞!!!

计算列的样式

封装一个方法, 计算列的样式:

const columnStyle = column => {  let style = {}  // 长宽对齐等基本样式  if (column.width) style.width = column.width + 'px'  if (column.height) style.height = column.height + 'px'  if (column.align) style.textAlign = column.align  // 超过一行变省略号  style.maxWidth = (column.maxWidth ?? 500) + 'px';  style.overflow = 'hidden';  style.textOverflow = 'ellipsis';  style.whiteSpace = 'nowrap';  return style}

最后, 再把这个方法应用到表格中:

<table class="table1">  <thead>    <tr>      <template v-for="(v,k) in props.columns" :key="k">        <th            :style="getColumnStyle(v)"            >          {{ v.title }}        </th>      </template>    </tr>  </thead>  <tbody>    <tr v-for="(v, k) in props.data" :key="k">      <template v-for="(vv,kk) in props.columns" :key="kk">        <td            :style="getColumnStyle(vv)"            >          {{ v[vv.key] }}        </td>      </template>    </tr>  </tbody></table>

接着我们再访问 http://localhost:5173/ 进行预览, 可以发现, 不管是表头还是表内容, 都已经实现一致的样式了, 这里都实现了居中对齐的效果.

在这里插入图片描述

此时, 完整的zdp_table1.vue的代码如下:

<script setup>import random from "../js/random.js";import "../css/table.css";const props = defineProps({  columns: {    type: Array,    default: function () {      return [        {          title: "序号",          key: "id",          width: 80,          align: "center"        },        {          title: "姓名",          key: "name",          width: 100,          align: "center"        },        {          title: "年龄",          key: "age",          width: 100,          align: "center"        }      ]    }  },  data: {    type: Array,    default: function () {      return random.users(8)    }  }})// 获取列的样式const getColumnStyle = column => {  let style = {}  // 长宽对齐等基本样式  if (column.width) style.width = column.width + 'px'  if (column.height) style.height = column.height + 'px'  if (column.align) style.textAlign = column.align  // 超过一行变省略号  style.maxWidth = (column.maxWidth ?? 500) + 'px';  style.overflow = 'hidden';  style.textOverflow = 'ellipsis';  style.whiteSpace = 'nowrap';  return style}</script><template>  <div>    <table          >            {{ v[vv.key] }}          </td>        </template>      </tr>      </tbody>    </table>  </div></template>

外部传递数据

我们之前使用的是默认值, 如果我现在有一个员工的数据, 想要渲染员工数据该如何操作呢?

这里为了和默认数据区分, 我特意在columns里面加了员工编号, 然后内容只生成了三条.

修改App.vue, 此时完整代码如下:

<script setup>import zdp_table1 from "./zdpui/components/zdp_table1.vue";import random from "./zdpui/js/random.js";const columns = [  {    title: "员工编号",    key: "id",    width: 80,    align: "center"  },  {    title: "姓名",    key: "name",    width: 100,    align: "center"  },  {    title: "年龄",    key: "age",    width: 100,    align: "center"  }]const data = random.users(3)</script><template>  <div>    <zdp_table1        :columns="columns"        :data="data"    />  </div></template>

接着我们再访问 http://localhost:5173/ 进行预览, 可以发现, 已经针对自定义的数据, 实现了渲染.

在这里插入图片描述

哈哈, 做到这一步的时候感觉好爽, 很有成就感!!!

总结

到目前为止, 我们就实现了zdp-table1这个组件的基本封装, 支持传递自定义的样式, 支持自定义表头, 表数据会自动根据表头的配置自动提取数据, 整体而言, 这个表格还是相对比较强大的.

不过这都只是玩具级别的, 因为真正的数据大部分情况下都是非常多的, 我们不可能一次性把这么多数据直接渲染出来, 我们还需要支持分页.

所以接下来要研究一下,分页该如何搞, 怎么把分页封装到我们的表格组件里面去.

0 阅读:0

Python私教

简介:全栈工程师,目标人工智能.抖音同理想国真恵玩.