![](/img/trans.png)
[英]Angularjs templating: model and function stop working in external templates?
[英]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 的作者写了一篇关于外部模板 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>
两个文件应该放在同一个文件夹中
// 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
},
...})
通过这种方式,您可以两全其美,而不必强迫自己在字符串中构建模板。
new Vue({
components: {
'helloworld': () => import(/* webpackChunkName: "helloworld" */ './helloworld/template.vue')
},
...})
这将根据浏览器中该页面的请求加载 helloworld.js(它将包含所有该组件的代码)。
当然,以上所有假设您使用具有import
功能的 ES6
至少有 2 种方法可以实现你想要的,其中(x 模板)已经被 Bill Criswell 提到过,但我认为值得添加一个例子
像这样定义你的组件
Vue.component('my-checkbox', { // id of x-template template: '#my-template' });
添加带有 x-template 的 html 文件(id 应与您在组件中指定的匹配)
<script type="text/x-template" id="my-template">...</script>
另一种方法(我更喜欢这个方法)是使用内联模板
像这样定义你的模板
Vue.component('my-template', {});
添加包含组件和模板的 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.