web-dev-qa-db-fra.com

VueJs templating. Comment charger des modèles externes

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>
51
rksh

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.

 vue file

En outre, l’auteur de Vue a écrit un article de Nice sur le thème des url de modèles externes:

http://vuejs.org/2015/10/28/why-no-template-url/

24
Bill Criswell

Vous pouvez essayer ceci: https://github.com/FranckFreiburger/http-vue-loader

Exemple: 

 new Vue({
        components: {
            'my-component': httpVueLoader('my-component.vue')
        },
        ...
12
Franck Freiburger

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 )

11
swift

1. Dans Vue 2.x, je vous recommande de vous en tenir à la convention en utilisant les fichiers .vue mais en inversant l'ordre des importations:

// 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.

2. Si vous voulez charger paresseux, il existe apparemment un moyen de le faire dans Vue 2.x

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

1
ako977

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.

0
David K. Hess

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>.

Utilisation (à partir de la documentation du chargeur)

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

0
Andriy Lach

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']));
0
RaduM