Vue3+Element Plus 二次封装el-table

6,972 阅读1分钟

最近终于学完Vue3的新语法,试着用Vue3+Element Plus做些小demo

开始

新建Vue3+TS项目,并安装Element Plus

在main.ts引入Element Plus

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

app.use(ElementPlus)

在components文件夹新建simple-table.vue

表头由外层传入,按钮默认展示编辑和删除,由外层slot传入按钮,便于维护吧

代码如下

<template>
  <div class="table-content">
    <h1>table</h1>
    <el-table :data="tableData" border fix style="width: 80%" size='small'>
      <!-- 多选 -->
      <el-table-column v-if="selectionIsNeed" type="selection"  width="55"> </el-table-column>
      <!-- 表头 -->
      <el-table-column v-for="column in columns" :key="column.prop" fixed
        :prop="column.prop" 
        :label="column.label" 
        :min-width="column.minWidth"
        >
      </el-table-column>
      <!-- 操作 -->
      <el-table-column v-if="optionIsNeed" fixed="right" label="操作" :width="optionWidth">
        <template #default="scope">
          <slot name="prev" :scope='scope'></slot>
          <el-button v-if="editIsNeed" @click="handleEdit(scope.$index, scope.row)" type="text" size="small">编辑</el-button>
          <el-button v-if="deleteIsNeed" @click="handleDelete(scope.$index, scope.row)" type="text" size="small">删除</el-button>
          <slot name="next" :scope='scope'></slot>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue'

export default defineComponent({
  name: 'SimpleTable',
  props: {
    columns: {
      type: Array
    },
    selectionIsNeed: {
      type: Boolean,
      default: false
    },
    optionIsNeed: {
      type: Boolean,
      default: true
    },
    editIsNeed: {
      type: Boolean,
      default: true
    },
    deleteIsNeed: {
      type: Boolean,
      default: true
    },
    optionWidth: {
      type: String,
      default: '120'
    },
    tableData: {
      type: Array,
      default: () => []
    }
  },
  setup (props, {emit}) {
    const handleEdit = (index: number, row: any[]) => {
      emit('handleEdit', { index: index, row: row })
    }
    const handleDelete =  (index: number, row: any[]) => {
      emit('handleDelete', { index: index, row: row })
    }
    return {
      handleEdit,
      handleDelete
    }
  },
})
</script>

<style lang="less" scoped>

</style>

直接在App.vue引入

代码如下

<template>
  <div id="nav">
    <simple-table
      :columns="columns"
      :tableData="tableData"
      optionWidth="200"
      @handleEdit="handleEdit"
      @handleDelete="handleDelete"
    >
      <template #prev="scope">
        <el-button type="text" size="small" @click="handleFly(scope)"
          >查看</el-button
        >
      </template>
      <template #next="scope">
        <el-button type="text" size="small" @click="handleFly(scope)"
          >起飞</el-button
        >
      </template>
    </simple-table>
  </div>
</template>

<script lang="ts">
import SimpleTable from '@/components/simple-table.vue'
import { defineComponent, reactive } from 'vue'

export default defineComponent({
  components: {
    SimpleTable
  },
  setup() {
    const columns = reactive([
      { prop: "name", label: "名称", minWidth: 120 },
      { prop: "sex", label: "性别", minWidth: 120 },
      { prop: "date", label: "日期", minWidth: 120 },
    ]);
    const tableData = reactive([
      { name: "刘德华", sex: "男", date: "2021-09-01" },
    ]);
    const handleFly = (scope: any) => {
      console.log(scope);
    };
    const handleEdit = (params: any) => {
      console.log(params);
    };
    const handleDelete = (params: any) => {
      console.log(params.row.name);
    };
    return {
      tableData,
      columns,
      handleFly,
      handleEdit,
      handleDelete,
    };
  },
})
</script>


<style lang="less">
</style>

效果如图

image.png

题外

在外部调用components下的vue组件需要依次引入;

而个人想法是components文件夹内部的组件可以都是全局组件,可以直接调用;

因此可以在components文件夹下,新建index.ts

敲入以下内容

需要注意,组件必须返回一个name值,作为组件的调用名称

import type { App } from 'vue'

const components:__WebpackModuleApi.RequireContext = require.context(
  '@/components',
  true,
  /\.vue$/
)

const autoRegist = {
  install(app: App) {
    components.keys().forEach((path) => {
      const file = components(path).default
      const fileName = file.name
      app.component(fileName, file || components(path))
    })
  }
}

export default autoRegist

然后在main.ts文件导入使用

以插件形式,全局导入components文件夹内部的vue组件

import autoRegist from './components'

app.use(autoRegist)

文章推荐

从离职到入职外包|2022年中总结 - 掘金 (juejin.cn)

使用Vite搭建Vue3项目实践记录 - 掘金 (juejin.cn)