vue3新拟态组件库开发流程之table组件源码分析

yizhihongxing

Vue3新拟态组件库开发流程之table组件源码分析攻略

1. 前言

Vue3作为一款优秀的前端框架,不断地为前端开发者带来更加方便和高效的开发模式。其中,拟态风格越来越受到大家的关注,为此,我们今天就来学习一下Vue3新拟态组件库开发流程中的table组件源码分析。

2. 源码分析

2.1. 源文件结构

table组件的源码位于/src/components/table目录下,相关文件和目录如下:

- table/
  - index.js
  - table.vue
  - table-cell.vue
  - table-header.vue
  - table-row.vue

源文件结构非常清晰,其中index.js是对外的入口文件,table.vue是table组件的主体代码。

2.2. 主体代码分析

首先,我们先看一下table.vue的代码。

<template>
  <table>
    <thead>
      <tr>
        <TableHeader
          v-for="(column, key) in columns"
          :key="key"
          :column="column"
          @sortChange="handleSortChange"
        />
      </tr>
    </thead>
    <tbody>
      <TableRow
        v-for="(row, rowIndex) in rows"
        :key="rowIndex"
        :row="row"
        :columns="columns"
      />
    </tbody>
  </table>
</template>

<script>
import TableHeader from './table-header.vue'
import TableRow from './table-row.vue'

export default {
  name: 'VTable',
  components: {
    TableHeader,
    TableRow
  },
  props: {
    columns: {
      type: Array
    },
    rows: {
      type: Array
    },
    sortColumn: {
      type: String,
      default: ''
    },
    sortOrder: {
      type: String,
      default: 'ascending'
    }
  },
  methods: {
    handleSortChange(column) {
      this.$emit('sort-change', column)
    }
  }
}
</script>

可以看到,table.vue主体代码非常简单,只包含一个<table>标签,其中含有两个子组件TableHeaderTableRow,还有几个props和一个监听事件。我们可以针对这几个部分做一个具体分析。

2.2.1. TableHeader部分

接下来我们看一下TableHeader组件的代码,它负责将传入的列信息展示在表格上部。TableHeader组件的代码如下:

<template>
  <th>
    <slot>{{ column.label }}</slot>
    <span v-if="column.sortable" class="sort-icon" :class="{ active: isSorted(column) }">
      <svg viewBox="0 0 24 24">
        <path
          d="M7.41 8.59L6 7.17V21a1 1 0 0 0 2 0V7.17l-1.41 1.42A1 1 0 0 0 6 9a1 1 0 0 0 .71.29 1 1 0 0 0 .7-.29l2.58-2.59a1 1 0 0 0 0-1.41 1 1 0 0 0-1.41 0z"
        />
      </svg>
    </span>
  </th>
</template>

<script>
export default {
  name: 'TableHeader',
  props: {
    column: {
      type: Object
    }
  },
  methods: {
    isSorted(column) {
      return column.prop === this.sortColumn
    },
    handleClick() {
      this.$emit('sortChange', this.column.prop)
    }
  }
}
</script>

主要由一个<th>标签组成,标签内部包含列名称column.label和排序图标。排序图标的显示受到列是否可排序以及当前列是否是排序列的影响。

2.2.2. TableRow部分

接下来我们看一下TableRow组件的代码,它负责将传入的行信息展示在表格上。TableRow组件的代码如下:

<template>
  <tr>
    <TableColumn
      v-for="(column, key) in columns"
      :key="key"
      :column="column"
      :row="row"
    />
  </tr>
</template>

<script>
import TableColumn from './table-column.vue'

export default {
  name: 'TableRow',
  components: {
    TableColumn
  },
  props: {
    columns: {
      type: Array
    },
    row: {
      type: Object
    }
  }
}
</script>

TableRow包含多个<TableColumn>组件,对于每一列信息,它都会将它传入到TableColumn组件内部去渲染,这里使用了v-for指令来遍历所有列信息并渲染。TableColumn组件是一个公共组件,我们将在下一个小节进行讲解。

2.2.3. TableColumn部分

最后我们看一下TableColumn组件的代码,它负责将传入的数据信息展示在表格上。TableColumn组件的代码如下:

<template>
  <td>
    <slot>{{ row[column.prop] }}</slot>
  </td>
</template>

<script>
export default {
  name: 'TableColumn',
  props: {
    column: {
      type: Object
    },
    row: {
      type: Object
    }
  }
}
</script>

我们看到,TableColumn组件仅仅只包含一个<td>标签,同时它也使用了插槽来动态获取每一行的指定列中的值并进行渲染。这里我们对组件的重利用达到了最大的优化。

