Skip to content

Commit be8db77

Browse files
wip(docs): add new example: Dynamic component (:is Special Attribute)
1 parent c29e8af commit be8db77

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

docs/examples.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* [SFC style CSS variable injection (new edition)](#sfc-style-css-variable-injection-new-edition)
77
* [Minimalist example (just for the fun)](#minimalist-example-just-for-the-fun)
88
* [Use `options.loadModule` hook](#use-optionsloadmodule-hook)
9+
* [Dynamic component (`:is` Special Attribute)](#dynamic-component-is-special-attribute)
910
<!--/toc-->
1011

1112
# Examples
@@ -380,6 +381,85 @@ _see at [vuejs/rfcs](https://github.com/vuejs/rfcs/pull/231)_
380381
[:top:](#readme)
381382

382383

384+
385+
## Dynamic component (`:is` Special Attribute)
386+
387+
<!--example:source:dynamic_component-->
388+
```html
389+
<!DOCTYPE html>
390+
<html>
391+
<body>
392+
<div id="app"></div>
393+
<script src="https://unpkg.com/vue@next"></script>
394+
<script src="https://cdn.jsdelivr.net/npm/[email protected] "></script>
395+
<script>
396+
397+
const options = {
398+
399+
moduleCache: {
400+
vue: Vue,
401+
},
402+
403+
getFile(url) {
404+
405+
switch ( url ) {
406+
case 'a.vue':
407+
return `
408+
<template>
409+
<i> a </i>
410+
</template>
411+
`;
412+
case 'b.vue':
413+
return `
414+
<template>
415+
<b> b </b>
416+
</template>
417+
`;
418+
}
419+
420+
return fetch(url).then(res => res.ok ? res.text() : Promise.reject( new Error(res.statusText) ));
421+
},
422+
423+
addStyle() {},
424+
}
425+
426+
const { loadModule } = window["vue3-sfc-loader"];
427+
428+
429+
const app = Vue.createApp({
430+
template: `
431+
<button
432+
@click="currentComponent = currentComponent === 'a' ? 'b' : 'a'"
433+
>toggle</button>
434+
dynamic component:
435+
<component :is="comp"></component>
436+
`,
437+
computed: {
438+
comp() {
439+
440+
const currentComponent = this.currentComponent; // the trick is here
441+
return Vue.defineAsyncComponent( () => loadModule(currentComponent + '.vue', options) )
442+
}
443+
},
444+
data() {
445+
return {
446+
currentComponent: 'a',
447+
}
448+
}
449+
});
450+
451+
app.mount('#app');
452+
453+
</script>
454+
</body>
455+
</html>
456+
```
457+
<!--example:target:dynamic_component-->
458+
[open in JSBin](http://jsbin.com/?html,output&html=%3C!DOCTYPE+html%3E%0A%3Chtml%3E%0A%3Cbody%3E%0A++%3Cdiv+id%3D%22app%22%3E%3C%2Fdiv%3E%0A++%3Cscript+src%3D%22https%3A%2F%2Funpkg.com%2Fvue%40next%22%3E%3C%2Fscript%3E%0A++%3Cscript+src%3D%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fvue3-sfc-loader%400.2.19+%22%3E%3C%2Fscript%3E%0A++%3Cscript%3E%0A%0A++++const+options+%3D+%7B%0A%0A++++++moduleCache%3A+%7B%0A++++++++vue%3A+Vue%2C%0A++++++%7D%2C%0A%0A++++++getFile(url)+%7B%0A%0A++++++++switch+(+url+)+%7B%0A++++++++++case+'a.vue'%3A%0A++++++++++++return+%60%0A++++++++++++++%3Ctemplate%3E%0A++++++++++++++++%3Ci%3E+a+%3C%2Fi%3E%0A++++++++++++++%3C%2Ftemplate%3E%0A++++++++++++%60%3B%0A++++++++++case+'b.vue'%3A%0A++++++++++++return+%60%0A++++++++++++++%3Ctemplate%3E%0A++++++++++++++++%3Cb%3E+b+%3C%2Fb%3E%0A++++++++++++++%3C%2Ftemplate%3E%0A++++++++++++%60%3B%0A++++++++%7D%0A%0A++++++++return+fetch(url).then(res+%3D%3E+res.ok+%3F+res.text()+%3A+Promise.reject(+new+Error(res.statusText)+))%3B%0A++++++%7D%2C%0A%0A++++++addStyle()+%7B%7D%2C%0A++++%7D%0A%0A++++const+%7B+loadModule+%7D+%3D+window%5B%22vue3-sfc-loader%22%5D%3B%0A%0A%0A++++const+app+%3D+Vue.createApp(%7B%0A++++++template%3A+%60%0A++++++++%3Cbutton%0A++++++++++%40click%3D%22currentComponent+%3D+currentComponent+%3D%3D%3D+'a'+%3F+'b'+%3A+'a'%22%0A++++++++%3Etoggle%3C%2Fbutton%3E%0A++++++++dynamic+component%3A%0A++++++++%3Ccomponent+%3Ais%3D%22comp%22%3E%3C%2Fcomponent%3E%0A++++++%60%2C%0A++++++computed%3A+%7B%0A++++++++comp()+%7B%0A%0A++++++++++const+currentComponent+%3D+this.currentComponent%3B+%2F%2F+the+trick+is+here%0A++++++++++return+Vue.defineAsyncComponent(+()+%3D%3E+loadModule(currentComponent+%2B+'.vue'%2C+options)+)%0A++++++++%7D%0A++++++%7D%2C%0A++++++data()+%7B%0A++++++++return+%7B%0A++++++++++currentComponent%3A+'a'%2C%0A++++++++%7D%0A++++++%7D%0A++++%7D)%3B%0A%0A++++app.mount('%23app')%3B%0A%0A++%3C%2Fscript%3E%0A%3C%2Fbody%3E%0A%3C%2Fhtml%3E%0A)<!--/example:target:dynamic_component-->
459+
[:top:](#readme)
460+
461+
462+
383463
<!---
384464
385465
const regexpReservedChars = '\\.+*?^$|[{()';

0 commit comments

Comments
 (0)