在管理员的一些后台页面里,我的中内心的数据列表里,都会有对这些数据进行增删改查的操做。好比在管理员后台的用户列表里,咱们能够录入新用户的信息,也能够对既有的用户信息进行修改。在vue中,咱们更应该专一于对数据的操做和处理。javascript
好比咱们有一个这样的页面:html
咱们在这个页面里,就实现了增删改查4个功能,点击连接查看demo【http://www.xiabingbao.com/demo/vue-curd/index.html】。vue
咱们把这些用户信息保存到list
的数组中,而后增删改查就在这个数组上进行:java
list: [ { username: 'aaaaa', email: '123@qq.com', sex: '男', province: '北京市', hobby: ['篮球', '读书', '编程'] }, { username: 'bbbbb', email: 'bbbbbbb@163.com', sex: '女', province: '河北省', hobby: ['弹琴', '读书', '插画'] } // ... ]
设置这些数据主要也是复习一下vue对表单的处理操做,这里面的表单有:文本输入框,单选按钮,select选择框,复选框等。编程
咱们的数据都放在数组list
中,可是这里并不直接对list对循环输出,而是先把list中的数据给一个数组slist
,对slist
进行循环输出。由于咱们在后面的查询功能中须要对数据进行过滤,数组list一直保存着原始数据(包括新增、修改后或已删除后),而数组slist只负责展现。数组
在vue中提供一个setSlist
方法,将须要展现的数据给了数组slist:ide
// 获取须要渲染到页面中的数据 setSlist(arr) { this.slist = JSON.parse(JSON.stringify(arr)); }
而后在html中使用v-for
把slist数组渲染出来:ui
<tr v-cloak v-for="(item, index) of slist"> <td>{{index+1}}</td> <td>{{item.username}}</td> <td>{{item.email}}</td> <td>{{item.sex}}</td> <td>{{item.province}}</td> <td>{{item.hobby.join(' | ')}}</td> <td><a href="javascript:;" @click="showOverlay(index)">修改</a> | <a href="javascript:;" @click="del(index)">删除</a></td> </tr>
在操做这一栏中,给修改和删除操做绑定上事件。this
把增长功能和删除合并到一块儿,是这两个功能相对来讲都比较简单。code
增长用户时使用push
方法,把用户的信息添加到list
数组的最后:
this.list.push({ username: 'ffff', email: 'fffffff@163.com', sex: '女', province: '河南省', hobby: ['弹琴', '插画'] });
这样就能添加一位ffff的用户了。
删除用户时,经过splice(index, 1)
,能够删除index位置的数据,页面上的数据自动就会更新。
当咱们想要修改某个元素时,能够把这个位置上的数据取出来放到弹层里(或者其余某个位置),在弹层里的信息能够取消或者修改后进行保存。
假设咱们弹层里的数据是selectedlist
,那么每次修改时,把index位置的数据给了selectedlist,而后在弹层中修改selectedlist。咱们也能看到修改数据的类型: 文本框(用户名,邮箱),单选按钮(性别),select选择框(所在省份),多选框(爱好),这里咱们主要练习的是表单处理(https://cn.vuejs.org/v2/guide/forms.html)。弹层是否显示用变量isActive
来控制:
// 修改数据 modifyData(index) { this.selected = index; // 修改的位置 this.selectedlist = this.list[index]; this.isActive = true; }
有没有发现一个问题,当修改弹层中的信息时,表格中的数据也同步更新了。但是咱们自己是但愿当点击保存按钮时,才把弹层中的数据保存到表格里。问题的根源就出在这里:
this.selectedlist = this.list[index];
由于list[index]
是个Object类型的数据,若使用=赋值,则赋值操做为浅度拷贝(把数据的地址赋值给对应变量,而没有把具体的数据复制给变量,变量会随数据值的变化而变化),selectedlist与list[index]使用相同的数据地址,互相引发数据值的变化。所以这里咱们须要进行深度拷贝:
this.selectedlist = JSON.parse( JSON.stringify(this.list[index]) ); // 先转换为字符串,而后再转换
当用户修改数据后,selectedlist就会发生变化,点击保存按钮时,将数据从新保存到index位置:
/* this.list 数据数组 this.selected 刚才修改的位置 this.selectedlist 须要保存的数据 */ Vue.set(this.list, this.selected, this.selectedlist);
在第1小节中咱们已经说过,在页面表格中展现的是slist
中的数据,就是为了方便执行查询操做:
// 获取须要渲染到页面中的数据 setSlist(arr) { this.slist = JSON.parse(JSON.stringify(arr)); }
每次根据某些条件将过滤后的数据赋值给slist数组,展现出查询后的数据。这里咱们的查询实现了两个小功能:
这里咱们经过用户名和邮箱进行查询,所以在过滤数据时,须要检测用户名和邮箱是否含有查询的单词。咱们先给输入框绑定一个input事件,同时用datalist展现用户可能要查询的词语:
<input type="text" placeholder="search" @input="search" list="cars" class="search"> <datalist id="cars"> <option v-for="item in searchlist" :value="item"></option> </datalist>
search功能的实现,searchlist
为在输入框下方展现的可能要搜索的词语,ss
数组则保存过滤后的数据,当循环完毕后,设置调用setSlist
方法修改slist数组:
// 搜索 search(e) { var v = e.target.value, self = this; self.searchlist = []; if (v) { var ss = []; // 过滤须要的数据 this.list.forEach(function (item) { // 检测用户名 if (item.username.indexOf(v) > -1) { if (self.searchlist.indexOf(item.username) == -1) { self.searchlist.push(item.username); } ss.push(item); } else if (item.email.indexOf(v) > -1) { // 检测邮箱 if (self.searchlist.indexOf(item.email) == -1) { self.searchlist.push(item.email); } ss.push(item); } }); this.setSlist(ss); // 将过滤后的数据给了slist } else { // 没有搜索内容,则展现所有数据 this.setSlist(this.list); } }
每当用户输入或者删除一个字符时都会调用search方法,执行查询操做,当用点击展现词语列表时,也会调用search方法。
其实咱们应该发现,修改功能(或新增功能)从代码和样式上相对来讲比较独立,咱们把弹层独立为组件的形式,把须要修改的数据经过props
传递给该组件(新增数据时,能够给组件传递一个空数据),当用户点击保存时,再经过$emit
给了父组件(子组件不能直接父级的数据,须要用data或者computed生成一个局部变量,而后再使用$emit方法把这个局部数据再传递上去):
// 弹层组件 Vue.component('model', { props: ['list', 'isactive'], template: `<div class="overlay" v-show="isactive"> <div class="con"> <h2 class="title">新增 | 修改</h2> <div class="content"> https://www.xiabingbao.com/vue/2017/07/10/vue-curd.html </div> </div> </div>`, computed: { modifylist() { return this.list; } }, methods: { changeActive() { this.$emit('change'); // 关闭弹层,修改isactive值 }, modify() { this.$emit('modify', this.modifylist); // 将修改后的数据传递给父组件 } } });
父组件,在父组件中截取change
和modify
事件,再用changeOverlay
和modify
来实现:
<model :list='selectedlist' :isactive="isActive" v-cloak @change="changeOverlay" @modify="modify"></model> <!-- 博客园 -->
洋洋洒洒写了很多,其实里面的难点不太多,主要是form表单方面的操做,再一个就是练习下组件间的数据与事件传递。内容比较简单,欢迎各位批评指正。
原文地址:https://www.xiabingbao.com/vue/2017/07/10/vue-curd.html