Rendering after ajax request - vue.js

I have place objects that look like this:
"london" : {
capital: true,
images: ["pic1.jpg","pic2.jpg"],
...
}
They are retrieved from the backend and assigned to a place object in data.
The issue/question I have is how to handle the delay in retrieving the data from the backend when rendering the view.
My template might have something like this:
<p>{{place.images[0]}}</p>
but this causes errors/warnings in the console because there is no such thing as the images array until the data has been fetched.
I can think of two ways to handle this.
I define an empty images array within the data object. But I would have to do this for every property (and sub-property) that I will potentially use which isn't ideal.
I use v-if and a loading variable to conditionally render the template part.
Is there a "vuejs" approach to this that I've not considered?

I think you are looking for The v-cloak directive
This directive will remain on the element until the associated Vue
instance finishes compilation.
You have to use like
<p v-cloak>{{place.images[0]}}</p>
Read about v-cloak in docs, and more discussion

Related

how to render single vue instance into different dom locations

Suppose you have to render paginated data.
A paginator component should appear above and below the data table rendering exactly the same output.
The most basic approach would be declaring the paginator component twice - one above the data and one below. But the resulting vnodes (and even the dom fragment) of the paginator component instances will be equal. Both paginator instances would compute (also twice !) completely equal vnode and dom fragments.
I would like to avoid duplicated vnodes/dom node rendering and computation time. Basically compute everything once and duplicating the resulting nodes would be the ideal goal.
My current known options:
Hacking something like a single Vue pagination component and cloning its resulting DOM output to somewhere else sounds like a bad idea because of potential Vuiejs $ref and dom/vuejs event handling issues. So this is actually no option.
What about cloning the vnode of the first pagination component instance and reuse it for the second instance ? Is that the way to go ?
What is the best option ?
Are there any better approaches to match my expectations ?

How to use vuejs directive on condition?

I am suing https://github.com/DominikSerafin/vuebar directive in my project. Now depending on some var i want to use it in html or not.
Like this
<div v-bar>
//this div contains huge html like 1200 lines of code and doing
// v-if is not option since i will have to duplicate all of its content
</div>
So to sumarize:
<div v-bar v-if="somevar"></div> // is not and option bceuse that div contains 1200 of code
Is there any way that i can say something like:
<div some_var ? v-bar:''></div>
Or to make my directive that sort of inherits that v-bar and renders?
Actually you can do one thing. Use Directive Hook Arguments.
You can put your condition based on the hook arguments inside the directive's code. And you can make sure the those hook arguments are reactive so that it could change when you want it to.
Write you logic whether to do something or not for directive inside the directive's code depending upon the binding values.
Read this, please comment if you are not clear.
No, there is no way to apply directive with some condition.
But you can try to create and destroy custom scroll bar programatically, from docs:
Public methods.
You can access them from your component context: this.$vuebar.
Alternatively you can access them from your main Vue instance:
Vue.vuebar. Every method needs to have passed Vuebar scroll container
element as the first argument. You can do that easily using $refs.
initScrollbar(DOM Element, options)
getState(DOM Element)
refreshScrollbar(DOM Element, options)
destroyScrollbar(DOM Element)

RiotJS mounting tag without subtags

I am using tag-based routing with RiotJS. If the tag in the route contains an other tag, it is automatically mounted. Which is great in some cases. But there are cases when I need to pass some options to the tag being mounted, that can't be passed as tag property. I know that this.tags will contain them and I have the means to pass that parameter afterward. But I still am curious if there is a way to stop RiotJS automounting some subtags.
Sounds like you have a design error.
Remember that a tag can contain any classic JS code; you can simply write a logic that populates the tag in any time, way, shape or form. You can also hide it's content via the if condition until it is populated, while it is mounted. You can also hide it in the parent and prevent its mounting in the same manner if you so desire.

Initialize dynamic Component in Code using Vue.js

I am currently developing a web application that is used to display elements for events on a map provided by HERE Maps. I am using Vue.
I have some components, but the relevant component is the component HereMaps.vue which initializes the map using the HERE Maps Api.
The HERE Maps Api provides the possibility to place so called InfoBubbles on the map showing additional information. These InfoBubbles can be provided some HTML-code in order to customize their appearance.
Please refer to the documentation for additional information
Following the documentation the code looks something like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<div class='someClass'>Some Content</div>"
});
this.ui.addBubble(bubble)
This is happening after mount in the "mounted" method from Vue in the "HereMaps" component.
The Bubbles are added in a "closed" (hidden) form and dynamically "opened" to reveal their content when the corresponding marker icon on the map is clicked. Therefore the HTML-code is present on the DOM after the component is mounted and is not removed at a later stage.
Now instead of supplying custom code within each bubble added to the UI i want to just add a component like this:
let bubble = new H.ui.InfoBubble(marker.getPosition(), {
content: "<myDynamicComponent></myDynamicComponent>"
});
this.ui.addBubble(bubble)
It does not matter to me wether the component is initialized using props or if it is conditionally rendered depending on the state of a global variable. I just want to be able to use the "myDynamicComponent" in order to customize the appearance in a different file. Otherwise the design process gets very messy.
As far as i know this is not possible or at least i was not able to get it work. This is probably due to the fact that the "myDynamicComponent" is not used within the "template" of the "HereMaps" component und thus Vue does not know that it needs to render something here after the directive is added to the DOM in the "mounted" method.
This is what the InfoBubble looks using normal HTML as an argument:
This is what the InfoBubble looks using the component as an argument:
It appears to just be empty. No content of the "myDynamicComponent" is shown.
Does anyone have any idea how i could solve this problem.
Thank You.
Answer is a bit complicated and I bet you wouldn't like it:)
content param can accept String or Node value. So you can make new Vue with rendered your component and pass root element as content param.
BTW, Vue does not work as you think, <myDynamicComponent></myDynamicComponent> bindings, etc exists in HTML only in compile time. After that all custom elements(components) are compiled to render functions. So you can't use your components in that way.
Give us fiddle with your problem, so we can provide working example:)

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.