5.0 KiB
5.0 KiB
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 defaultstatement - 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:
<script>
import { DataTable } from "simple-datatables";
import img1 from "../../../assets/img/team-2.jpg";
// ... more imports but no export or setup
</script>
After:
<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
onMountedto initialize DataTable after component mounts - ✅ All imports are now properly exposed to the template
2. Contacts.vue (src/views/pages/CRM/Contacts.vue)
Before:
<script setup lang="ts">
import SoftButton from "@/components/SoftButton.vue";
import ContactTable from "@/components/molecules/Tables/ContactTable.vue";
</script>
After:
<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
- DataTable Integration: The table is now initialized as a DataTable on mount
- Component Registration: All child components properly imported and registered
- Image Assets: All team images properly imported and accessible
- Clean Setup: No TypeScript complexity, pure Vue 3 Composition API
Testing
To verify the fix works:
- Navigate to the Contacts page
- The table should now render with all data
- DataTable features (sorting, etc.) should work
- All avatars and images should display
Common Issues with <script setup>
❌ Wrong - Old Options API style:
<script>
export default {
components: { MyComponent },
data() { return {} }
}
</script>
✅ Correct - Script setup:
<script setup>
import MyComponent from './MyComponent.vue'
// MyComponent is automatically registered
// No need for components: {} registration
</script>
❌ Wrong - Missing imports:
<template>
<soft-button /> <!-- Won't work, not imported -->
</template>
<script setup>
// Missing import!
</script>
✅ Correct - With imports:
<template>
<soft-button /> <!-- Works! -->
</template>
<script setup>
import SoftButton from '@/components/SoftButton.vue'
</script>
Benefits of This Approach
- Simpler: No TypeScript complexity
- Cleaner: Less boilerplate code
- Standard: Follows Vue 3 best practices
- Maintainable: Easy to understand and modify
- Performant:
<script setup>has better runtime performance
Next Steps
If you want to add more features:
Add Search to the table:
<script setup>
import { ref } from 'vue'
const searchQuery = ref('')
onMounted(() => {
new DataTable(dataTableEl, {
searchable: true, // Enable search
fixedHeight: true
})
})
</script>
Make the data dynamic:
<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.