could you please tell me how to use watch function in vue js .I tried to used but I got this error.
vue.js:485 [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: "m"
found in
---> <AddTodo>
<Root>
https://plnkr.co/edit/hVQKk3Wl9DF3aNx0hs88?p=preview
I created different components and watch properties in the main component
var AddTODO = Vue.extend({
template: '#add-todo',
props: ['m'],
data: function () {
return {
message: ''
}
},
methods: {
addTodo: function () {
console.log(this.message)
console.log(this.m);
this.m =this.message;
},
},
});
When I try to add item I am getting this error.
Step to reproduce this bug
Type anything on input field and click on Add button
this.m =this.message;
this line is the issue,
It's recommended that you don't modify prop directly...
instead create a data property and then modify it.
It shows warning because you're modifying the prop item, prop value will be overwritten whenever the parent component re-renders.
The component's props are automatically updated in the component as soon as you change their value outside of it.
For this reason, trying to change the value of a property from inside your component is a bad idea: you should use the props as read-only.
If you want to use a prop as the initial value of some of your component's data you can simply declare it this way:
data: function () {
return {
changeable: this.receivedProp;
}
},
That being said, if you are trying to change the value of a prop from inside a component to be able to use your reassigned prop outside of it, you are doing it the wrong way. The way you should handle this is by using Vue's custom events.
Remember, as Vue's documentation states:
In Vue, the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events.
Related
I have a Prop in my component that is a User object, I then have this function:
onChange: function(event){
this.$v.$touch();
if (!this.$v.$invalid) {
this.$axios.put('update',{
code:this.user.code,
col:event.target.name,
val:event.target.value
}).then(response => {
this.user[event.target.name]=event.target.value
});
}
}
I can see in the Vue console debugger that the correct attribute has been updated, this attribute exists when the component is created but the template where I reference it does not refresh:
<p>Hi {{user.nickname}}, you can edit your details here:</p>
This is all within the same component so I'm not navigating to child or parent. I'm sure props have been reactive elsewhere in my code?
Ok, it seems this is intended behaviour. According to the documentation
https://v2.vuejs.org/v2/guide/components-props.html in the scenario that I have it should be handled as:
The prop is used to pass in an initial value; the child component wants to use it as a local data property afterwards. In this case,
it’s best to define a local data property that uses the prop as its
initial value:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
Usually components should be reactive to Props, though i have had experiences where it was non-reactive so i added the prop to a watcher and put the functional call there.
props: ["myProp"],
watch:{
myProp(){
// ... your functions here
}
}
I am having an issue with watchers not being triggered upon data change in my component. The property in the data is reactive, as it has been set upon component creation and not later on.
Here is the piece of code, in which the issue is:
https://codesandbox.io/s/nlpvz0y6m
To explain in more detail, the status property gets its status from the parent, which intern gets it from a Vuex state object, it is being passed to the component successfully, as I am able to log it and change it.
However, when I setup a watcher, to execute a function upon a change in it's value, it simply doesn't trigger. Regardless how I make the change - whether with an internal method of the component or an event.
What I need is for the watcher to trigger upon change of the status property, but am not certain why it does not reflect it at all.
The structure is as it follows: BottomBar is the parent, a bool value is passed as property to Spin.vue as a prop and then the prop is assigned to a data property on the child component.
The bool value itself, comes from index.js, where the Vuex instance is.
In the console, it is showing the following two errors
[vuex] unknown getter: isSpinning
[vuex] unknown mutation type: spinIt
The issue seems to be how the store is set up. Try this.
export const store = new Vuex.Store({
state: {
controls: {
spin: false
}
},
getters: {
isSpinning: state => {
return state.controls.spin;
}
},
mutations: {
spinIt(state) {
return (state.controls.spin = !state.controls.spin);
}
}
});
You had your mutations and getters sat inside your state. I have moved them outside, and updated the references inside to make the code work as expected.
https://codesandbox.io/s/8xyxmvr8jj
I am new to VueJs and I am doubtful about passing the optional payload
Could anyone please tell me how to pass the value returned by a computed function in the child component to the parent component using the optional payload.
I want to implement a separate independent search component which returns the search results to all other components. The computed function looks like this:
get computedSports () {
if (!this.searchModel || this.searchModel.length === 0)
return this.sports
else
return this.fuseSearch.search(this.searchModel)
}
This is how I am trying to pass the value returned by computed function to its parent component in the child template:
#input="$bus.$emit('computed-sports', computedSports)"
In the parent component, this is how I am trying to access the value of the child's computed function:
v-on:computed-sports=""
I am not quite sure how to access the value here. Could anyone help me out in this?
Thanks!
The argument to a v-on should be a method or inline function that takes the payload as an argument. For example
v-on:computed-sports="handleComputedSports"
and your method might be defined
handleComputedSports(theValue) {
console.log("The value is", theValue);
}
There's an example in this section of the documentation. Your emit is fine. The fact that the value comes from a computed makes no difference to anything.
I know if you want to alter something within a component itself you use state, and when the emit is external then u use props to receive it. But today I stumped across this example
var Label = React.createClass({
handleClick: function(){
console.log("Click");
this.props.children = "Text After Click";
this.setState({liked: false});
},
render: function () {
console.log("Render");
return (
<p ref="p" onClick={this.handleClick}>{this.props.children}</p>
);
}
});
Used props instead of state to change the text a value of a button. I'm confused now. The link to the source is here http://myshareoftech.com/2013/12/unit-testing-react-dot-js-with-jasmine-and-karma.html
I don't know about the source but when i tried above code it throws this error:
Uncaught TypeError: Cannot assign to read only property 'children' of object #<Object>.
It should not work because the basic property of the props is, as per DOC:
Props are Read-Only, Whether you declare a component as a function or a class, it must never modify its own props. All React components must act like pure functions with respect to their props.
Check the fiddle for error: https://jsfiddle.net/pjnp6yza/
Reference: https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only
All props form a one-way-down binding between the child property and
the parent one: when the parent property updates, it will flow down to
the child, but not the other way around. This prevents child
components from accidentally mutating the parent’s state, which can
make your app’s data flow harder to reason about. In addition, every
time the parent component is updated, all props in the child component
will be refreshed with the latest value. - One-Way Data Flow
The Vue2 Component Docs suggests doing the following to use props as an initial value:
// via https://v2.vuejs.org/v2/guide/components.html#One-Way-Data-Flow
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
So in my code I mimicked those instructions here.
However data() in Note.vue isn't being updated even though the prop value is received according to vue-devtools.
Haven't had success setting the values with the mounted or created lifescyle methods.
When I use static data, this seems to work fine, how can I ensure the child component reacts to receiving props when it comes from a remote source?
When you are passing initialNote as prop for initial value, but I see initialNote is being populated asynchronously in getNote method, so it will not be present initially when the component will be mounted. It will be populated after some time by the time initialisation would have already happened.
In the example give in vue documentation, initialCounter is static value which will perfect as it will have same value from beginning.