Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Array/Object in props as default value #1032

Closed
butsalt opened this issue Jul 10, 2015 · 18 comments
Closed

Use Array/Object in props as default value #1032

butsalt opened this issue Jul 10, 2015 · 18 comments

Comments

@butsalt
Copy link

butsalt commented Jul 10, 2015

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.

@yyx990803
Copy link
Member

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: () => []
  }
}

@butsalt
Copy link
Author

butsalt commented Jul 10, 2015

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...

@butsalt
Copy link
Author

butsalt commented Jul 10, 2015

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

@yyx990803
Copy link
Member

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

@butsalt
Copy link
Author

butsalt commented Jul 10, 2015

Great, thanks for your advise!

@jituanlin
Copy link

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

@FyiurAmron
Copy link

FyiurAmron commented Oct 23, 2017

@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...

@jituanlin
Copy link

@FyiurAmron Between freedom and risk, I choose freedom.

@FyiurAmron
Copy link

FyiurAmron commented Oct 24, 2017

@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.

@endoplasmic
Copy link

endoplasmic commented Feb 28, 2018

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,
    }),
  },
},

@andreatulimiero
Copy link

@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

@EdwinBetanc0urt
Copy link

@endoplasmic thank you, it works perfectly

@konojunya
Copy link

konojunya commented Dec 11, 2018

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 }
  }
}

@tianguangrong
Copy link

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!

@javiertury
Copy link

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

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

tsackit pushed a commit to tsackit/v-suggestions that referenced this issue Apr 11, 2019
@bhavinjr
Copy link

bhavinjr commented Jan 9, 2020

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

@thomasboidun
Copy link

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.

@BartusZak
Copy link

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)
  },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests