Vue.js使用-组件示例(实现数据的CRUD)

vue

1.业务场景

用户(姓名,年龄,性别)的增删改查

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 >

<div class="container">

<simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid>

</div>

</div>

<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" title="vue.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 >

<div class="container">

<simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid>

</div>

</div>

<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 >

<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 >

<div class="container">

<simple-grid v-bind:columns="columns" v-bind:peoples="peoples"></simple-grid>

</div>

</div>

<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 >

<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

还实现了根据关键字查找,防止主键重复等功能。

以上是 Vue.js使用-组件示例(实现数据的CRUD) 的全部内容, 来源链接: utcz.com/z/378872.html

回到顶部