Discussion
Discussion copied to clipboard
How to change component template dynamically
Hi,
I want to change Component's template string dynamically. The component is already attached to DOM. Then I change the template at run time. I want that change to get reflect in UI.. Please let me know the way.
Currently i am creating a component using below method
Vue.component('Comp1', {
'template':'Loading...'
});
Then when my data loads and i get template str in templatestr variable then again i am doing:
Vue.component('Comp1', {
'template': templatestr
});
I am again creating a new component with the same name but this time with new template string. ideally it should replace the previously attached component with the new one. But it is not working as per the expectation. Please tell me if i am wrong somewhere.
Thanks, Anshul
Use v-if
or v-show
directives to show/hide things:
<p v-if="loading">Loading...</p>
<template v-if="!loading">
<!-- loaded data here -->
</template>
i cannot use v-if because more than 50 templates are being loaded dynamically on demand of user.
I think you are approaching this with wrong assumptions. Templates for a component is static, once it's defined you can't change it. You need to express the parts that may be changed inside the template.
It's probably a good use case for the deprecated partial syntax... or, I can make v-html
automatically compile its content.
I have a problem... I am trying to make a 'view source' component. The template is in an external file loaded with jQuery. I use async component syntax to declare it., it's like that:
Vue.component('source-view', function (resolve, reject) {
loader('/ScriptsLocal/components/SourceView.html').done(tpl => {
resolve({
template: tpl,
data: function () {
var result = { text: null };
if (this.selector) {
var eHtml = $(this.selector);
if (eHtml && eHtml.length)
result.text = eHtml.html();
}
return result;
},
props: {
selector: {
type: String,
required: false,
},
},
});
}).fail(x => reject(x));
})
The problem with that is it always get the HTML after Vue has updated it, I would like to get the early html, showing all the bindings!!! Any idea how I could do that with template in an external file?
Not in my HTML page I use the sourceView component like that:
<source-view title="Source code: view" selector=".liveExample"></source-view>
@yyx990803 I think that would be nice that v-html
compiles its template. Otherwise how are we supposed to manage this kind of behavior ? I have a list that can display 300 types of element. I'm not going to load them all. I'll just load those I need to display the list.
I feel like there is a lack of support on run-time loading component from the server. I always get stuck when it comes to download a template and bootstrap it in my Vue...
I think I found a decent solution to this problem, using render function: https://jsfiddle.net/gm4uf485/2/
new Vue({
el: '#app',
data: {
msg: 'hello',
template: null
},
render: function(createElement) {
if (!this.template) {
return createElement('div', 'Loading...');
} else {
return this.template();
}
},
mounted() {
var self = this;
setTimeout(function() {
self.template = Vue.compile('<div><span>{{ msg }}</span></div>').render;
}, 1000);
}
})
@Elfayer it doesn't work on vue 2.
have this error message: Uncaught TypeError: _vue2.default.compile is not a function(…)
@jeblister See the JSFiddle above, it does use Vue2. You might be using the runtime-only version. You need the standalone version to use Vue.compile()
. See: https://vuejs.org/v2/guide/installation.html#Standalone-vs-Runtime-only-Build
But here is a more appropriate example (more complexe too): https://jsfiddle.net/Linusborg/47ejdvyy/6/ From the forum: https://forum.vuejs.org/t/vue-compile-what-is-staticrenderfns-render-vs-staticrenderfns/3950/12
@Elfayer Thank you very much !
@Elfayer @LinusBorg
A problem with the second example (using functional components to render dynamic templates) seems to be strange reactivity. It looks like any state change, even those unrelated to functional components' props, will trigger re-rendering: https://jsfiddle.net/mcgullenz/c7vqwbkm/
Is this to be expected or am I doing something wrong? Thanks.
This repo is deprecated, please forum.vuejs.org
does this work with server side rendering also?