web-dev-qa-db-ja.com

VueJsのテンプレートに外部HTMLファイルをロードする方法

私はvue jsを初めて使用します。node/ npmまたはcliを使用せずに、CDNを介してvuejsを含める単純なプロジェクトを作成しています。

私はすべてのhtmlマークアップを、成長するにつれて乱雑に見える単一のhtmlに保持します。私はhtmlをビューに分割しようとしましたが、ng-includeのangularJs

私は以前にangularで働いていましたが、ng-include外部HTMLファイルをロードします。私はそれと似たようなものをvueで探しています。全体のポイントは、私のhtmlファイルをより保守しやすい個別のファイルに分割することです。

<template src="./myfile.html"/>しかし、それは動作しません

12
Khaleel

できません。非同期コンポーネントを使用する必要があります-ガイドを読む こちら

3
user6748331

実際には非常に簡単ですが、何か覚えておく必要があります。舞台裏では、Vueはhtmlテンプレートマークアップをコードに変換します。つまり、HTMLとして定義された各要素は、JavaScriptディレクティブに変換されて要素を作成します。テンプレートは便利です。そのため、単一ファイルコンポーネント(vueファイル)は、webpackのようなものでコンパイルせずに実行できるものではなく、テンプレートの別の方法を使用する必要があります。プリコンパイルを必要とせず、このシナリオで使用できます。

1-文字列/テンプレートリテラル

例:_template: '<div>{{myvar}}</div>'_

2-レンダリング機能????

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

Vueにはテンプレートを作成する他の方法がいくつかありますが、それらは基準に一致しません。

以下は両方の例です。

AddItem.js-レンダリングの使用????関数

_'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-テンプレートリテラル(バックティック)の使用

_'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);
    }
  }
});
_

そして、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;

次のURLで実際にご覧ください: https://repl.it/OEMt/9

3
Daniel

ng-includeは、ルーター用のテンプレートをロードするために本当に素晴らしかったです。別の方法は、fetchを使用して、独自のプロミスを実装することです。

0
domih

実際にできます。これはちょっと簡単です。ニーズと状況に依存します。ただし、このコードは技術的には正しくありませんですが、どのように機能するかを説明し、大きな自由を与え、元のvueインスタンスを小さくします。

これを機能させるには、vue router(cdnは大丈夫))、この場合はaxiosまたはfetch(古いブラウザーのサポートを気にしない場合)が必要です。

私の意見の唯一の欠点は、コンテンツファイルに追加の呼び出しパラメーター$ parentを追加する必要があることです。これにより、強制的にvueが機能します。

インデックス

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

hello.htmlコンテンツ

<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

ルーターの説明

これを完全に機能させるには、最初のビューの後の現在のページがインデックスにない場合にすべてをレンダリングするようにhtaccessを設定する正しい方法を見つける必要があります。その他はすべて正常に動作するはずです。

ご覧のとおり、インデックスの場合、helloコンテンツファイルが読み込まれます。

0
Tauras