2017-05-31 84 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