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

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日

相关文章

  • 短视频滑动播放在 H5 下的实现方式

    实现短视频滑动播放在H5下有多种方法,以下是其中两种较为常见的方式。 方式一:使用 H5 视频插件 实现步骤 在 HTML 中插入视频标签,例如: <video src="your_video.mp4" width="100%" controls></video> 其中 src 属性为视频文件的…

    css 2023年6月10日
    00
  • css实现3d立体魔方的示例代码

    实现3D立体魔方的示例代码需要使用CSS 3D transform属性。 设定CSS样式 首先,我们需要给魔方定义一个立方体容器,然后给每个面分别定义CSS样式。对于每一个面,需要设置其宽高和位置。 下面是一个示例: .cube { position: relative; margin: 100px auto; transform-style: preser…

    css 2023年6月10日
    00
  • Bootstrap基本模板的使用和理解1

    Bootstrap基本模板的使用和理解1 Bootstrap是一种用于快速构建Web应用程序界面的现代化前端框架。它基于HTML,CSS和JavaScript,为开发者提供了许多可重用的代码和工具,从而可以更轻松地创建响应式,移动优先的网站设计。 什么是Bootstrap基本模板 Bootstrap基本模板是一个已经经过样式处理和布局设计的HTML页面,它内…

    css 2023年6月10日
    00
  • CSS中Single Div 绘图技巧的实现

    CSS中的Single Div绘图技巧是一种极具创意和技巧性的CSS绘图方法,是利用一个元素(div)的伪元素(::before和::after)来绘制出复杂的图形。以下是Single Div绘图技巧的实现攻略: 1. 了解CSS中伪元素的使用方法 在CSS中,伪元素如::before和::after可以用来在一个元素前面或后面插入内容,这些内容与元素的内容…

    css 2023年6月10日
    00
  • javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等

    获取和判断浏览器窗口、屏幕、网页的高度、宽度等是前端开发基础中非常重要的知识点,在网站开发中常常会使用到。JavaScript提供了多种方式来获取这些值,下面是这些方法的详细讲解: 获取浏览器窗口的高度和宽度 获取浏览器窗口的高度和宽度可以使用window.innerHeight和window.innerWidth这两个属性来实现,代码如下: console…

    css 2023年6月10日
    00
  • IE6、IE7、IE8浏览器下的CSS、JS兼容性对比

    IE6/IE7/IE8浏览器下的CSS兼容性问题 在现代的浏览器中,我们可以使用最新的CSS属性来创建漂亮的网页,但是在IE6/IE7/IE8等老旧的浏览器中,我们需要注意一些CSS兼容性问题。 盒模型 在标准盒模型(box-sizing: content-box)中,元素的width和height只包括内容的宽和高,但在IE6/IE7/IE8等旧版浏览器中…

    css 2023年6月10日
    00
  • 纯CSS实现的三列布局网页效果实例

    接下来我将为你详细讲解“纯CSS实现的三列布局网页效果实例”的完整攻略。 什么是三列布局 三列布局指的是将一个网页分成左侧、中间、右侧三个区域的布局方式。通常情况下,左右两列固定宽度,中间列自适应宽度。 纯CSS实现三列布局的步骤 下面是使用纯CSS实现三列布局的步骤: 定义HTML结构 在HTML中,需要定义三个div元素分别作为三栏的容器。一般情况下,中…

    css 2023年6月10日
    00
  • JavaScript的Backbone.js框架的一些使用建议整理

    我来为你详细讲解一下“JavaScript的Backbone.js框架的一些使用建议整理”的完整攻略。 一、Backbone.js框架 Backbone.js是一个轻量级的JavaScript框架,用于Web应用程序和单页应用程序(SPA)的开发。它提供了一个MVC(Model-View-Controller)模式的结构,使得Web开发更加简单和高效。 1.…

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