Как загрузить внешний файл html в шаблон в VueJs

Я новичок в vue js. Я просто создаю простой проект, где я просто включаю vuejs через CDN. не используя node/npm или cli.

Я сохраняю все мои html-разметки в одном html, который выглядит беспорядочным, когда он растет. Я попытался разделить html на представления и хочу включить его чем-то, аналогичным ng-include angularJs

Раньше я работал в угловом формате, где ng-include загружал внешние html файлы. Я ищу что-то подобное этому в vue. все дело в том, чтобы разбить мои html файлы на более поддерживаемые отдельные файлы.

столкнулись с <template src="./myfile.html"/> но это не работает. Может кто-нибудь помочь мне

Ответ 1

Вы не можете. Вы должны использовать компоненты асинхронных - прочитать инструкцию здесь

Ответ 2

Это действительно замечательно легко, но вам нужно помнить об этом. За кулисами Vue конвертирует ваш HTML-шаблон в код. То есть каждый элемент, который вы видите как HTML, преобразуется в директиву javascript для создания элемента. Шаблон является удобством, поэтому однофайловый компонент (vue файл) - это не то, что вы сможете сделать без компиляции с чем-то вроде webpack. Вместо этого вам нужно будет использовать другой способ шаблонирования. К счастью, существуют другие способы определения шаблонов, которые не требуют предварительной компиляции и могут использоваться в этом сценарии.

1 - строковые/шаблонные литералы

Пример: template: '<div>{{myvar}}</div>'

2 - функция рендеринга 🤢

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

У Vue есть несколько других способов создания шаблонов, но они просто не соответствуют критериям.

вот пример для обоих:

AddItem.js - использование функций render 😠

'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 - использование шаблонных литералов (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);
    }
  }
});

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

См. Его в действии по адресу: https://repl.it/OEMt/9

Ответ 3

ng-include действительно потрясающе для загрузки шаблонов для маршрутизатора. Альтернативой является использование fetch и реализация ваших собственных обещаний.

Ответ 4

Вы решили свою проблему? Я сталкиваюсь с вашей проблемой. Приложение I

Ответ 5

На самом деле вы можете. Это довольно легко. Зависит от ваших потребностей и ситуации. Тем не менее, этот код НЕ является технически правильным, однако он объяснит вам, как он может работать, дает вам большую свободу и уменьшает исходный экземпляр vue.

Чтобы это работало, вам понадобится маршрутизатор vue (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 content

<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 на рендеринг всего, если текущая страница после первого просмотра не проиндексирована. Все остальное должно работать нормально.

Как вы можете видеть, если это индекс, он загрузит приветственный файл контента.