Vue: Use Array/Object in props as default value

Created on 10 Jul 2015  路  18Comments  路  Source: vuejs/vue

Whether I can use Array/Object as default value in props setting?

{
    props: {
        arr: {
            type: Array,
            default: []
        }
    }
}

If i may, that will be a bug. Because every instance will share the same thing when I not passing target property to this component. Try this fiddle.

intend to implement

Most helpful comment

You can return the default value for a prop inside the data function as well:

data: function () {
  return {
    arr: []
  }
}

A warning seems necessary in the case you described. A solution would be:

props: {
  arr: {
    type: Array,
    default: function () { return [] }
  }
}

A little verbose, but better with ES6:

props: {
  arr: {
    type: Array,
    default: () => []
  }
}

All 18 comments

You can return the default value for a prop inside the data function as well:

data: function () {
  return {
    arr: []
  }
}

A warning seems necessary in the case you described. A solution would be:

props: {
  arr: {
    type: Array,
    default: function () { return [] }
  }
}

A little verbose, but better with ES6:

props: {
  arr: {
    type: Array,
    default: () => []
  }
}
props: {
  arr: {
    type: Array,
    default: function () { return [] }
  }
}

That might not be a good idea. Because sometime I really need a function as my default value like:

props: {
  clickHandler: {
    type: Function,
    default: function () { alert("A bit confusing") }
  }
}

So format will might be confusing...

Unless we can use function as factory except type===Function

That's quite obvious - you don't need to make a copy for functions.

Great, thanks for your advise!

I know HOW, but WHY? Why vue.js must use factory function for instance default props?

@jituanlin I assume it's because while primitives can always be copied safely, it's quite possible that a shallow copy of Object/Array would simply not work. It's somewhat better to force an explicit factory f-n than to expect that the programmer would remember about this bit every time lest he bugs his code to hell with it...

@FyiurAmron Between freedom and risk, I choose freedom.

@jituanlin You get both in this case.

In general case I'd agree with you; still, notice that frameworks are used to reduce cognitive load and streamline functionalities. In this case (Array/Object props) it's similar to why data is a function in Vue: we have an explicit factory method that can be easily extended (or even replaced with a factory/singleton function completely external to a component or a regular utility function if you wish!), with 0 of the risk of having invalid forced copies of objects etc.

Also, in this case, there's very little (if any) freedom gained by forcing the framework to use an under-the-hood factory (cloning/copying) function, instead of simply allowing the programmer to do it himself explicitly. I'd even say that allowing you to provide a factory instead of just forcing you to provide a reference to an existing object actually increases your freedom, while at the same time reducing the risk here. In simplest case, it's 4 additional characters in ES6, so I think the cost is managable here chuckles.

If you ended up here looking for how to do it with an object, it looks like this _(take note of the brackets)_:

props: {
  yourProp: {
    type: Object,
    default: () => ({
      param: value,
      param2: value,
    }),
  },
},

@yyx990803 Using the ES6 solution you proposed, when reusing the component I end up with the prop to be undefined. Is this a coincidence?
The scaffold of the project is realized through vue-cli ver. 3

@endoplasmic thank you, it works perfectly

When dealing with something like options,

props: {
  options: {
    type: Object,
    default: () => ({
      param: value,
      param2: value,
    }),
  },
}

With such code, you must props options params1, params2 from the parent component.

Since this.options is undefined within default: () => {} , I can not write code

default: () => ({ ...this.options, {
  param: value,
  param2: value
}})

Is it only possible to use the life cycle such as created to merge the default value and props value?


update

We created a default option using data() {} and thought that the method of merge using computed is the best, so we dealt with that way.

data() {
  return {
    defaultOptions: {
      param: "value",
      param2: "value"
    }
  }
},
computed: {
  someOptions() {
    return { ...this.defaultOptions, ...this.options }
  }
}

You can return the default value for a prop inside the data function as well:

data: function () {
  return {
    arr: []
  }
}

A warning seems necessary in the case you described. A solution would be:

props: {
  arr: {
    type: Array,
    default: function () { return [] }
  }
}

A little verbose, but better with ES6:

props: {
  arr: {
    type: Array,
    default: () => []
  }
}

this is good method,what is the original reason that the bug happens,please!

ES6 syntax for objects is () => ({}), as () => {} treats the curly brackets as a block statement that returns undefined.

props: {
  arr: {
    type: Array,
    default: () => ({})
  }
}

If you ended up here looking for how to do it with an object, it looks like this _(take note of the brackets)_:

props: {
  yourProp: {
    type: Object,
    default: () => ({
      param: value,
      param2: value,
    }),
  },
},

@endoplasmic perfect

Please, can you explain me this error => SyntaxError: invalid assignment left-hand side.

She is on this line (in props : { ... })
labels: { type: Array, function () { return [ "label1" = "Pr茅nom", "label2" = "Nom", "label3" = "Email" ] } },

The error is exactly at the beginning of the table.

Is there a way to access patient directly inside getDefaultState function?

/** default data state */
const getDefaultState = patient => ({
  patientData: { ...patient }
})

export default {
  props: {
    patient: {
      type: Object,
      default: () => ({
        patientId: null
      })
    }
  },
  data() {
    return getDefaultState(this.patient)
  },
Was this page helpful?
0 / 5 - 0 ratings