I was just wondering if this is even possible, lets assume I have this code here:
<div v-for="tile in container" v-bind:class="proper-class">
<tile :tile='tile' #update="update-class"></tile>
</div>
I want to change the css class of the parent div when a variable inside of the component changes.
I know we should use $emit but we have a v-for in here, so we're creating multiple components, the $emit callback will update proper-class BUT this will update the css class of ALL the parents and not just the parent of the component that issued the update event.
What could be a solution to this?
Thanks in advance.
You can use the sync modifier to create a two way binding between the parent and child. It's nothing more than syntactic sugar for the child component emitting an event back to the parent with the desired payload.
this.$emit('update:propName', payload)
Vue sync modifier
Related
According to Vue.js docs (Components: One-Way data Flow) I assumed that I'm not able to update parent's variable from child component.
How is it possible, that when I bind a variable to child component, it is updated without emitting any event?
Here is Vue SFC playground example.
How can I use a copy of variable in child component without propagating changes to parent?
Edit: I'm curious why the property userAccount in AccountPage.vue gets updated.
There's no v-model, no events submitted, yet it still gets updated.
Edit:
In AccountForm.Vue an reactive and mutable ref object is created when writing
const userAccount = ref ({..})
Changing the reactive object will affect the parent. If you remove the ref() you'll see that the parent isn't updated.
https://v3.vuejs.org/api/refs-api.html#ref
Old answer:
When you use v-model you create a two-way data binding. V-model is a shorthand for v-bind and input, that is you bind data to child via v-bind and receive data via input event that is emitted from child.
So,
<input v-model="searchText">
is the same as writing
<input
v-bind:value="searchText"
v-on:input="searchText = $event.target.value"
>
https://v2.vuejs.org/v2/guide/components.html#Using-v-model-on-Components
The example demonstrates the usage of v-model and as stated in the docs
Custom events can also be used to create custom inputs that work with
v-model. Remember that:
<input v-model="searchText">
does the same thing as:
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
meaning it does fire an event
I have this component which has a v-model directive:
<my-component v-model="someData.someProp"></my-component>
Now, I'd like to be able to watch this piece of data inside the component and make changes based on this model changing via outside influences. So here's what I tried and it's not working:
watch : {
value (newVal, oldVal) {
// ...
}
}
It seems like it should work, or something comparable should be out there, but I just can't find it right now.
EDIT:
The most common answers I found and provided center on using the watcher to watch the data as if it's inside the parent component - but I'd like to watch it inside the child component without concern of what's going on in the parent.
I'm able to work around this by not using v-model and using simple named properties such as :my-data="someData.someProp" at which point I can successfully watch a myData variable inside the child component. I can also use #input to set the data back in the parent component if it's changed from within. But v-model is shorter and if there's a way to use that instead of a workaround that would be preferable.
From what I understand you are trying to pass a prop to your child component from your parent one and watch it in your child.
Assuming you have something like this in your parent:
<div>
<my-component v-model="someData.someProp"></my-component>
</div>
I understand you are getting undefined for that prop when you watch it, which is normal because you should pass it like this:
<my-component :myValue="someData.someProp"></my-component>
Then you should have access to the prop trought this.myValue.
If someData.someProp changes on the parent component it will automatically reflect on the child one.
Again this is what I could understand from your explanation and the amount of code you provided.
i'm using vue.js and vuetify.
elements made by parent element exist in my code.
i want to change parent element's class dynamically depending on it's child class, like jQuery has() method.
is vue.js has any way to do this?
jQuery has()
You can access a state if a child property of a child on different ways. (I assume the child class is set based on a certain state).
You could use vuex that keep a state over several components. You could emit a state back to you parent component. Or you could use the ref to access the child components properties.
<component ref="childcomponent"></markdown>
process: function(){
// items is defined object inside data() of the child component
var hasClass= this.$refs.childcomponent.item
}
I am currently working on a project that has a component structure like follows
Parent component that contains items
This component has a v-for over this.items.
That v-for has a
ChildComponent contains a form that modifies properties of this.item via v-model for each property.
I was expecting, since VueJS does not support 2 way databinding by default, that ParentComponent would not be aware about changes that I make in ChildComponent.
However, since my ChildComponent is a modal dialog, I can see the changes that I make in ChildComponent are reflected in ParentComponent.
As much as I like what I see, I don't understand it...
Could someone shed a light on this for me?
I have Vue component which receives json data from props, after this render child components using v-for and pass this data as prop. Everything works fine until i try to remove one item from this list, when i remove it, it removes element incorrectly. In vue devtools i see that parent receives data correctly but not renders it properly. can anyone help me?
here is my code: https://gist.github.com/giokaxo/3d291b9b7b8ef97f81dc83799c430302
Use "key" attribute when rendering elements using v-for, for example:
<p v-for="(product, index) in order.products" :key="i">..</p>
The relevant documentation is here:
You can directly use v-for on a custom component, like any normal
element:
<my-component v-for="item in items" :key="item.id"></my-component>
In 2.2.0+, when using v-for with a component, a key is now required.
However, this won’t automatically
pass any data to the component, because components have isolated
scopes of their own. In order to pass the iterated data into the
component, we should also use props:
<my-component
v-for="(item, index) in items"
v-bind:item="item"
v-bind:index="index"
v-bind:key="item.id">
</my-component>
The reason for not automatically injecting item into the component is because that makes the component
tightly coupled to how v-for works. Being explicit about where its
data comes from makes the component reusable in other situations.
And here:
When Vue is updating a list of elements rendered with v-for, it by
default uses an “in-place patch” strategy. If the order of the data
items has changed, instead of moving the DOM elements to match the
order of the items, Vue will simply patch each element in-place and
make sure it reflects what should be rendered at that particular
index.
...
To give Vue a hint so that it can track each node’s identity, and thus
reuse and reorder existing elements, you need to provide a unique key
attribute for each item. An ideal value for key would be the unique id
of each item.