Подтвердить что ты не робот

VueJs templating. Как загрузить внешние шаблоны

Я новичок в Vue.js, я использовал AngularJS в течение некоторого времени, а в angular мы использовали для загрузки шаблонов, таких как

template: '/sometemplate.html',
controller: 'someCtrl'

Как мы можем сделать такую ​​вещь в Vue, вместо того, чтобы хранить большие HTML-шаблоны внутри JavaScript, как это,

new Vue({
  el: '#replace',
  template: '<p>replaced</p>'
})

Это нормально для небольших шаблонов, но для больших шаблонов это практично?

Есть ли способ загрузить внешний HTML-шаблон или использовать HTML-шаблон внутри тега script, как в Vue?

<script type="x-template" id="template>HTML template goes here</html>
4b9b3361

Ответ 1

Вы можете использовать шаблон тега script, просто ссылаясь на его id.

{
  template: '#some-id'
}

Тем не менее, я настоятельно рекомендую использовать vueify (если вы используете browserify) или vue-loader (если вы используете webpack), чтобы вы могли хранить свои компоненты в хороших маленьких .vue файлах, подобных этому.

vue file

Также автор Vue написал хороший пост на тему внешних шаблонов URL:

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

Ответ 3

Дэвид, это хороший пример, но лучший способ убедиться, что DOM скомпилирован?

https://jsfiddle.net/q7xcbuxd/35/

Когда я имитирую асинхронную операцию, как в приведенном выше примере, она работает. Но как только я загружаю внешнюю страницу "на лету", Vue жалуется, потому что DOM не готов. Более конкретно: Uncaught TypeError: Cannot set property 'vue' of undefined Есть ли лучший способ сделать это, чем позвонить $compile, когда страница загрузилась? Я пробовал с $mount, но это не помогло.

UPDATE: Ничего, я наконец понял, как это сделать:

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

И в фактическом шаблоне я удалил

<script id="someTemplate" type="text/x-template"></script>

и включал только html.

(для этого решения требуется HTTP-загрузчик https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.10/vue-resource.min.js)

Ответ 4

1. В Vue 2.x я рекомендую придерживаться соглашения с использованием файлов .vue, но вместо этого инвертировать порядок импорта:

// template.vue
<template>
  <div class="helloworld">
      <h1>Hello world</h1>
  </div>
</template>

<script>
  import src from './src'
  export default src
</script>

и в отдельном файле

// src.js
export default {
  name: 'helloworld',
  props: {},
  ...
}

Тогда в вашей регистрации компонента

import helloworld from './helloworld/template.vue'

new Vue({
 components: {
 'helloworld': helloworld
},
...})

Таким образом, вы получаете лучшее из обоих миров, и вам не нужно заставлять себя создавать шаблоны внутри строки.

2. Если вы хотите ленивой загрузки, очевидно, есть способ сделать это в Vue 2.x

new Vue({
 components: {
 'helloworld': () => import(/* webpackChunkName: "helloworld" */ './helloworld/template.vue')
},
...})

Это загрузит helloworld.js (который будет содержать весь этот код компонента) по запросу этой страницы в браузере.

Конечно, все вышеперечисленное предполагает, что вы используете ES6 с возможностями import

Ответ 5

Я пробовал http-vue-loader, и он работает нормально. Эта библиотека проста в использовании и имеет хорошую документацию и примеры

Хотя вы не можете загружать шаблоны непосредственно из файла, вы все равно можете хранить html в отдельных однофайловых компонентах. Вы даже можете пропустить часть <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>

Оба файла должны быть размещены в одной папке на одном уровне

Ответ 6

Вы можете использовать этот подход с суперагентом:

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]);
    });

Просто разместите шаблон <script> на основе тегов внутри something.html на вашем сервере.

Если вы используете jQuery, . load должен работать.

Просто убедитесь, что это завершено до того, как DOM, о котором идет речь, скомпилирован Vue. Или используйте $mount для ручной настройки.

Ответ 7

Используйте броузер, чтобы расслоить все, как это:

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

Ответ 8

Есть как минимум 2 способа добиться того, чего вы хотите, один из них (x-шаблоны) уже упомянут Биллом Крисвеллом, но я думаю, что стоит добавить пример

  1. Определите свой компонент следующим образом

    Vue.component('my-checkbox', { // id of x-template template: '#my-template' });

  2. Добавьте html файл с вашим x-шаблоном (идентификатор должен совпадать с тем, который вы указали в компоненте)

    <script type="text/x-template" id="my-template">...</script>

Другой подход (и он мне больше нравится) - использовать встроенный шаблон

  1. Определите свой шаблон следующим образом

    Vue.component('my-template', {});

  2. Добавьте HTML файл со своим компонентом и шаблоном внутри него

    <my-template inline-template>place for your html</my-template>

Только не забудьте добавить атрибут inline-template, иначе он не будет работать