基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3.7 KiB

Component Guidelines

How components are built in this project.


Overview

This project uses Vue 3 with Element Plus components. Components follow a consistent pattern for props, slots, and composition.


Element Plus el-table-v2 Usage

IMPORTANT: el-table-v2 has a different API than el-table. Key differences:

Auto-resizing with ElAutoResizer

el-table-v2 does NOT have an autosize prop. Use ElAutoResizer wrapper instead:

<el-auto-resizer>
  <template #default="{ height, width }">
    <el-table-v2
      :columns="columns"
      :data="data"
      :width="width"
      :height="height"
      :row-height="50"
      :header-height="50"
    />
  </template>
</el-auto-resizer>

Note: Parent container of ElAutoResizer must have a fixed height (e.g., height: 100% or explicit pixel value).

el-table-v2 Required Props

el-table-v2 requires both width and height as mandatory props - they cannot be omitted.

Slot-to-CellRenderer Conversion

el-table-v2 uses cellRenderer functions instead of Vue slots. To render parent slots:

import { useSlots, renderSlot } from 'vue';

const slots = useSlots();

// In column definition:
col.cellRenderer = ({ cellData, rowData }) => {
  if (slots[slotName]) {
    return renderSlot(slots, slotName, { row: rowData });
  }
  return h('span', {}, formattedValue);
};

Column Flex Distribution

For auto-distributed column widths (no explicit width), use flexGrow: 1:

const col = {
  key: 'code',
  title: 'Name',
  dataKey: 'code',
  width: 120,        // minimum width required
  flexGrow: 1,       // expands to fill available space
  align: 'center',
};

Import Path Conventions

Correct Import Patterns

// ✅ CORRECT: Use relative paths for internal modules
import { clearAndAssign, deepCopy } from "../util/objectUtil";
import { ElAutoResizer, ElTableV2 } from "element-plus";

// ❌ WRONG: noob-mengyxu/utils does not exist
import { clearAndAssign } from "noob-mengyxu/utils";

Rule: For utility functions within the project, always use relative paths (../util/, ./). The noob-mengyxu namespace is only for exporting packages.


Component Structure

<template>
  <div class="component-name">
    <!-- Markup -->
  </div>
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue';

// Props definition
interface Props {
  data?: any;
  columns?: TableColumn[];
}

const prop = withDefaults(defineProps<Props>(), {
  data: () => [],
  columns: () => [],
});

const emit = defineEmits(['query', 'change']);
</script>

<style lang="scss" scoped>
/* Scoped styles */
</style>

Props Conventions

  1. Use withDefaults(defineProps<Props>()) for optional props with defaults
  2. Always provide default values for array/object props
  3. Use TypeScript interfaces for complex prop types

Common Mistakes

1. Timestamp Formatting Assumptions

The formatStamp function expects Unix timestamps in seconds (not milliseconds):

const formatStamp = (value: any) => {
  const date = new Date(value * 1000); // expects seconds
  // ...
};

When generating test data, use Math.floor(Date.now() / 1000) or Date.now() / 1000.

2. Element Plus Version Mismatch

Element Plus el-table (v1) and el-table-v2 (virtualized) have completely different APIs:

  • v1: uses prop for columns, slots for cell rendering
  • v2: uses columns prop, cellRenderer functions, separate ElAutoResizer

3. Forgetting Required Props

When using new Element Plus components, verify required props - they will cause runtime errors if omitted.


Accessibility

  • Use semantic HTML elements
  • Ensure keyboard navigation works
  • Add ARIA labels where necessary