Vue.js Basic Learning 08 — Custom Components 101

拿上個 list 的範例來改寫成 component。步驟該有:

  1. 建立 template
  2. 宣告 component
  3. 套用 component
<div id="app">
<my-task :list="tasks"></my-task>
</div>
<template id="task-template">
<ul>
<div v-for="task in list">
<li :class="task.completed ? 'delete-me' : ''" @click="toggleDelete(task)">
{{ task.name }}
</li>
</div>
</ul>
</template>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript">
Vue.component('my-task', {
template: '#task-template',
props: ['list'],
methods: {
toggleDelete: function(task) {
task.completed = !task.completed;
}
}
})
new Vue({
el: '#app',
data: {
tasks: [
{name: "Go to the store", completed: false},
{name: "Go to the bank", completed: false},
{name: "Go to the doctor", completed: true}
]
}
});
</script>

以上和之前的範例沒有新的變化,但與影片中講者最後示範了多增加一個 component,但差別是他的資料不由 Vue data 來,而是直接在 <my-task> 中餵入陣列:

<my-task :list="[{name:'Go to a movie', completed: false}]"></my-task>

在影片範例中用的 Vue 版號是 1.0.8,新產生的 list 依舊有 toggle delete的功能,但用了最新版 (^2.0)之後卻只能呈現,click 事件無效。可以切換兩個版本看看:

<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/vue/1.0.8/vue.js"></script>

查看 console.log 後發現,其實事件是有觸發,也有取得傳進來的 task ,但若是直接在 method 中 console.log(task),可以觀察到一般的 data 資料和直接寫在 my-task 上的資料在 log 中看起來是不同的:

第一個 log 是 click “Go to a movie” 而來的,是原生的 javascript 物件資料。而第二個 log 雖然沒有展開,但是他大概是 Vue 的實例物件。

再參考一下 Vue 的 change log 發現由元件產生出來的內容,以往是 two way binding 而在 2.0 開始改為 one way binding,目的是不讓某一 child 影響 parent。同樣在之前的範例影片講者也有介紹到 sync:可以讓 child 的變化跟新回 parent,同樣在 2.0 已經 deprecated:

v-bind:plan=“plan”.sync

詳情可參考官方對 One way data flow 的說明: