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