Javascript VueJs 模板。如何加载外部模板
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31633573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
VueJs templating. How to load external templates
提问by rksh
I'm new to Vue.js, I've used AngularJS for some time and in angular we used to load templates such as,
我是 Vue.js 的新手,我使用 AngularJS 有一段时间了,在 angular 中我们曾经加载过模板,例如,
template: '/sometemplate.html',
controller: 'someCtrl'
How can we do such a thing in Vue, instead of keeping large HTML templates inside JavaScript like this,
我们如何在 Vue 中做这样的事情,而不是像这样在 JavaScript 中保留大型 HTML 模板,
new Vue({
el: '#replace',
template: '<p>replaced</p>'
})
This is OK for small templates but for large templates is this practical?
这对于小模板来说是可以的,但是对于大模板来说这实用吗?
Is there a way to load external template HTML or use HTML template inside a script tag like in Vue?
有没有办法像 Vue 一样加载外部模板 HTML 或在脚本标签内使用 HTML 模板?
<script type="x-template" id="template>HTML template goes here</html>
回答by Bill Criswell
You can use the script tag template by just referring to its id
.
您可以通过引用脚本标签模板来使用它的id
.
{
template: '#some-id'
}
Though, I highly recommend using vueify(if you use browserify) orvue-loader(if you use webpack) so you can have your components stored in nice little .vue
files like this.
不过,我强烈建议使用vueify(如果您使用browserify)或vue-loader(如果您使用 webpack),这样您就可以将您的组件存储在这样的小.vue
文件中。
Also, the author of Vue wrote a nice post about the topic of external template urls:
另外,Vue 的作者写了一篇关于外部模板 url 主题的好文章:
回答by Franck Freiburger
You can try this: https://github.com/FranckFreiburger/http-vue-loader
你可以试试这个:https: //github.com/FranckFreiburger/http-vue-loader
Example:
例子:
new Vue({
components: {
'my-component': httpVueLoader('my-component.vue')
},
...
回答by swift
David, that is a nice example, but what's the best way to make sure the DOM is compiled?
大卫,这是一个很好的例子,但确保 DOM 被编译的最佳方法是什么?
https://jsfiddle.net/q7xcbuxd/35/
https://jsfiddle.net/q7xcbuxd/35/
When I simulate an async operation, like in the example above, it works. But as soon as I load an external page "on the fly", Vue complains because the DOM is not ready.
More specifically:
Uncaught TypeError: Cannot set property 'vue' of undefined
Is there a better way to do this than to call $compile
when the page has loaded? I've tried with $mount
, but that didn't help.
当我模拟一个异步操作时,就像上面的例子一样,它可以工作。但是一旦我“即时”加载外部页面,Vue 就会抱怨,因为 DOM 还没有准备好。更具体地说:
有没有比在页面加载时调用更好的方法来做到这一点?我已经尝试过,但这没有帮助。Uncaught TypeError: Cannot set property 'vue' of undefined
$compile
$mount
UPDATE:Never mind, I finally figured out how to do it:
更新:没关系,我终于想出了怎么做:
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
});
});
});
And in the actual template, I removed the
在实际模板中,我删除了
<script id="someTemplate" type="text/x-template"></script>
tags and only included the html.
标签,只包含 html。
(This solution requires the http loader from https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.10/vue-resource.min.js)
(此解决方案需要来自https://cdnjs.cloudflare.com/ajax/libs/vue-resource/0.1.10/vue-resource.min.js的 http 加载器)
回答by ako977
1. In Vue 2.x I recommend sticking with convention by using .vue files but instead, inverting the order of imports:
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>
and in a separate file
并在一个单独的文件中
// src.js
export default {
name: 'helloworld',
props: {},
...
}
Then in your component registration
然后在您的组件注册中
import helloworld from './helloworld/template.vue'
new Vue({
components: {
'helloworld': helloworld
},
...})
This way you get the best of both worlds and you don't have to force yourself to build templates within a string.
通过这种方式,您可以两全其美,而不必强迫自己在字符串中构建模板。
2. If you want to lazy load, apparently there is a way to do so in Vue 2.x
2.如果你想延迟加载,显然在Vue 2.x中有一种方法可以做到
new Vue({
components: {
'helloworld': () => import(/* webpackChunkName: "helloworld" */ './helloworld/template.vue')
},
...})
This will load helloworld.js (which will contain all that component's code) on request of that page in the browser.
这将根据浏览器中该页面的请求加载 helloworld.js(它将包含所有该组件的代码)。
Of course, all the above assumes you are using ES6 with import
capabilities
当然,以上所有假设您使用具有import
功能的ES6
回答by Andriy Lach
I've tried http-vue-loaderand it works fine. This library is easy to use and has good documentation and examples
我试过http-vue-loader,它工作正常。这个库很容易使用并且有很好的文档和例子
Although you can't load templates from filed directly you still can keep html in separate single-file components. You can even skip <script>...</script>
part.
尽管您不能直接从文件中加载模板,但您仍然可以将 html 保存在单独的单文件组件中。你甚至可以跳过<script>...</script>
部分。
Usage (from loader's documentation)
用法(来自加载程序的文档)
my-component.vue
my-component.vue
<template>
<div class="hello">Hello {{who}}</div>
</template>
index.html
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>
Both files should be placed in one folder at the same level
两个文件应该放在同一个文件夹中
回答by Victor Bredihin
there are at least 2 ways to achieve what you want, on of them (x-templates) already mentioned by Bill Criswell, but I think it worth to add an example
至少有 2 种方法可以实现你想要的,其中(x 模板)已经被比尔克里斯威尔提到过,但我认为值得添加一个例子
Define your component like this
Vue.component('my-checkbox', { // id of x-template template: '#my-template' });
Add html file with your x-template (id should match the one you specified in the component)
<script type="text/x-template" id="my-template">...</script>
像这样定义你的组件
Vue.component('my-checkbox', { // id of x-template template: '#my-template' });
添加带有 x-template 的 html 文件(id 应与您在组件中指定的匹配)
<script type="text/x-template" id="my-template">...</script>
Another approach (and I like this one better) would be to use inline template
另一种方法(我更喜欢这个方法)是使用内联模板
Define your template like this
Vue.component('my-template', {});
Add html file with your component and template inside it
<my-template inline-template>place for your html</my-template>
像这样定义你的模板
Vue.component('my-template', {});
添加包含组件和模板的 html 文件
<my-template inline-template>place for your html</my-template>
Just don't forget to add inline-template
attribute, otherwise it won't work
只是不要忘记添加inline-template
属性,否则它将不起作用
回答by RaduM
Use browserify to bundle everything like this:
使用 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']));
回答by David K. Hess
You can use this approach with superagent:
您可以将此方法与超级代理一起使用:
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]);
});
Just put your <script>
tag based template inside of something.html
on your server.
只需将<script>
基于标签的模板something.html
放在您的服务器上。
If you are using jQuery, .loadshould work.
如果您使用 jQuery,.load应该可以工作。
Just make sure this completes before the DOM in question is compiled by Vue. Or use $mountto manually set things up.
只需确保在 Vue 编译有问题的 DOM 之前完成。或者使用$mount手动设置。