2017-05-31 85 views
1

我希望对某人来说这是一个微不足道的问题,我只是想念一小段代码:我从knockout.js迁移到vue.js,我想知道是否有简单在vue.js中以与knockout.js中相同的方式使用模板。剪断下面的代码使用knockout.js和按预期工作:使用模板清晰分离视图和代码使用Vue

function viewmodel() { 
 
    this.person = ko.observable(new person()); 
 
} 
 
function person() { 
 
    this.first = ko.observable('hello'); 
 
    this.last = ko.observable('world'); 
 
} 
 
ko.applyBindings(new viewmodel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<script type="text/html" id="person-template"> 
 
    <p data-bind="text: first"/> 
 
    <p data-bind="text: last"/> 
 
</script> 
 
<div> 
 
    <div data-bind="template: { name: 'person-template', data: person }"/> 
 
</div>

然而,我无法弄清楚如何达到同样的vue.js。我知道vue.js和所有这些组件,但我希望保持原样,并且不要将更多特定于视图的代码放入我的JavaScript文件中。 (我已经不愉快的el: '#app',但是这是目前我最关注的)当然,这个代码不工作:

var app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
     person: { 
 
      first: 'hello', 
 
      last: 'world' 
 
     } 
 
    } 
 
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script> 
 

 
<script type="text/x-template" id="person-template"> 
 
    <p v-text="first"/> 
 
    <p v-text="last"/> 
 
</script> 
 
<div id="app"> 
 
    <div><!-- how? is this even possible? --></div> 
 
</div>

有没有办法得到这个工作通过只改变代码的HTML部分?最好只有<div> -Element。

回答

4

所以这不是只有改变模板,但一个额外的属性可以在这里工作。在Vue中指定一个模板。

var app = new Vue({ 
    el: '#app', 
    template: "#person-template", 
    data: { 
     person: { 
      first: 'hello', 
      last: 'world' 
     } 
    } 
}); 

我也稍微修改了你的模板,因为任何Vue或组件的模板都需要一个根元素。我建议你做而不是在Vue中使用自闭标签,因为我已经看到了这个原因。 Vue需要有效的HTML5和self closing tags are not valid HTML5

<script type="text/x-template" id="person-template"> 
    <div> 
    <p v-text="person.first"></p> 
    <p v-text="person.last"></p> 
    </div> 
</script> 

工作example

此外,以这种方式指定模板的一种非常常见的方式,不使用那种hacky script标记就是使用HTML5 template element

<template id="person-template"> 
    <div> 
    <p v-text="person.first"></p> 
    <p v-text="person.last"></p> 
    </div> 
</template> 

最后,知道你是略有不悦el:"#app"可以离开el地产出的Vue公司的定义和使用方法$mount安装的Vue您选择的元素。所以如果你想完全不顾一切的担忧,你可以做这样的事情。

const renderer = Vue.compile(document.querySelector("#person-template").innerHTML) 
const example = { 
    data: { 
     person: { 
      first: 'hello', 
      last: 'world' 
     } 
    } 
} 
const app = new Vue(Object.assign({}, example, renderer)) 
app.$mount("#app") 

Example

我应该提到没有人真的这样做(编译他们的模板手动,这是通常使用$挂载),我知道。它还取决于使用包含编译器的Vue版本(如果您使用的是webpack或其他一些构建工具,则可能没有这个版本)。你也可以做这样的事情:

const app = new Vue(Object.assign({}, example, {template: "#person-template"})) 
app.$mount("#app") 

它们基本上将允许你指定一个模板,组件和安装它all separately的地方。

+0

@NumLock所以,我有几个想法,并在接受答案后添加它们。只是FYI。 – Bert

+0

谢谢。我非常感谢所有的努力。我目前正试图掌握在模板内直接引用'person'而不仅仅是其属性的含义。用我的KO例子,我可以重新使用这个模板来创建基本上具有这两个属性的所有东西。至少现在(根据我目前的理解),我只卸载了如何渲染人物而不是定义(可重复使用的)模板 –

+0

@NumLock您总是可以定义一个只渲染人物的人物组件。 – Bert