簡體   English   中英

VueJs 模板。 如何加載外部模板

[英]VueJs templating. How to load external templates

我是 Vue.js 的新手,我使用 AngularJS 有一段時間了,在 angular 中我們曾經加載過模板,例如,

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

我們如何在 Vue 中做這樣的事情,而不是像這樣在 JavaScript 中保留大型 HTML 模板,

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

這對於小模板來說是可以的,但是對於大模板來說這實用嗎?

有沒有辦法像 Vue 一樣加載外部模板 HTML 或在腳本標簽內使用 HTML 模板?

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

您可以通過引用其id來使用腳本標記模板。

{
  template: '#some-id'
}

不過,我強烈建議使用vueify (如果您使用browserify )或vue-loader (如果您使用 webpack),這樣您就可以將您的組件存儲在像這樣的.vue小文件中。

vue 文件

另外,Vue 的作者寫了一篇關於外部模板 url 主題的好文章:

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

你可以試試這個:
對於 Vue2: https : //github.com/FranckFreiburger/http-vue-loader
對於 Vue3: https : //github.com/FranckFreiburger/vue3-sfc-loader

示例(Vue2):

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

示例(Vue3):

Vue.createApp({
  components: {
    'my-component': Vue.defineAsyncComponent(() => loadModule('./myComponent.vue', opts))
  },
  ...

大衛,這是一個很好的例子,但確保 DOM 被編譯的最佳方法是什么?

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

當我模擬一個異步操作時,就像上面的例子一樣,它可以工作。 但是一旦我“即時”加載外部頁面,Vue 就會抱怨,因為 DOM 還沒有准備好。 更具體地說: Uncaught TypeError: Cannot set property ' vue ' of undefined有沒有比在頁面加載時調用$compile更好的方法來做到這一點? 我試過$mount ,但這沒有幫助。

更新:沒關系,我終於想出了怎么做:

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。

(此解決方案需要來自https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.10/vue-resource.min.js的 http 加載器)

我試過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>

兩個文件應該放在同一個文件夾中

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(它將包含所有該組件的代碼)。

當然,以上所有假設您使用具有import功能的 ES6

至少有 2 種方法可以實現你想要的,其中(x 模板)已經被 Bill Criswell 提到過,但我認為值得添加一個例子

  1. 像這樣定義你的組件

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

  2. 添加帶有 x-template 的 html 文件(id 應與您在組件中指定的匹配)

    <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屬性,否則它將不起作用

您可以將此方法與超級代理一起使用:

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應該可以工作。

只需確保在 Vue 編譯有問題的 DOM 之前完成。 或者使用$mount手動設置。

使用 browserify 捆綁所有內容,如下所示:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM