206 lines
5.0 KiB
Markdown
206 lines
5.0 KiB
Markdown
# ContactTable Component Fix
|
|
|
|
## Problem
|
|
The `<contact-table />` component was not showing in the Contacts.vue page.
|
|
|
|
## Root Cause
|
|
The **ContactTable.vue** component had an incomplete `<script>` section:
|
|
- Missing `export default` statement
|
|
- Not using `<script setup>` properly
|
|
- Components (SoftCheckbox, SoftButton, SoftAvatar) were not imported
|
|
- Images (img1-img6) were imported but not exposed to the template
|
|
- No proper component setup
|
|
|
|
## Solution
|
|
Converted both files to use Vue 3 `<script setup>` without TypeScript.
|
|
|
|
### Changes Made
|
|
|
|
#### 1. ContactTable.vue (`src/components/molecules/Tables/ContactTable.vue`)
|
|
|
|
**Before:**
|
|
```vue
|
|
<script>
|
|
import { DataTable } from "simple-datatables";
|
|
import img1 from "../../../assets/img/team-2.jpg";
|
|
// ... more imports but no export or setup
|
|
</script>
|
|
```
|
|
|
|
**After:**
|
|
```vue
|
|
<script setup>
|
|
import { onMounted } from 'vue'
|
|
import { DataTable } from 'simple-datatables'
|
|
import SoftCheckbox from '@/components/SoftCheckbox.vue'
|
|
import SoftButton from '@/components/SoftButton.vue'
|
|
import SoftAvatar from '@/components/SoftAvatar.vue'
|
|
import img1 from '@/assets/img/team-2.jpg'
|
|
import img2 from '@/assets/img/team-1.jpg'
|
|
import img3 from '@/assets/img/team-3.jpg'
|
|
import img4 from '@/assets/img/team-4.jpg'
|
|
import img5 from '@/assets/img/team-5.jpg'
|
|
import img6 from '@/assets/img/ivana-squares.jpg'
|
|
|
|
onMounted(() => {
|
|
const dataTableEl = document.getElementById('order-list')
|
|
if (dataTableEl) {
|
|
new DataTable(dataTableEl, {
|
|
searchable: false,
|
|
fixedHeight: true
|
|
})
|
|
}
|
|
})
|
|
</script>
|
|
```
|
|
|
|
**Key fixes:**
|
|
- ✅ Added `<script setup>` for proper Vue 3 Composition API
|
|
- ✅ Imported required components (SoftCheckbox, SoftButton, SoftAvatar)
|
|
- ✅ Used `@/` alias for cleaner imports
|
|
- ✅ Added `onMounted` to initialize DataTable after component mounts
|
|
- ✅ All imports are now properly exposed to the template
|
|
|
|
#### 2. Contacts.vue (`src/views/pages/CRM/Contacts.vue`)
|
|
|
|
**Before:**
|
|
```vue
|
|
<script setup lang="ts">
|
|
import SoftButton from "@/components/SoftButton.vue";
|
|
import ContactTable from "@/components/molecules/Tables/ContactTable.vue";
|
|
</script>
|
|
```
|
|
|
|
**After:**
|
|
```vue
|
|
<script setup>
|
|
import SoftButton from '@/components/SoftButton.vue'
|
|
import ContactTable from '@/components/molecules/Tables/ContactTable.vue'
|
|
</script>
|
|
```
|
|
|
|
**Key fixes:**
|
|
- ✅ Removed TypeScript (`lang="ts"`)
|
|
- ✅ Consistent quote style
|
|
- ✅ Properly imports ContactTable component
|
|
|
|
## How `<script setup>` Works
|
|
|
|
With `<script setup>`:
|
|
- No need for `export default`
|
|
- All top-level imports are automatically available in the template
|
|
- All top-level variables are automatically reactive
|
|
- Cleaner, more concise syntax
|
|
- Better TypeScript inference (when needed)
|
|
|
|
## Component Structure
|
|
|
|
```
|
|
Contacts.vue (parent)
|
|
└── ContactTable.vue (child)
|
|
├── SoftCheckbox.vue
|
|
├── SoftButton.vue
|
|
└── SoftAvatar.vue
|
|
```
|
|
|
|
## Features Added
|
|
|
|
1. **DataTable Integration**: The table is now initialized as a DataTable on mount
|
|
2. **Component Registration**: All child components properly imported and registered
|
|
3. **Image Assets**: All team images properly imported and accessible
|
|
4. **Clean Setup**: No TypeScript complexity, pure Vue 3 Composition API
|
|
|
|
## Testing
|
|
|
|
To verify the fix works:
|
|
1. Navigate to the Contacts page
|
|
2. The table should now render with all data
|
|
3. DataTable features (sorting, etc.) should work
|
|
4. All avatars and images should display
|
|
|
|
## Common Issues with `<script setup>`
|
|
|
|
### ❌ Wrong - Old Options API style:
|
|
```vue
|
|
<script>
|
|
export default {
|
|
components: { MyComponent },
|
|
data() { return {} }
|
|
}
|
|
</script>
|
|
```
|
|
|
|
### ✅ Correct - Script setup:
|
|
```vue
|
|
<script setup>
|
|
import MyComponent from './MyComponent.vue'
|
|
// MyComponent is automatically registered
|
|
// No need for components: {} registration
|
|
</script>
|
|
```
|
|
|
|
### ❌ Wrong - Missing imports:
|
|
```vue
|
|
<template>
|
|
<soft-button /> <!-- Won't work, not imported -->
|
|
</template>
|
|
<script setup>
|
|
// Missing import!
|
|
</script>
|
|
```
|
|
|
|
### ✅ Correct - With imports:
|
|
```vue
|
|
<template>
|
|
<soft-button /> <!-- Works! -->
|
|
</template>
|
|
<script setup>
|
|
import SoftButton from '@/components/SoftButton.vue'
|
|
</script>
|
|
```
|
|
|
|
## Benefits of This Approach
|
|
|
|
1. **Simpler**: No TypeScript complexity
|
|
2. **Cleaner**: Less boilerplate code
|
|
3. **Standard**: Follows Vue 3 best practices
|
|
4. **Maintainable**: Easy to understand and modify
|
|
5. **Performant**: `<script setup>` has better runtime performance
|
|
|
|
## Next Steps
|
|
|
|
If you want to add more features:
|
|
|
|
### Add Search to the table:
|
|
```vue
|
|
<script setup>
|
|
import { ref } from 'vue'
|
|
|
|
const searchQuery = ref('')
|
|
|
|
onMounted(() => {
|
|
new DataTable(dataTableEl, {
|
|
searchable: true, // Enable search
|
|
fixedHeight: true
|
|
})
|
|
})
|
|
</script>
|
|
```
|
|
|
|
### Make the data dynamic:
|
|
```vue
|
|
<script setup>
|
|
import { ref, onMounted } from 'vue'
|
|
import axios from 'axios'
|
|
|
|
const contacts = ref([])
|
|
|
|
onMounted(async () => {
|
|
const response = await axios.get('/api/contacts')
|
|
contacts.value = response.data
|
|
})
|
|
</script>
|
|
```
|
|
|
|
Then loop through contacts in the template with `v-for`.
|