3. 示例说明

我们该如何使用这个table组件呢?下面我们来举两个简单的示例说明。

3.1. 基本用法

<template>
  <div>
    <VTable
      :columns="columns"
      :rows="rows"
      @sort-change="sortChangeHandler"
      :sortColumn="sortColumn"
      :sortOrder="sortOrder"
    />
  </div>
</template>

<script>
import VTable from '@/components/table/index.js'

export default {
  name: 'example',
  components: {
    VTable
  },
  data() {
    return {
      columns: [
        { label: '姓名', prop: 'name', sortable: true },
        { label: '年龄', prop: 'age', sortable: true },
        { label: '性别', prop: 'gender' }
      ],
      rows: [
        { name: '小明', age: 18, gender: 1 },
        { name: '小红', age: 16, gender: 0 },
        { name: '小李', age: 20, gender: 1 },
        { name: '小白', age: 18, gender: 0 },
        { name: '小黄', age: 19, gender: 1 }
      ],
      sortColumn: '',
      sortOrder: 'ascending'
    }
  },
  methods: {
    sortChangeHandler(column) {
      if (column === this.sortColumn) {
        this.sortOrder = this.sortOrder === 'ascending' ? 'descending' : 'ascending'
      } else {
        this.sortColumn = column
        this.sortOrder = 'ascending'
      }
      this.sortRows()
    },
    sortRows() {
      this.rows.sort((row1, row2) => {
        let ascending = this.sortOrder === 'ascending' ? 1 : -1
        let descending = -ascending
        if (row1[this.sortColumn] > row2[this.sortColumn]) {
          return ascending
        } else if (row1[this.sortColumn] < row2[this.sortColumn]) {
          return descending
        } else {
          return 0
        }
      })
    }
  }
}
</script>

以上代码实现了一个简单的表格展示功能,其中columnsrows是table组件的props,分别对应表格的列信息和行信息。如果某一列可以排序,对应的column对象中的sortable值为true,并且用户可以点击表头中的排序图标进行升序或降序排列。sortColumnsortOrder分别表示当前排序的列和顺序。

3.2. 带分页功能

<template>
  <div>
    <div class="table-pagination">
      <el-pagination
        v-model="currentPage"
        :total="rows.length"
        :page-size="pageSize"
        :current-page.sync="currentPage"
        :prev-text="'上一页'"
        :next-text="'下一页'"
        :layout="'prev, pager, next'"
      />
    </div>
    <VTable
      :columns="columns"
      :rows="currentPageRows"
      @sort-change="sortChangeHandler"
      :sortColumn="sortColumn"
      :sortOrder="sortOrder"
    />
  </div>
</template>

<script>
import VTable from '@/components/table/index.js'
import { ElPagination } from 'element-plus'

export default {
  name: 'example',
  components: {
    VTable,
    ElPagination
  },
  data() {
    return {
      columns: [
        { label: '姓名', prop: 'name', sortable: true },
        { label: '年龄', prop: 'age', sortable: true },
        { label: '性别', prop: 'gender' }
      ],
      rows: [
        { name: '小明', age: 18, gender: 1 },
        { name: '小红', age: 16, gender: 0 },
        { name: '小李', age: 20, gender: 1 },
        { name: '小白', age: 18, gender: 0 },
        { name: '小黄', age: 19, gender: 1 }
      ],
      sortColumn: '',
      sortOrder: 'ascending',
      currentPage: 1,
      pageSize: 3
    }
  },
  computed: {
    currentPageRows() {
      let start = (this.currentPage - 1) * this.pageSize
      let end = start + this.pageSize
      return this.rows.slice(start, end)
    }
  },
  methods: {
    sortChangeHandler(column) {
      if (column === this.sortColumn) {
        this.sortOrder = this.sortOrder === 'ascending' ? 'descending' : 'ascending'
      } else {
        this.sortColumn = column
        this.sortOrder = 'ascending'
      }
      this.sortRows()
    },
    sortRows() {
      this.rows.sort((row1, row2) => {
        let ascending = this.sortOrder === 'ascending' ? 1 : -1
        let descending = -ascending
        if (row1[this.sortColumn] > row2[this.sortColumn]) {
          return ascending
        } else if (row1[this.sortColumn] < row2[this.sortColumn]) {
          return descending
        } else {
          return 0
        }
      })
    }
  }
}
</script>

以上代码在示例1的基础上加入了分页功能,使用了Element Plus的分页组件。其中,计算属性currentPageRows根据当前页码和每页显示的数量计算出当前页需要展示的数据行,然后传入到VTable组件中进行渲染。如果用户点击了分页器上的上一页或下一页按钮,currentPage会得到更新,计算属性currentPageRows也会随之更新,自动渲染出新的表格。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue3新拟态组件库开发流程之table组件源码分析 - Python技术站

