it-swarm.com.de

So laden Sie eine externe HTML-Datei in eine Vorlage in VueJs

Ich bin neu in Js. Ich erstelle gerade ein einfaches Projekt, in das ich nur Vuejs über CDN einbeziehe. nicht mit knoten/npm oder cli.

Ich behalte mein HTML-Markup in einem einzigen HTML-Code, der mit zunehmendem Wachstum unordentlich aussieht. Ich habe versucht, HTML in Ansichten aufzuteilen und möchte es durch etwas Analoges zu ng-include von angleJs aufnehmen

Ich habe vorher in eckig gearbeitet, wo es ng-include gibt, um externe HTML-Dateien zu laden. Ich suche etwas Ähnliches in vue. Der springende Punkt ist, meine HTML-Dateien in mehr wartbare separate Dateien aufzuteilen. 

ich habe <template src="./myfile.html"/> gefunden, aber es funktioniert nicht Kann mir jemand helfen? 

8
Khaleel

Du kannst nicht Sie müssen asynchrone Komponenten verwenden - lesen Sie die Anleitung hier

2
user6748331

Es ist eigentlich erstaunlich einfach, aber man muss sich etwas merken. Hinter den Kulissen konvertiert Vue Ihre HTML-Vorlagenmarkierung in Code. Das heißt, jedes Element, das Sie als HTML sehen, wird in eine Javascript-Direktive umgewandelt, um ein Element zu erstellen. Die Vorlage ist eine Annehmlichkeit, daher können Sie mit der Ein-Datei-Komponente (vue-Datei) nicht etwa mit Webpack kompilieren. Stattdessen müssen Sie eine andere Art der Vorlage verwenden. Glücklicherweise gibt es andere Möglichkeiten, Vorlagen zu definieren, die nicht vorkompiliert werden müssen und in diesem Szenario verwendet werden können.

1 - String-/Vorlagenliterale

beispiel: template: '<div>{{myvar}}</div>'

2 - Renderfunktion ????

beispiel: render(create){create('div')}

Vue bietet verschiedene Möglichkeiten zum Erstellen von Vorlagen, sie entsprechen jedoch nicht den Kriterien.

hier ist das Beispiel für beide:

AddItem.js - Rendern ???? Funktionen

'use strict';
Vue.component('add-item', {
  methods: {
    add() {
      this.$emit('add', this.value);
      this.value = ''
    }
  },

  data () {
    return {
      value: ''
    }
  },

  render(createElement) {
    var self = this
    return createElement('div', [
      createElement('input', {
        attrs: {
          type: 'text',
          placeholder: 'new Item'
        },
        // v-model functionality has to be implemented manually
        domProps: {
          value: self.value
        },
        on: {
          input: function (event) {
            self.value = event.target.value
            // self.$emit('input', event.target.value)
          }
        }
      }),
      createElement('input', {
        attrs: {
          type: 'submit',
          value: 'add'
        },
        on: {
          click: this.add
        }
      }),
    ])
  }
});

ListItem.js - Verwendung von Vorlagenliteralen (Back-Ticks)

'use strict';
Vue.component('list-item', {
  template: `<div class="checkbox-wrapper" @click="check">
    <h1>{{checked ? '☑' : '☐'}} {{ title }}</h1>
  </div>`,
  props: [
    'title',
    'checked'
  ],
  methods: {
    check() {
      this.$emit('change', !this.checked);
    }
  }
});

und das HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.0/vue.js"></script>
  <script src="ListItem.js"></script>
  <script src="AddItem.js"></script>
</head>
<body>
<div id="app">
  <add-item @add='list.Push({title:arguments[0], checked: false})'></add-item>
  <list-item v-for="(l, i) in list" :key="i" :title="l.title" :checked="l.checked" @change="l.checked=arguments[0]"></list-item>
</div>
<script type="text/javascript">
new Vue({
  el: '#app',
  data: {
    newTitle: '',
    list: [
      { title: 'A', checked: true },
      { title: 'B', checked: true },
      { title: 'C', checked: true }
    ]
  }
});
</script>
</body>
</html>


TL; DR;

Sieh es in Aktion unter: https://repl.it/OEMt/9

2
Daniel

ng-include war wirklich super für das Laden von Vorlagen für den Router. Eine Alternative ist die Verwendung von fetch und die Implementierung Ihres eigenen Versprechens.

0
domih

Eigentlich kannst du. Das ist ein bisschen einfach. Hängt von Ihren Bedürfnissen und Ihrer Situation ab. Allerdings dieser Code ist technisch NICHT korrekt, aber er erklärt Ihnen, wie es funktionieren könnte, gibt Ihnen enorme Freiheit und verkleinert Ihre ursprüngliche vue Instanz).

Damit dies funktioniert, benötigen Sie vue Router (cdn ist in Ordnung) und in diesem Fall Axios oder Fetch (falls Sie ältere Browser nicht unterstützen möchten).

Der einzige Nachteil meiner Meinung nach ist, dass Sie in Inhaltsdateien zusätzliche Aufrufparameter hinzufügen müssen $ parent. Dies zwingt vue zur Arbeit.

Index

<div id="app">

  <router-link v-for="route in this.$router.options.routes" :to="route.path" :key="route.path">{{ route.name }}</router-link>

  <section style="margin-top:50px;">
     <component :is="magician && { template: magician }" />
  </section>

</div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>

  <script>
     const viewer = axios.create({ baseURL: location.Origin });

     const routes = [
       {"name":"Hello","slug":"hello","path":"/lol/index.html"},
       {"name":"Page One","slug":"page_one","path":"/lol/page-one.html"},
       {"name":"Page Two","slug":"page_two","path":"/lol/page-two.html"}
     ];

     const app = new Vue({
       router,
       el: '#app',
       data: {
          magician: null,
       },
       watch: {
          $route (to) {
              this.loader(to.path);
          }
       },
       mounted() {
          this.loader(this.$router.currentRoute.path);
       },
       methods: {
          viewer(opt) {
              return viewer.get(opt);
          },
          loader(to) {
              to == '/lol/index.html' ? to = '/lol/hello.html' : to = to;
              this.viewer(to).then((response) => {
                  this.magician = response.data;
              }).catch(error => {
                  alert(error.response.data.message);
              })
          },
          huehue(i) {
            alert(i);
          }
       }
     });
  </script>

Hallo.html Inhalt

<button v-on:click="$parent.huehue('this is great')">Button</button>

page-one.html content

<select>
   <option v-for="num in 20">{{ num }}</option>
</select>

page-two.html content

// what ever you like

Router Erklärung

Damit dies perfekt funktioniert, müssen Sie einen korrekten Weg finden, um Ihren htaccess so zu konfigurieren, dass alles gerendert wird, wenn die aktuelle Seite nach der ersten Ansicht kein Index ist. Alles andere sollte gut funktionieren.

Wie Sie sehen können, wenn es sich um einen Index handelt, wird die Hallo-Inhaltsdatei geladen.

0
Tauras