Skip to content

Common Development Issues & Solutions

A comprehensive troubleshooting guide to help you quickly resolve common issues encountered during secondary development of the Vue admin template. This guide covers environment setup, component integration, styling conflicts, build processes, and deployment challenges.

Problem: Getting errors like “Unsupported Node.js version” or compatibility issues with dependencies.

Node.js Version Management
# Check current Node.js version
node --version
# Expected versions for this template:
# Node.js: >= 20.19.0
# Install/switch to correct Node.js version using nvm
nvm install 20
nvm use 20
# Or using volta
volta install node@20
# Verify installation
node --version # Should output v20.19.x or higher

Solutions:

  1. Use Node Version Manager (nvm):

    Terminal window
    # Install nvm (if not already installed)
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
    # Install and use Node.js 20+
    nvm install 20
    nvm use 20
    nvm alias default 20
  2. Use Volta (recommended):

    Terminal window
    # Install volta
    curl https://get.volta.sh | bash
    # Pin Node.js version for the project
    volta pin node@20
  3. Update package.json engines:

    {
    "engines": {
    "node": ">=20.19.0"
    }
    }

Problem: Table not displaying data or showing “No data available” despite having data.

Fixing Table Data Issues
// ❌ Common mistakes
const tableData = ref() // undefined
const tableData = ref({}) // object instead of array
const tableData = ref([{ id: 1, user_name: 'John' }]) // snake_case keys
// ✅ Correct data format
const tableData = ref<User[]>([
{ id: 1, name: 'John Doe', email: '[email protected]' },
{ id: 2, name: 'Jane Smith', email: '[email protected]' }
])
// ✅ Column definitions must match data keys
const columns: ColumnDef<User>[] = [
{ accessorKey: 'name', header: 'Name' }, // matches data.name
{ accessorKey: 'email', header: 'Email' }, // matches data.email
// ❌ { accessorKey: 'user_name', header: 'Name' } // key doesn't exist
]
// ✅ Handle async data properly
const { data: users, loading } = useAsyncData('users', () => fetchUsers())
const tableData = computed(() => users.value || [])

Debugging Steps:

// Add debugging to understand data structure
watch(() => tableData.value, (newData) => {
console.log('Table data:', newData)
console.log('Data type:', typeof newData)
console.log('Is array:', Array.isArray(newData))
console.log('Length:', newData?.length)
if (newData?.[0]) {
console.log('First item keys:', Object.keys(newData[0]))
}
}, { immediate: true })

Problem: Form validation not working or showing incorrect error messages.

Fixing Zod Schema Issues
// ❌ Common Zod schema mistakes
const schema = z.object({
email: z.string(), // ❌ no email validation
age: z.string().min(18), // ❌ string instead of number
role: z.string().oneOf(['admin', 'user']), // ❌ should use enum
confirmPassword: z.string() // ❌ no password confirmation logic
})
// ✅ Correct Zod schema with proper validation
const schema = z.object({
email: z.string()
.min(1, 'Email is required')
.email('Please enter a valid email address'),
age: z.preprocess(
(val) => val === '' ? undefined : Number(val), // Handle empty strings
z.number()
.min(18, 'Must be at least 18 years old')
.max(120, 'Must be less than 120 years old')
),
role: z.enum(['admin', 'user', 'moderator'], {
errorMap: () => ({ message: 'Please select a valid role' })
}),
password: z.string()
.min(8, 'Password must be at least 8 characters')
.regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, 'Password must contain uppercase, lowercase, and number'),
confirmPassword: z.string()
}).refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match",
path: ["confirmPassword"] // Show error on confirmPassword field
})
// ✅ Optional fields with defaults
const optionalSchema = z.object({
name: z.string().min(1),
bio: z.string().max(500).optional().default(''),
newsletter: z.boolean().default(false),
preferences: z.object({
theme: z.enum(['light', 'dark']).default('light'),
language: z.string().default('en')
}).optional().default({})
})