(0)
上一篇 2023年6月9日
下一篇 2023年6月9日

相关文章

  • 使用html+css实现页面书本翻页特效

    实现页面书本翻页特效可以通过以下步骤实现: 1. 定义HTML结构 首先,你需要定义一个HTML结构以在页面上呈现出一个可翻页的书本效果。在这个HTML结构中,你需要包含一些标签来描述书本的不同部分,例如前/后页面、书本封面、书本内容等等。需要注意的是,这种书本翻页效果大多是使用JavaScript或HTML5 Canvas技术完成的,因此需要在你的HTML…

    css 2023年6月9日
    00
  • CSS3的几个标签速记(推荐)

    下面是对“CSS3的几个标签速记(推荐)”的完整攻略: CSS3的几个标签速记 CSS3 版本相比 CSS2.1 版本有了很多新增的功能和标签。本文介绍了这些 CSS3 标签的速记方式,以方便开发者更加快速地编写样式。 边框 圆角 使用 border-radius 属性可以设置元素的圆角大小: /* 设置四个角的圆角大小为 10px */ div { bor…

    css 2023年6月10日
    00
  • CSS 字体单位em简介

    CSS 字体单位em简介 在CSS中,我们常使用像素(px)作为字体大小的单位。但是,随着Web的不断发展,越来越多的网站采用了响应式设计,而px固定的大小不符合响应式设计所需,因此em成为了更好的选择。 em是什么? em是一个相对单位,根据其父元素的字体大小而定。一般而言,1em等于父元素的字体大小。比如,如果一个段落的字体大小被设置为1.2em,那么字…

    css 2023年6月9日
    00
  • 移动端点击态处理的三种实现方式

    移动端点击态处理是Web开发中的一个重要环节,可以提高网站的用户体验,让用户更加直观地感受网站的交互效果。本文将为大家介绍三种实现移动端点击态处理的常用方式。 一、使用CSS :active 伪类 使用CSS :active伪类是最直接的一种方式,只需要定义一个样式,然后在HTML标签中使用即可。这种方式设置的点击态只有短暂的持续时间,点击一下后立即消失。 …

    css 2023年6月10日
    00
  • DIV重叠 CSS让DIV层叠 两个DIV或多个DIV顺序重叠加

    下面我就来详细讲解一下“DIV重叠 CSS让DIV层叠 两个DIV或多个DIV顺序重叠加”的完整攻略。 概述 在网页设计中,经常会遇到需要将多个DIV重叠在一起的场景,这样可以实现一些特殊的效果。针对这种需求,我们可以通过CSS样式来实现DIV层叠效果。 方法1:使用z-index属性 z-index 属性指定元素的层叠顺序,数值越大越靠前,即越靠近用户。一…

    css 2023年6月9日
    00
  • Bootstrap打造一个左侧折叠菜单的系统模板(一)

    我来详细讲解一下”Bootstrap打造一个左侧折叠菜单的系统模板(一)”的完整攻略。此文章的攻略包含以下三部分: 1. 准备工作 在编写左侧折叠菜单前,需要先引入Bootstrap框架。打开网页http://getbootstrap.com/并按照引导指示下载所需文件即可。同时,该模板基于jQuery,所以也需要在页面中引入jQuery库: <!–…

    css 2023年6月9日
    00
  • 基于JavaScript实现游戏购物车效果详解

    基于JavaScript实现游戏购物车效果详解 背景介绍 本文介绍了如何使用 JavaScript 实现游戏购物车效果。该购物车效果可以用于游戏中的商城系统,用户在商城中选择游戏道具后,可以加入购物车等待结算。 实现步骤 HTML 页面准备 在 HTML 页面中准备两个结构 class 分别为 shop 和 cart,用于展示商城中的商品和购物车中的商品。 …

    css 2023年6月11日
    00
  • 面试官常问的web前端问题大全

    Web前端面试官常问问题大全 Web前端是目前应用最广泛的技术领域之一,随着市场对前端人才的需求不断增长,前端开发岗位的竞争也愈发激烈。因此,在Web前端的面试中,常会被问到一些有关Web前端的基础概念、技术体系和前端开发实战等问题。以下是一些常被Web前端面试官问到的问题: 前端基础 1. HTML 和 XHTML 有什么区别? HTML和XHTML都是用…

    css 2023年6月9日
    00
合作推广
合作推广
分享本页
返回顶部