1. 修改sample-grid的template
<template> <!--...已省略--> <tbody> <tr v-for="(index,entry) in dataList | filterBy searchKey"> <td v-for="col in columns"> <span v-if="col.isKey"><a href="javascript:void(0)" @click="openEditItemDialog(index, 'Edit item ' + entry[col.name])">{{entry[col.name]}}</a></span> <span v-else>{{entry[col.name]}}</span> </td> </tr> </tbody> <!--...已省略--> <modal-dialog :mode="mode" :title="title" :item="item" :fields="columns" v-on:create-item="createItem" v-on:update-item="updateItem"> </modal-dialog> </template>遍历列表数据时,使用v-if指令判断当前列是否为主键列,如果是主键列,则给主键列添加链接,然后给链接绑定click事件,click事件用于打开修改数据的对话框。
在<modal-dialog>标签上,给sample-grid绑定自定义事件update-item,update-item事件指向sample-grid的方法updateItem。
2. 修改modal-dialog的template
<div v-for="field in fields"> <label>{{ field.name }}</label> <select v-if="field.dataSource" v-model="item[field.name]" :disabled="mode === 2 && field.isKey"> <option v-for="opt in field.dataSource" :value="opt">{{ opt }}</option> </select> <input v-else type="text" v-model="item[field.name]" :disabled="mode === 2 && field.isKey"> </div>在修改模式下(mode = 2),如果当前字段是主键字段,则禁止修改。
3. 修改sample-grid的methods选项
Vue.component('simple-grid', {
// ...已省略
methods: {
openEditItemDialog: function(index, title) {
// 对话框的标题
this.title = title
// mode = 2表示修改模式
this.mode = 2
// 初始化this.item
this.item = {}
// 将选中行的数据拷贝到this.item
for (var i in this.dataList[index]) {
this.item[i] = this.dataList[index][i]
}
// 广播事件,传入参数true表示显示对话框
this.$broadcast('showDialog', true)
},
getKeyColumn: function() {
for (var i = 0; i < this.columns.length; i++) {
if (this.columns[i].isKey) {
return this.columns[i].name
}
}
},
updateItem: function() {
// 获取主键列
var keyColumn = this.getKeyColumn()
for (var i = 0; i < this.dataList.length; i++) {
// 根据主键查找要修改的数据,然后将this.item数据更新到this.dataList[i]
if (this.dataList[i][keyColumn] === this.item[keyColumn]) {
for (var j in this.item) {
this.dataList[i][j] = this.item[j]
}
break;
}
}
// 广播事件,传入参数false表示隐藏对话框
this.$broadcast('showDialog', false)
// 修改完数据后,重置item对象
this.item = {}
}
}
// ...已省略
})
追加了3个方法:openEditDialog,getKeyColumn和updateItem。
opeEditItemDialog方法用于打开对话框,this.$broadcast('showDialog', true) 调用子组件modal-dialog的showDialog事件,传入参数true表示显示对话框。
getKeyColumn方法用于获取主键列,调用updateItem方法时,会根据主键数据找到dataList中匹配的元素。
updateItem方法用于保存修改的数据,this.$broadcast('showDialog', false) 调用子组件modal-dialog的showDialog事件,传入参数false表示隐藏对话框。
4.修改modal-dialog的methods选项
save: function() { //新建模式 if (this.mode === 1) { // 使用$dispatch调用simple-grid的create-item事件 this.$dispatch('create-item') }else if(this.mode === 2){ // 使用$dispatch调用simple-grid的update-item事件 this.$dispatch('update-item') } }修改methods选项中的save方法,this.mode === 2时,将事件派发到父组件的update-item事件。
第5步——修改数据新建功能View Demo
修改sample-grid的methods选项,追加itemExists方法,然后修改createItem方法。
itemExists: function(keyColumn) { for (var i = 0; i < this.dataList.length; i++) { if (this.item[keyColumn] === this.dataList[i][keyColumn]) return true; } return false; }, createItem: function() { var keyColumn = this.getKeyColumn() if (!this.itemExists(keyColumn)) { // 将item追加到dataList this.dataList.push(this.item) // 广播事件,传入参数false表示隐藏对话框 this.$broadcast('showDialog', false) // 新建完数据后,重置item对象 this.item = {} } else { alert(keyColumn + ' "' + this.item[keyColumn] + '" is already exists') } }由于主键列数据是不能重复的,所以在新增数据时需要判断主键列数据是否已经存在。
总结说到底,组件的API主要来源于以下三部分:
这三大知识点在上下两篇文章中都体现出来了,限于篇幅和个人知识的匮乏,我并不能将组件的所有特性都描述出来,这还需要靠各位花一些时间去多多了解官网的API,并付诸实践。
如果要构建一些大型的应用,基于组件的开发模式是一个不错的选择,我们将整个系统拆分成一个一个小组件,就像乐高一样,然后将这些组件拼接起来。