Vue.js使用-组件示例(实现数据的CRUD)
2018-01-31 19:37
1316 查看
1.业务场景
用户(姓名,年龄,性别)的增删改查
2.数据格式
定义字段,name:字段名称,iskey:是否主键(添加,修改数据标志),dataSource:可选列表(下拉框选项)
定义数据,用户信息列表
3.组件定义
我们需要定义两个组件,表格显示组件,信息维护组件。
4.表格显示组件
运行结果:
定义了一个simple-grid组件,将Vue对象中的columns,peoples属性值绑定到组件,表头使用columns属性值,数据列使用peoples属性值。
deleteItem方法,用来删除peoples对应的元素。
5.信息维护组件
表格组件实现了数据的查询和删除,添加和修改要通过信息维护组件来实现。
把信息维护组件作为表格组件的子组件,来实现表格和弹窗数据的交互,事件的传递。
1)新增
运行结果:
弹窗组件modal-dialog定义了一个show属性,v-bind:class="{'dialog-active':show},show为false时隐藏,true显示弹窗。
子组件使用了父组件的mode,fields,item,title四个属性。
mode:1-新增,2-修改
fields:父组件的columns属性,用来显示需要维护的字段
item:新添加的数据对象
title:弹窗title(新增or修改)
点击父组件创建按钮openItemDialog时,会将showDialog事件broadcast到子组件。
showDialog完成弹窗的显示隐藏
modal-dialog组件的template,#dialog-template绑定了新数据对象item,维护完毕,点击保存按钮时,触发save方法,将保存事件派发到父组件处理。
create_item绑定了父组件的createItem方法
createItem中将新的数据对象添加到数据列表,广播showDialog事件到子组件,关闭弹窗,添加数据完毕。
2)修改
运行结果:
数据使用iskey标志主键,更新时,editItemDialog中使用findItemByKey根据主键找到要修改的数据,赋给item属性(供子组件使用),
然后broadcast广播showDialog事件,子组件接收到showDialog通知后,显示弹窗。
点击保存按钮时,调用save方法,将update_item事件派发到父组件
父组件中将item更新到数据列表peoples,需要注意的是,在findItemByKey方法时,需要使用深度拷贝,将数据对象赋给item,而不是直接将数据对象的引用赋给item,
这样当子组件中model属性值更新时,无论是否点击保存按钮,表格组件中对应的值都会变化。或者使用单次绑定v-bind:name.once。
6.其他
源码地址如下:
https://github.com/shijingjing07/vue_demo
还实现了根据关键字查找,防止主键重复等功能。
用户(姓名,年龄,性别)的增删改查
2.数据格式
定义字段,name:字段名称,iskey:是否主键(添加,修改数据标志),dataSource:可选列表(下拉框选项)
columns: [{name: 'name', iskey: true}, {name: 'age'},{name: 'sex', dataSource:['Male', 'Female']}],
定义数据,用户信息列表
peoples: [{name: 'shijingjing', age: 30, sex:'Male'},{name: 'renjiangfeng', age:29, sex:'Female'}]
3.组件定义
我们需要定义两个组件,表格显示组件,信息维护组件。
4.表格显示组件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="styles/index.css"> </head> <body> <div id="app"> <div class="container"> <simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid> </div> </div> <template id="grid-template"> <table> <tr> <th v-for="column in columns">{{ column.name | capitalize }}</th> <th>Delete</th> </tr> <tr v-for="people in peoples"> <td v-for="column in columns"> <span>{{ people[column.name] }}</span> </td> <td style="text-align: center"><button class="btn-delete" v-on:click="deleteItem(people)">delete</button></td> </tr> </table> </template> </body> <script src="js/vue.js"></script> <script> Vue.component( 'simple-grid',{ template: '#grid-template', props: ['peoples', 'columns'], methods: { deleteItem: function (people) { for(var i=0;i<this.peoples.length;i++){ if(this.peoples[i] == people){ this.peoples.splice(i, 1); return } } } } } ) new Vue({ el: '#app', data: { columns: [{name: 'name', iskey: true}, {name: 'age'},{name: 'sex', dataSource:['Male', 'Female']}], peoples: [{name: 'shijingjing', age: 30, sex:'Male'},{name: 'renjiangfeng', age:29, sex:'Female'}] } }) </script> </html>
运行结果:
定义了一个simple-grid组件,将Vue对象中的columns,peoples属性值绑定到组件,表头使用columns属性值,数据列使用peoples属性值。
deleteItem方法,用来删除peoples对应的元素。
5.信息维护组件
表格组件实现了数据的查询和删除,添加和修改要通过信息维护组件来实现。
把信息维护组件作为表格组件的子组件,来实现表格和弹窗数据的交互,事件的传递。
1)新增
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="styles/index.css"> </head> <body> <div id="app"> <div class="container"> <simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid> </div> </div> <template id="grid-template"> <table> <tr> <th v-for="column in columns">{{ column.name | capitalize }}</th> <th>Delete</th> </tr> <tr v-for="people in peoples"> <td v-for="column in columns"> <span>{{ people[column.name] }}</span> </td> <td style="text-align: center"><button class="btn-delete" v-on:click="deleteItem(people)">delete</button></td> </tr> </table> <div class="container"> <button v-on:click="openItemDialog('创建')">创建</button> </div> <modal-dialog v-bind:mode="mode" v-bind:title="title" v-bind:item="item" v-bind:fields="columns" v-on:create_item="createItem"></modal-dialog> </template> <template id="dialog-template"> <div class="dialog" v-bind:class="{'dialog-active':show}"> <div class="dialog-header">{{ title }}</div> <div class="dialog-body"> <div v-for="field in fields" class="form-group"> <label>{{ field.name }}</label> <input type="text" v-model="item[field.name]"> </div> </div> <div class="dialog-footer"> <div class="form-group"> <label></label> <button class="btn-save" v-on:click="save">保存</button> <button class="btn-close" v-on:click="close">关闭</button> </div> </div> </div> <div class="dialog-overlay"></div> </template> </body> <script src="js/vue.js"></script> <script> Vue.component( 'simple-grid',{ template: '#grid-template', data: function () { return{ mode: 0, title: '', item: {}, } }, props: ['peoples', 'columns', 'search'], methods: { openItemDialog:function (title) { this.title = title; this.mode = 1; this.item = {}; this.$broadcast('showDialog', true); }, deleteItem: function (people) { for(var i=0;i<this.peoples.length;i++){ if(this.peoples[i] == people){ this.peoples.splice(i, 1); return } } }, createItem: function () { this.peoples.push(this.item); this.$broadcast("showDialog", false); this.item = {}; } }, components:{ 'modal-dialog':{ template: '#dialog-template', data: function () { return { show: false } }, props: ['mode', 'fields', 'item', 'title'], methods:{ close:function () { this.show = false; }, save:function () { if(this.mode ==1){ this.$dispatch('create_item'); } } }, events:{ 'showDialog': function (show) { this.show = show } } } } } ) new Vue({ el: '#app', data: { columns: [{name: 'name'}, {name: 'age'}], peoples: [{name: 'shijingjing', age: 30},{name: 'renjiangfeng', age:29}] } }) </script> </html>
运行结果:
弹窗组件modal-dialog定义了一个show属性,v-bind:class="{'dialog-active':show},show为false时隐藏,true显示弹窗。
子组件使用了父组件的mode,fields,item,title四个属性。
mode:1-新增,2-修改
fields:父组件的columns属性,用来显示需要维护的字段
item:新添加的数据对象
title:弹窗title(新增or修改)
点击父组件创建按钮openItemDialog时,会将showDialog事件broadcast到子组件。
events:{ 'showDialog': function (show) { this.show = show } }
showDialog完成弹窗的显示隐藏
modal-dialog组件的template,#dialog-template绑定了新数据对象item,维护完毕,点击保存按钮时,触发save方法,将保存事件派发到父组件处理。
save:function () { if(this.mode ==1){ this.$dispatch('create_item'); } }
create_item绑定了父组件的createItem方法
v-on:create_item="createItem"
createItem中将新的数据对象添加到数据列表,广播showDialog事件到子组件,关闭弹窗,添加数据完毕。
createItem: function () { this.peoples.push(this.item); this.$broadcast("showDialog", false); this.item = {}; }
2)修改
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="styles/index.css">
</head>
<body>
<div id="app">
<div class="container">
<simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid>
</div>
</div>
<template id="grid-template">
<table>
<tr>
<th v-for="column in columns">{{ column.name | capitalize }}</th>
<th>Delete</th>
</tr>
<tr v-for="people in peoples | filterBy search">
<td v-for="column in columns">
<span v-if="column.iskey">
<a href="javascript:void(0)" v-on:click="editItemDialog(people[column.name])">{{ people[column.name] }}</a>
</span>
<span v-else>{{ people[column.name] }}</span>
</td>
<td style="text-align: center"><button class="btn-delete" v-on:click="deleteItem(people)">delete</button></td>
</tr>
</table>
<modal-dialog v-bind:mode="mode" v-bind:title="title" v-bind:item="item" v-bind:fields="columns" v-on:create_item="createItem" v-on:update_item="updateItem"></modal-dialog>
</template>
<template id="dialog-template">
<div class="dialog" v-bind:class="{'dialog-active':show}">
<div class="dialog-header">{{ title }}</div>
<div class="dialog-body">
<div v-for="field in fields" class="form-group">
<label>{{ field.name }}</label>
<input type="text" v-model="item[field.name]" v-bind:disabled="mode ==2 && field.iskey">
</div>
</div>
<div class="dialog-footer">
<div class="form-group">
<label></label>
<button class="btn-save" v-on:click="save">保存</button>
<button class="btn-close" v-on:click="close">关闭</button>
</div>
</div>
</div>
<div class="dialog-overlay"></div>
</template>
</body>
<script src="js/vue.js"></script>
<script>
Vue.component(
'simple-grid',{
template: '#grid-template',
data: function () {
return{
mode: 0,
title: '',
item: {},
keyColumn: ''
}
},
ready: function () {
for(var i=0;i<this.columns.length;i++){
if(this.columns[i].iskey){
this.keyColumn = this.columns[i].name;
break;
}
}
},
props: ['peoples', 'columns', 'search'],
methods: {
editItemDialog: function (key) {
this.title ='修改-' + key;
this.mode = 2;
var currItem = this.findItemByKey(key);
console.log(currItem)
this.item = currItem;
this.$broadcast('showDialog', true);
},
deleteItem: function (people) {
for(var i=0;i<this.peoples.length;i++){
if(this.peoples[i] == people){
this.peoples.splice(i, 1);
return
}
}
},
updateItem: function () { for(var i=0;i<this.peoples.length;i++){ if(this.peoples[i][this.keyColumn] == this.item[this.keyColumn]){ for(var key in this.item){ this.peoples[i][key] = this.item[key]; } break; } } this.$broadcast('showDialog', false); this.item = {}; },
findItemByKey: function (key) {
for(var i=0; i<this.peoples.length;i++){
if(this.peoples[i].name == key){
return this.peoples[i];
}
}
}
},
components:{
'modal-dialog':{
template: '#dialog-template',
data: function () {
return {
show: false
}
},
props: ['mode', 'fields', 'item', 'title'],
methods:{
close:function () {
this.show = false;
},
save:function () { if(this.mode ==1){ this.$dispatch('create_item'); } else if(this.mode == 2){ this.$dispatch('update_item'); } }
},
events:{ 'showDialog': function (show) { this.show = show } }
}
}
}
)
new Vue({
el: '#app',
data: {
columns: [{name: 'name', iskey: true}, {name: 'age'}],
peoples: [{name: 'shijingjing', age: 30},{name: 'renjiangfeng', age:29}]
}
})
</script>
</html>
运行结果:
数据使用iskey标志主键,更新时,editItemDialog中使用findItemByKey根据主键找到要修改的数据,赋给item属性(供子组件使用),
然后broadcast广播showDialog事件,子组件接收到showDialog通知后,显示弹窗。
点击保存按钮时,调用save方法,将update_item事件派发到父组件
save:function () { if(this.mode ==1){ this.$dispatch('create_item'); } else if(this.mode == 2){ this.$dispatch('update_item'); } }
父组件中将item更新到数据列表peoples,需要注意的是,在findItemByKey方法时,需要使用深度拷贝,将数据对象赋给item,而不是直接将数据对象的引用赋给item,
这样当子组件中model属性值更新时,无论是否点击保存按钮,表格组件中对应的值都会变化。或者使用单次绑定v-bind:name.once。
updateItem: function () { for(var i=0;i<this.peoples.length;i++){ if(this.peoples[i][this.keyColumn] == this.item[this.keyColumn]){ for(var key in this.item){ this.peoples[i][key] = this.item[key]; } break; } } this.$broadcast('showDialog', false); this.item = {}; },
6.其他
源码地址如下:
https://github.com/shijingjing07/vue_demo
还实现了根据关键字查找,防止主键重复等功能。
相关文章推荐
- 使用Bootstrap + Vue.js实现添加删除数据示例
- vue.js使用v-model指令实现的数据双向绑定功能示例
- vue.js实现请求数据的方法示例
- vue.js 使用axios实现下载功能的示例
- vue组件Prop传递数据的实现示例
- Vue.js分页组件实现:diVuePagination的使用详解
- vue.js通过子组件通信和父子组件通信实现动态表单动态绑定事件(适合交互系统统一使用)
- Vue.js实现一个漂亮、灵活、可复用的提示组件示例
- vue.js使用v-if实现显示与隐藏功能示例
- 使用vue.js实现联动效果的示例代码
- 在Vue中使用sortable.js实现拖动效果并保存拖动数据
- Vue 中使用vue2-highcharts实现曲线数据展示示例
- vue2.0使用swiper组件实现轮播的示例代码
- vue.js项目 el-input 组件 监听回车键实现搜索功能示例
- Vue 中使用vue2-highcharts实现实时曲线数据展示示例
- Vue结合原生js实现自定义组件自动生成示例
- vue2.0使用Sortable.js实现的拖拽功能示例
- 使用Bootstrap + Vue.js实现 添加删除数据
- 不使用jquery实现js打字效果示例分享
- jquery滚动组件(vticker.js)实现页面动态数据的滚动效果