How to use v-bind without showing all the properties as HTML attributes? - vuejs2

The standard way of passing properties to a component is to use the v-bind directive:
<Child :prop1="myObj.prop1" :prop2="myObj.prop2" :prop3="myObj.prop3"/>
But Vue makes it possible to simply pass the entire object:
<Child v-bind="myObj"/>
However, one downside I've come across is that the HTML element shows all these properties:
<div class="child" prop1="[Object object]" prop2="2" prop3="[1,2,3]">...<div/>
Is there a way to prevent this behaviour?

There is a way to avoid this without passing props explicitly:
https://v2.vuejs.org/v2/guide/components-props.html#Non-Prop-Attributes
add inheritAttrs: false to the component you are passing props to

After reading documentation on component props look's like vueJs does not provided such provision to avoid this. https://v2.vuejs.org/v2/guide/components-props.html

Related

Vue component communication between header component and components in the router-view

Im facing a problem for my VUE app, Im using the vue Router to navigate to my component
In my Header component I use router-link to navigate to a Home component
The problem is :
In my Header component I would like a checkBox (a boolean variable) that change the content of my Home component (rendered in the router-view) like a v-if that would check the boolean variable in the Header
Here is my App.vue template I was trying to solve the problem through emits but Im Kinda stuck for passing data inside a component (inside the router-view)
<template>
<div class="content">
<HeaderComponent #eventCheckBox="handleCheckBox" />
<router-view />
<FooterComponent />
</div>
Do you guys have already faced this issue, is there a way to do it the classic way or should I try plugins like Portal or Teleport ?
Portal and Teleport are the same, just a different name (teleport in Vue3, being the official name).
As of the rest of the question, this explains it very well: https://stackoverflow.com/a/49702934/8816585
Mainly, you need to see if you need to use a store like Pinia (recommended one) and Vuex. Most of the time, you could use a parent/child relationship. Here is another article explaining when you would need something like that: https://markus.oberlehner.net/blog/should-i-store-this-data-in-vuex/#alternatives-to-storing-data-in-vuex
In Vue3, you could even not use a store and rely solely on the singleton pattern + composables (again, a lot of articles are available for that one).
TLDR: use your Vue devtools and inspect the state flowing.
If you need more, reach for more powerful tools.

Vue: watching a v-model's 'value' in a component

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.

Is it possible in Vue to programatically wrap an element or component with a transition using a custom directive or render function?

To make code more simple/clean for me and my designers, I'd like to be able to do something like below. Is it possible - using a custom directive or render function to implement this with a simple attribute?
This would really help separating animation from structure and functionality, which I think could be helpful in many cases. I figure render functions can easily wrap an element with other HTML elements, but can they wrap elements (or components) with custom Vue transitions?
This:
<template>
<my-component custom-transition></mycomponent>
</template>
Becomes this:
<template>
<custom-transition>
<my-component></mycomponent>
</custom-transition>
</template>
Or maybe bring it up on Github?
Thanks!
A Vue forum member provided a great solution for me in this thread using dynamic components. Happy!

How to get the parent template component in Vue

I know in vue, I can use this.$parent to get the upper component in the vdom tree. But I'm expecting something different: to get the component that rendered the current component.
For instance, I have a component (named comp-container) with template:
<template>
<comp-a>
<comp-b></comp-b>
</comp-a>
</template>
And in comp-b the $parent would be an instance of comp-a not comp-container which I'm expecting.
My current aproach is traversing up with the $parent attribute until I find comp-b exists in $options.components. This method is working for now but seems quite ugly and breaks if comp-b is a globaly registered component. Is there an official way to do this?
Passing the parent template component via props as <comp-b :container="this"></comp-b> may do the job, but it's too verbose to be liked.
I'm not sure about the exact use case, but basically if there are slots involved (which I almost assume, because otherwise $parent will work fine), you can find the rendering component at:
this.$slots.default[0].context;
Basically, the context property of a slot is the rendering context (rendering component - i.e. the component who's template the component was rendered in).
Only tested with Vue 2

Vue component not updating after parent state change

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.