如果要實(shí)現(xiàn)一個(gè)增刪辦事列表的功能处坪,在不引用外部庫(kù)與框架的情況下(不考慮兼容性),我們一般會(huì)寫(xiě)成下面這種形式架专。(輸入框輸入后同窘,按下Enter鍵后,更新列表部脚。)查看演示
<div>
<input id="input" />
<ul id="list">
<!-- <li>
<span></span>
<button>X</button>
</li> -->
</ul>
</div>
<script type="text/javascript">
var input = document.getElementById('input');
var list = document.getElementById('list');
function createNode(str) {
var div = document.createElement('div');
div.innerHTML = str;
return div.children[0];
}
var temp = '<li><span></span><button>X</button></li>'
input.addEventListener('keyup', function(event) {
if(event.keyCode == 13 && input.value) {
var newNode = createNode(temp);
list.appendChild(newNode);
var span = newNode.getElementsByTagName('span')[0];
var deleteBtn = newNode.getElementsByTagName('button')[0];
console.log(deleteBtn.parentNode);
span.innerText = input.value;
input.value = '';
deleteBtn.onclick = function() {
console.log(this.parentNode);
list.removeChild(this.parentNode);
};
}
});
</script>
使用Vue.js代碼可以寫(xiě)成下面的形式想邦。(使用Vue.js需下載引入vue.js文件)
<div id="app">
<input v-model="newTodo" v-on:keyup.enter="addTodo">
<ul>
<li v-for="todo in todos">
<span>{{ todo.text }}</span>
<button v-on:click="removeTodo($index)">X</button>
</li>
</ul>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{ text: 'Add some todos' }
]
},
methods: {
addTodo: function () {
var text = this.newTodo.trim()
if (text) {
this.todos.push({ text: text })
this.newTodo = ''
}
},
removeTodo: function (index) {
this.todos.splice(index, 1)
}
}
})
</script>
使用Vue寫(xiě)完最大的感受就是,整個(gè)過(guò)程沒(méi)有直接操作DOM委刘。只對(duì)數(shù)據(jù)進(jìn)行操作就可以控制頁(yè)面顯示丧没,并且,Vue對(duì)象層次劃分清晰锡移,比如上面骂铁,Vue對(duì)象里el選中容器,data存儲(chǔ)數(shù)據(jù)罩抗,methods定義方法。
然后我發(fā)現(xiàn)灿椅,學(xué)習(xí)可以使用下面方法:學(xué)習(xí)一個(gè)新東西套蒂,先不管懂不懂,對(duì)著示例把代碼碼一遍茫蛹,如果這個(gè)新工具是老工具的替代操刀,也要使用老的方法實(shí)踐一遍,然后進(jìn)行對(duì)比婴洼,就會(huì)對(duì)新工具有更直觀的感受骨坑。
對(duì)Vue體驗(yàn)過(guò)后,驚訝于它的簡(jiǎn)潔與強(qiáng)大,于是上網(wǎng)找能夠使用Vue的練習(xí)欢唾∏揖看到一個(gè)功能比較適合:添加書(shū)籍列表(沒(méi)有進(jìn)行數(shù)據(jù)檢測(cè)) 查看演示
以下是代碼:
<div id="book_store">
<table>
<thead><tr><td>書(shū)名</td><td>作者</td><td>價(jià)格</td><td>操作</td></tr></thead>
<tbody>
<tr v-for="item in list">
<td>{{ item.book_name }}</td>
<td>{{ item.author }}</td>
<td>{{ item.price }}</td>
<td><button v-on:click="removeBook($index)">刪除</button></td>
</tr>
</tbody>
</table>
<div>
<h3>添加書(shū)籍</h3>
<p><label>書(shū)名<input type="text" v-model="new_book.book_name"></label></p>
<p><label>作者<input type="text" v-model="new_book.author"></label></p>
<p><label>價(jià)格<input type="text" v-model="new_book.price"></label></p>
<button v-on:click="addBook">添加</button>
</div>
</div>
<script type="text/javascript" src="vue.js"></script>
<script type="text/javascript">
new Vue({
el: '#book_store',
data: {
new_book: null,
list: []
},
methods: {
addBook: function() {
var book_name = this.new_book.book_name.trim(),
author = this.new_book.author.trim(),
price = this.new_book.price.trim();
if(book_name && author && price) {
var book = {
book_name: book_name,
author: author,
price: price
}
this.list.push(book);
this.new_book = null;
}
},
removeBook: function(index) {
this.list.splice(index, 1);
}
}
});
</script>
運(yùn)行上面代碼會(huì)有警告,如圖
這是因?yàn)樵赿ata里我將new_book設(shè)置為了null礁遣,因此瀏覽器在渲染頁(yè)面的時(shí)候在data里找不到new_book.book_name等屬性斑芜,于是程序替我們創(chuàng)建了這些對(duì)象屬性并給出了警告。一個(gè)警告貌似無(wú)關(guān)緊要祟霍,但是在使用變量/屬性前最好將它初始化杏头。
關(guān)鍵字符:new Vue()、data沸呐、methods醇王、v-*、{{}}
上面命名方式有點(diǎn)不一致崭添,以后我將統(tǒng)一將變量使用下劃線_連接寓娩,函數(shù)命名使用駝峰形式。這樣名稱既清晰又能區(qū)別函數(shù)與變量滥朱。
在下一篇我會(huì)提一點(diǎn)響應(yīng)式相關(guān)的東西根暑。先簡(jiǎn)單介紹下,在使用new Vue(options)創(chuàng)建Vue對(duì)象的過(guò)程中徙邻,會(huì)vue.js遍歷該對(duì)象的data對(duì)象屬性排嫌,并將它們轉(zhuǎn)換為getter/setter以實(shí)現(xiàn)動(dòng)態(tài)跟蹤。而data對(duì)象也會(huì)從一個(gè)普通對(duì)象變成一個(gè)下面這種形式的對(duì)象:
由于構(gòu)建data對(duì)象的過(guò)程設(shè)計(jì)一系列復(fù)雜的操作缰犁,所以后續(xù)如果直接使用data.property給data添加屬性淳地,這個(gè)屬性并不會(huì)觸發(fā)視圖更新,因?yàn)樗鼪](méi)有被轉(zhuǎn)換為getter/setter帅容。如圖:
那么后續(xù)我們?nèi)绾谓odata添加新的觸發(fā)視圖更新的屬性呢颇象?后面會(huì)從Vue的源碼中找答案。