Tinkering with Vue for the first time, I have a rather innocuous input like so:
<input type="number" name="quantity" v-model="quantity" />
This lives inside a component.
When quantity is set on the prop object, I get this error (when changing the value in the input):
Vue.component('my-product', {props: {quantity : {default: 1}}});
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "quantity"
But when quantity is set on the data object as demonstrated on the Vue tutorial documentation, I get this error:
Vue.component('my-product', {data: {quantity : 1}});
[Vue warn]: The "data" option should be a function that returns a per-instance value in component definitions.
I'm at a loss. This field has no bearing on the parent views (vues?) so perhaps I am simply misunderstanding how to set this up.
Oh it's right there in the error text...
Vue.component('my-product', {
data: function(){
return {quantity : 1}
}
});
Related
There is a code I take over from another developer. He used a Vuex property POLL to initialize some components. I wanted to use a different approach - get the object at upper level and pass it as a property downstream to the components. The object is fetched in async method from the backend. I thought that Vue reactivity will initialize real value later. But I get an error:
[Vue warn]: Property or method "poll" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <PollHeading> at src/components/molecules/PollHeading.vue
<CompletePoll> at src/components/organisms/CompletePoll.vue
<Home> at src/views/Home.vue
Home.vue
<Poll v-if="this.$store.getters.LATEST_POLL" :item="this.$store.getters.LATEST_POLL" />
...
created() {
this.$store.dispatch('GET_LATEST_POLL');
},
CompletePoll.vue
<PollHeading :item="item"/>
...
props: {
item: Object,
},
PollHeading.vue
props: {
item: Object,
},
Am I going the wrong direction and the original developer was right? Or is there a way how to fix my approach? He used to do:
PollHeading.vue (I renamed to CompletePoll.vue)
computed: {
poll() {
return {
poll: this.$store.getters.POLL,
};
},
Problem 1)
[Vue warn]: Property or method "poll" is not defined on the instance but referenced during render. means that you have this declared in template block of .vue file, but it's not declared in the script's data property or computed. I don't see that specific .vue file where you use poll variable.
Problem 2) When you use variables in tmeplate blocks, you shouldn't use this .
So instead of this: <Poll v-if="this.$store.getters.LATEST_POLL" :item="this.$store.getters.LATEST_POLL" />
Write: <Poll v-if="$store.getters.LATEST_POLL" :item="$store.getters.LATEST_POLL" />
Problem 3) https://github.com/literakl/mezinamiridici/blob/master/spa/src/components/molecules/PollHeading.vue on this file you use poll in template but you don't have that variable created anywhere. your prop's name is item and not poll. So change poll to item in template block everywhere in that file.
I've got a test that during it's setup process I pass some default props to the component. Then, in the test, I use setProps to pass more specific data into it. Issue is that both default and new data are nested within same props object named org and Vue obviously complains that the default is getting overwritten. Is there a way around this?
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "optimisticClearFilters"
Here's an example. When I do this from test, it seems to override all org keys.
wrapper.setProps( { org: { deptSize: [0, 5] }} );
For example if I have:
var posts = {
status: 6
rows: [{}, {}, {}]
details: "some details",
amount: 1
}
And I want to test component with changed status value without exception, I do:
post.status = status
wrapper.setProps({ post: { ...post} })
In my component I get some props from state like this:
computed: mapGetters({
id: 'downloadId',
pageLimit: 'pageLimit',
pageMaxSize: 'pageMaxSize',
cleaningInterval: 'cleaningInterval'
})
and I bind the property:
<input type="number" v-model.number="pageLimit" id="pageMaxSize" />
Save method:
methods: {
onSave () {
alert('Your data: ' + JSON.stringify(this.pageLimit))
}
}
When a value is entered into the input field and the save button is clicked, this.pageLimit remains the initial value
how do I get the updated value?
There is two issues with your code:
v-model should be used with data only and not with computed. a computed property value in Vue.js can not be changed unless the value or one of the values it depends on has changed.
You can not update the state directly. This is one of vuex rules. To update it you have to use a vuex mutation for that.
So the solution is:
Create a data property called tempPageLimit and bind it to the input using v-model.
In the store, Create a mutation that update the pageLimit with the value of the tempPageLimit and map it to your component using mapMutations.
Execute this mutation inside the onSave method.
look here if you want to read about vuex mutations.
I've a page where field names are of type array.
eg. mapping[map][email_address][type]
Now in Vue, I want to set the default value and I'm doing it as below
new Vue({
el: '#configure',
data: {
mapping: {
map: {
email_address: {
type: 'incoming_field'
}
}
}
}
})
But I get an error in console
[Vue warn]: Property or method "map" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
vue.js:569 [Vue warn]: Property or method "email_address" is not defined on the instance but referenced during render. Make sure to declare reactive data properties in the data option.
vue.js:569 [Vue warn]: Error in render function:
(found in <Root>)
What is the best way to handle such field names in Vuejs?
As par you code, you have to do:
mapping['map']['email_address']['type']
or
mapping.map.email_address.type
You should rethink your data to not have so many nested objects.
If you are setting a property directly within an object, it is good practice to use Vue.set to ensure you do not break reactivity. Doing this will save you hours of headaches trying to figure out where something broke.
Vue.set(mapping.map.email_address, 'type', value_to_set)
I have a parent component
<template><child></child></template> export { components: [ child] }
and child component
<template><!-- markup --></template> export { props ['id'] }
When I retrieve information from a resource after posting I want to be able to pass the received data from parent to the child property.
// parent function
then(response=>{// need to set child.id = response.data });
Now I tried setting the property value directly and got the warning
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value
And I can't use emit or broadcast because I'm using Vue 2.0, $broadcast is undefined and I can't $emit to children. What would be the best way to pass the data? This value only lasts for the parent and child and does not need to be preserved or persisted.