Problem: Custom styles being overridden by Tailwind or component styles not applying.

Resolving Tailwind Conflicts
<!-- ❌ Common Tailwind conflicts -->
<HiTable class="bg-blue-500" /> <!-- May be overridden by component styles -->
<div class="p-4 p-6"> <!-- Last class wins, p-6 will override p-4 -->
<!-- ✅ Solutions for Tailwind conflicts -->
<!-- Method 1: Use important modifier -->
<HiTable class="!bg-blue-500" /> <!-- Forces the style -->
<!-- Method 2: Use CSS-in-JS for complex styling -->
<HiTable :style="{ backgroundColor: 'rgb(59 130 246)' }" />
<!-- Method 3: Use component-specific classes -->
<HiTable class="custom-table-blue" />
<!-- Method 4: Use CSS custom properties -->
<HiTable
class="custom-table"
:style="{ '--table-bg': '#3b82f6' }"
/>

CSS Solutions:

styles/components.css
/* Method 1: Higher specificity */
.custom-table-blue.hi-table {
@apply bg-blue-500;
}
/* Method 2: CSS custom properties */
.custom-table {
background-color: var(--table-bg, theme('colors.white'));
}
/* Method 3: Component-specific overrides */
.hi-table.custom-styling {
@apply bg-white border border-gray-200 rounded-lg shadow-sm;
}
.hi-table.custom-styling th {
@apply bg-gray-50 font-semibold text-gray-900;
}
.hi-table.custom-styling td {
@apply border-t border-gray-100;
}
/* Method 4: Dark mode considerations */
.dark .hi-table.custom-styling {
@apply bg-gray-800 border-gray-700;
}
.dark .hi-table.custom-styling th {
@apply bg-gray-700 text-gray-100;
}
.dark .hi-table.custom-styling td {
@apply border-gray-600;
}

Problem: Build failing due to TypeScript errors or type checking issues.

Fixing TypeScript Errors
// ❌ Common TypeScript errors and fixes
// Error: Property 'data' does not exist on type 'never'
const tableData = ref([]) // ❌ TypeScript can't infer type
const tableData = ref<User[]>([]) // ✅ Explicit type annotation
// Error: Type 'string' is not assignable to type 'never'
const formData = reactive({}) // ❌ Empty object has no properties
const formData = reactive<UserFormData>({ // ✅ Type the reactive object
name: '',
email: '',
role: 'user'
})
// Error: Cannot find module or its corresponding type declarations
import { SomeComponent } from './components' // ❌ Missing file extension or index
import { SomeComponent } from './components/SomeComponent.vue' // ✅ Explicit path
import { SomeComponent } from './components/index' // ✅ Using index file
// Error: 'ref' is declared but its value is never read
const tableRef = ref() // ❌ Unused ref
const tableRef = ref<InstanceType<typeof HiTable>>() // ✅ Typed and used
// ✅ Type-safe component refs
const formRef = ref<{
validate: () => Promise<boolean>
reset: () => void
setValues: (values: any) => void
}>()
// ✅ Type-safe event handlers
const handleSubmit = (data: UserFormData) => { // ✅ Typed parameter
console.log(data.name) // TypeScript knows about 'name' property
}
// ✅ Type-safe API responses
interface ApiResponse<T> {
data: T
message: string
success: boolean
}
const fetchUsers = async (): Promise<ApiResponse<User[]>> => {
const response = await fetch('/api/users')
return response.json()
}

Common TypeScript Configuration Issues:

// tsconfig.json - recommended configuration
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"strict": true,
"noUnusedLocals": false, // Set to false during development
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
}

When encountering issues, run through this checklist:

If you’re still experiencing issues after trying these solutions:

  1. Check the GitHub Issues: Search existing issues in the template repository
  2. Browser DevTools: Use Console, Network, and Vue DevTools for debugging
  3. Community Support: Join the Vue.js Discord or relevant community forums
  4. Documentation: Refer to official documentation for Vue 3, Vite, and related libraries