Vue v-if start hidden - vue.js

I have a v-if on a tag <span v-if="someValue"> which I want to start hidden and only become visible once the value in someValue is set to true. Unfortunately even if the value false from the start it still flashes up when loading the page (probably before Vue has time to remove the tag).
Is there a nice way to deal with this issue?

The initial "flashing" is not actually related to the v-if.
It is due to the fact that you first load the dom and then vue js will "manipulate" it. Vue is loaded after your html markup and therefore you will see everything until vue js is finally loaded and will hide elements according to your code.
To get rid of this you can place a v-cloak directive on one of your outer elements and add a css like
[v-cloak].class-of-my-outer-element {
display: none;
}
the v-cloak "attribute" will be removed by vue after it is initialized. that means nothing is shown until your code is ready.
Minor update / edit : Don't forget the v-cloak element needs to be inside if your #app or whereever you mount your vue application.

Related

How to unmount vuejs instance from DOM

Is there any way to unmount vuejs Instance from DOM?
I want to mount and unmount the Vue instance for suited condition.
There is an vm.unmount() method on Vue 3 instance. If you are using Vue 2 you can use vm.$destroy().
If you are using file template you can use v-if condition on your component. That will remove element from DOM based on condition.
#gurkan-ugurlu third option works well.
My requirement was to mount and unmount the Vue instance. but it turns out, it was to render the DOM element for the suited condition for that template condition works well.
by searching, I understood that template conditions like if-else actually render the component. it's not like applying CSS property display: none;

Access dom element with vuejs and vuetify in v-tabs

I have a div tag with an 'id="meet"' into v-tabs.
I need to access the node of this tag after I click a tab. I am using
let node=document.querySelector("#meet").
My problem is that it always returns "null". Here is the codepen: https://codepen.io/luizalves/pen/WNrepxz
What is wrong here?
There is no guarantee that after $nextTick you will see DOM element immediately.
<div id="meet"></div>
<button #click="onTest">test</button>
...
methods: {
onTest () {
let node=document.querySelector("#meet");
console.log('meet here',node)
},
After you clicked test you'll see in a console:
"meet here" "<div id='meet'></div>"
You can try to extract this div with an unique id into a separate component and inside it you can use mounted hook to know that it exists in DOM
Of course, according to vuetify docs, you may add eager prop to v-tab-item component, and that's it, but...possibly you are doing something wrong.
It's not a good idea to always add this prop because you are losing one of the vuetify 2.X advantages - lazy loading. This may lead to big performance problems if there are many elements on the tab.
Maybe it would be better if you will work directly with reactive variables (like variables in v-model directive), not DOM objects.

Vue force all children components to render

I’m using Vue & Vuetify to create my app. With vuetify I’m using v-expansion-panels to create an accordion style display. Each v-expansion-panel itself contains a custom component.
I have noticed these components are not created until the expansion panel is clicked for the first time. After that, using keep-alive allows all reactive properties and methods of the child component to be active (this is my desired behavior).
How can I force the child components to be created when the parent is created? This, any method triggered in the created() lifecycle hook of a child component should fire when the parent is created.
This Codepen is an example of the current behavior. Note: be sure to look at the console when you click the panel.
If you think about it, it actually makes sense to lazy load content of expansion panels since it is useless work if the user never opens them anyway. So probably the thing you try to accomplish has some better approach, but if you still like it then my advice is to find a way of programatically opening / closing the panel (as seen here) and quickly open it and close it when rendering parent component. In this way, you will have your child component created and the UI will remain the same.
A Vuetify solution should be achievable by adding the eager prop to a v-expansion-panel-content element in the Expansion Panel. This should force any components or content contained within the v-expansion-panel-content element to render on mounted.
<v-expansion-panels v-model="panels">
<v-expansion-panel>
<v-expansion-panel-content eager>
<custom-component />
</v-expansion-panel-content>
</v-expansion-panel>
</v-expansion-panels>

How to disable replacing the app root div with the component HTML while using templates

So basically, when using components - the app root passed to the Vue instance gets replaced by whatever HTML is in the component. Is there a way to disable this and just nest the stuff Vue renders inside the app root instead?
for example - if index.html has a wrapper of
<div id="myVueApp"></div>
and I set el: "#myVueApp" on the Vue instance, the whole node will get removed and replaced by whatever I have in my template resulting in
<div id="myComponent">...</div>
Is there a way to make it into
<div id="myVueApp">
<div id="myComponent">...</div>
</div>
Should work. From what I understand, you want to have multiple parts of your Vue app to be splitted up in the rendered HTML output as well, more specifically into multiple divs.
I think this should work if you use multiple Vue instances.
Set up a structure in your HTML file and give them appropriate id's.
Then, create the Vue instances you want and assign each of them to their specific div using el.
However, I can't tell you if this is a good idea and follows the best practice..
Hope this helps!

How to avoid {{expr}} flash to display on page before Vue.js take over?

For example, I have somewhat large amount of spans (over 300+) in one page, each span has {{expr}} binding to display its content:
<span>{{expr}}</span>
Right after page loaded, the literal {{expr}} will flash to display on the page before VueJS takes over and display the real binding value. This looks bad to client, is there a way to avoid it?
v-cloak is the HTML attribute you are looking for.
This directive will remain on the element until the associated Vue instance finishes compilation. Combined with CSS rules such as [v-cloak] { display: none }, this directive can be used to hide un-compiled mustache bindings until the Vue instance is ready.