Je suis nouveau dans Vue.js. Cela fait un certain temps que je travaille avec AngularJS et, de manière angulaire, nous avons chargé des modèles tels
template: '/sometemplate.html',
controller: 'someCtrl'
Comment pouvons-nous faire une telle chose dans Vue, au lieu de garder de grands modèles HTML dans JavaScript comme ceci,
new Vue({
el: '#replace',
template: '<p>replaced</p>'
})
Cela convient pour les petits modèles, mais pour les grands modèles, est-ce pratique?
Est-il possible de charger un modèle HTML externe ou d'utiliser un modèle HTML dans une balise de script comme dans Vue?
<script type="x-template" id="template>HTML template goes here</html>
Vous pouvez utiliser le modèle de balise de script en vous référant simplement à sa id
.
{
template: '#some-id'
}
Cependant, je vous recommande vivement d’utiliser vueify (si vous utilisez browserify) ou vue-loader (si vous utilisez webpack) pour que vos composants soient stockés dans de jolis petits fichiers .vue
comme celui-ci.
En outre, l’auteur de Vue a écrit un article de Nice sur le thème des url de modèles externes:
Vous pouvez essayer ceci: https://github.com/FranckFreiburger/http-vue-loader
Exemple:
new Vue({
components: {
'my-component': httpVueLoader('my-component.vue')
},
...
David, c’est un bon exemple, mais quel est le meilleur moyen de s’assurer que le DOM est compilé?
https://jsfiddle.net/q7xcbuxd/35/
Lorsque je simule une opération asynchrone, comme dans l'exemple ci-dessus, cela fonctionne. Mais dès que je charge une page externe "à la volée", Vue se plaint de ce que le DOM n'est pas prêt . Plus précisément: Uncaught TypeError: Cannot set property 'vue' of undefined
Existe-t-il un meilleur moyen de le faire que appeler $compile
lorsque la page a été chargée? J'ai essayé avec $mount
, mais cela n'a pas aidé.
UPDATE: Peu importe, j'ai enfin compris comment le faire:
Vue.component('async-component', function (resolve, reject) {
vue.$http.get('async-component.html', function(data, status, request){
var parser = new DOMParser();
var doc = parser.parseFromString(data, "text/html");
resolve({
template: doc
});
});
});
Et dans le modèle actuel, j'ai supprimé le
<script id="someTemplate" type="text/x-template"></script>
balises et seulement inclus le HTML.
(Cette solution nécessite le chargeur HTTP de https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.10/vue-resource.min.js )
// template.vue
<template>
<div class="helloworld">
<h1>Hello world</h1>
</div>
</template>
<script>
import src from './src'
export default src
</script>
et dans un fichier séparé
// src.js
export default {
name: 'helloworld',
props: {},
...
}
Puis dans votre enregistrement de composant
import helloworld from './helloworld/template.vue'
new Vue({
components: {
'helloworld': helloworld
},
...})
De cette façon, vous obtenez le meilleur des deux mondes et vous n'avez pas à vous forcer à créer des modèles dans une chaîne.
new Vue({
components: {
'helloworld': () => import(/* webpackChunkName: "helloworld" */ './helloworld/template.vue')
},
...})
Cela chargera helloworld.js (qui contiendra tout le code de ce composant) à la demande de cette page dans le navigateur.
Bien entendu, tout ce qui précède suppose que vous utilisez ES6 avec des capacités import
Vous pouvez utiliser cette approche avec superagent:
var promise = superagent.get("something.html")
.end(function (error, response) {
if (error) {
console.error("load of something.html failed", error));
return;
}
var parser = new DOMParser()
var doc = parser.parseFromString(response.text, "text/html");
document.body.appendChild(doc.scripts[0]);
});
Il suffit de placer votre modèle basé sur une balise <script>
à l'intérieur de something.html
sur votre serveur.
Si vous utilisez jQuery, .load devrait fonctionner.
Assurez-vous simplement que cette opération est terminée avant que le DOM en question ne soit compilé par Vue. Ou utilisez $ mount pour configurer manuellement les éléments.
J'ai essayé http-vue-loader et cela fonctionne bien. Cette bibliothèque est facile à utiliser et a une bonne documentation et exemples
Bien que vous ne puissiez pas charger les modèles directement depuis un fichier, vous pouvez toujours conserver le code HTML dans des composants séparés à fichier unique. Vous pouvez même ignorer la partie <script>...</script>
.
my-component.vue
<template>
<div class="hello">Hello {{who}}</div>
</template>
index.html
<!doctype html>
<html lang="en">
<head>
<script src="https://unpkg.com/vue"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
</head>
<body>
<div id="my-app">
<my-component></my-component>
</div>
<script type="text/javascript">
new Vue({
el: '#my-app',
components: {
'my-component': httpVueLoader('my-component.vue')
}
});
</script>
</body>
</html>
Les deux fichiers doivent être placés dans un dossier au même niveau
Utilisez browserify pour regrouper tout comme ceci:
//Home.js
import Vue from 'vue';
var Home = Vue.extend({
template: require('./Home.vue')
});
export default Home;
//Home.vue
<h1>Hello</h1>
// And for your browserify bundle use a transform called stringify
... .transform(stringify(['.html', '.svg', '.vue', '.template', '.tmpl']));