Fix: data() Should Return an Object in Vue.js

Error message:
data() should return an object.
Components 2025-01-25

What Causes This Warning?

This warning occurs in the Options API when the data option is not a function that returns an object, or when the function returns something other than a plain object (like undefined, null, or an array).

The Problem

// ❌ data as object (not a function)
export default {
  data: {
    count: 0
  }
}

// ❌ data function returning nothing
export default {
  data() {
    const count = 0
    // No return statement!
  }
}

// ❌ data function returning array
export default {
  data() {
    return [1, 2, 3]
  }
}

// ❌ data function returning null
export default {
  data() {
    return null
  }
}

The Fix

Return a Plain Object

// ✅ data as function returning object
export default {
  data() {
    return {
      count: 0,
      message: 'Hello',
      items: []
    }
  }
}

With Composition API

<script setup>
import { ref, reactive } from 'vue'

// ✅ Use ref for primitives
const count = ref(0)
const message = ref('Hello')

// ✅ Use reactive for objects
const state = reactive({
  items: [],
  loading: false
})
</script>

Common Scenarios

Forgetting Return Statement

// ❌ Missing return
export default {
  data() {
    const state = {
      count: 0
    }
    // Forgot to return!
  }
}

// ✅ With return
export default {
  data() {
    return {
      count: 0
    }
  }
}

Conditional Return

// ❌ Conditional might return undefined
export default {
  data() {
    if (someCondition) {
      return { count: 0 }
    }
    // Returns undefined if condition is false
  }
}

// ✅ Always return an object
export default {
  data() {
    if (someCondition) {
      return { count: 0, extra: true }
    }
    return { count: 0 }
  }
}

Arrow Function with Object Literal

// ❌ Arrow function needs parentheses for object literal
export default {
  data: () => { count: 0 } // This is a block, not an object!
}

// ✅ Wrap object in parentheses
export default {
  data: () => ({ count: 0 })
}

// ✅ Or use regular function
export default {
  data() {
    return { count: 0 }
  }
}

Async Data Initialization

// ❌ data cannot be async
export default {
  async data() {
    const result = await fetchData()
    return { result }
  }
}

// ✅ Initialize empty, fetch in lifecycle
export default {
  data() {
    return {
      result: null,
      loading: true
    }
  },
  async created() {
    this.result = await fetchData()
    this.loading = false
  }
}

Class Instance in Data

// ❌ Class instances can cause issues
export default {
  data() {
    return new MyDataClass() // Not a plain object
  }
}

// ✅ Return plain object with class instance as property
export default {
  data() {
    return {
      myClass: new MyDataClass()
    }
  }
}

Why data Must Be a Function

In Vue, data must be a function so each component instance gets its own reactive data object:

// ❌ Shared data object (causes bugs)
const sharedData = { count: 0 }

export default {
  data: sharedData // All instances share same object!
}

// ✅ Factory function (each instance gets fresh object)
export default {
  data() {
    return { count: 0 } // New object for each instance
  }
}

Migrating to Composition API

// Options API
export default {
  data() {
    return {
      count: 0,
      user: { name: '' },
      items: []
    }
  }
}

// Composition API equivalent
import { ref, reactive } from 'vue'

export default {
  setup() {
    const count = ref(0)
    const user = reactive({ name: '' })
    const items = ref([])

    return { count, user, items }
  }
}

// Script setup (cleanest)
<script setup>
import { ref, reactive } from 'vue'

const count = ref(0)
const user = reactive({ name: '' })
const items = ref([])
</script>

Quick Checklist

  • data must be a function, not an object
  • Function must return a plain object {}
  • Don’t forget the return statement
  • Wrap arrow function object literals in parentheses
  • Don’t return arrays, null, or undefined
  • Use lifecycle hooks for async initialization
  • Consider migrating to Composition API