1 [v-cloak]{display:none}
2 table{border:1px solid #ccc;padding:0;border-collapse:collapse;table-layout:fixed;margin-top:10px;width:100%}
3 table td,table th{height:30px;border:1px solid #ccc;background:#fff;font-size:15px;padding:3px 3px 3px 8px}
4 table th:first-child{width:30px}
5 .container{width:800px;margin:10px auto 0;font-size:13px;font-family:'Microsoft YaHei'}
6 .container .search{font-size:15px;padding:4px}
7 .container .add{padding:5px 15px}
8 .overlay{position:fixed;top:0;left:0;width:100%;height:100%;z-index:6;background:rgba(0,0,0,.7)}
9 .overlay td:first-child{width:66px}
10 .overlay .con{position:absolute;width:420px;min-height:300px;background:#fff;left:50%;top:50%;-webkit-transform:translate3d(-50%,-50%,0);transform:translate3d(-50%,-50%,0);padding:20px}
1 <div class="container" id="app"> 2 <div> 3 <input type="text" placeholder="search" @input="search" list="cars" class="search" /> 4 <datalist id="cars"> 5 <option v-for="item in searchlist" :value="item"></option> 6 </datalist> 7 <input type="button" class="add" @click="add" value="新增" /> 8 </div> 9 <div> 10 <table> 11 <tr> 12 <th>id</th> 13 <th>用户名</th> 14 <th>邮箱</th> 15 <th>性别</th> 16 <th>省份</th> 17 <th>爱好</th> 18 <th>操作</th> 19 </tr> 20 <tr v-cloak v-for="(item, index) of slist"> 21 <td>{{ index + 1 }}</td> 22 <td>{{ item.username }}</td> 23 <td>{{ item.email }}</td> 24 <td>{{ item.sex }}</td> 25 <td>{{ item.province }}</td> 26 <td>{{ item.hobby.join(' | ') }}</td> 27 <td> 28 <a href="javascript:;" @click="showOverlay(index)">修改</a> | 29 <a href="javascript:;" @click="del(index)">删除</a> 30 </td> 31 </tr> 32 </table> 33 </div> 34 <model :list="selectedlist" :isactive="isActive" v-cloak @change="changeOverlay" @modify="modify"></model> 35 </div> 36 javascript代码:
1 Vue.component('model', { 2 props: ['list', 'isactive'], 3 template: `<div class="overlay" v-show="isactive"> 4 <div class="con"> 5 <h2 class="title">新增 | 修改</h2> 6 <div class="content"> 7 <table> 8 <tr> 9 <td>用户名</td> 10 <td><input type="text" v-model="modifylist.username"></td> 11 </tr> 12 <tr> 13 <td>邮箱</td> 14 <td><input type="text" v-model="modifylist.email"></td> 15 </tr> 16 <tr> 17 <td>性别</td> 18 <td> 19 <label><input type="radio" name="sex" value="男" v-model="modifylist.sex">男</label> 20 <label><input type="radio" name="sex" value="女" v-model="modifylist.sex">女</label> 21 <label><input type="radio" name="sex" value="未知" v-model="modifylist.sex">未知</label> 22 </td> 23 </tr> 24 <tr> 25 <td>省份</td> 26 <td> 27 <select name="" id="" v-model="modifylist.province"> 28 <option value="北京市">北京市</option> 29 <option value="河北省">河北省</option> 30 <option value="河南省">河南省</option> 31 <option value="重庆市">重庆市</option> 32 <option value="广东省">广东省</option> 33 <option value="辽宁省">辽宁省</option> 34 </select> 35 </td> 36 </tr> 37 <tr> 38 <td>爱好</td> 39 <td> 40 <label><input type="checkbox" v-model="modifylist.hobby" value="篮球">篮球</label> 41 <label><input type="checkbox" v-model="modifylist.hobby" value="读书">读书</label> 42 <label><input type="checkbox" v-model="modifylist.hobby" value="插画">插画</label> 43 <label><input type="checkbox" v-model="modifylist.hobby" value="编程">编程</label> 44 <label><input type="checkbox" v-model="modifylist.hobby" value="弹琴">弹琴</label> 45 </td> 46 </tr> 47 </table> 48 <p> 49 <input type="button" @click="changeActive" value="取消"> 50 <input type="button" @click="modify" value="保存"> 51 </p> 52 </div> 53 </div> 54 </div>`, 55 computed: { 56 modifylist() { 57 return this.list; 58 } 59 }, 60 methods: { 61 changeActive() { 62 this.$emit('change'); 63 }, 64 modify() { 65 this.$emit('modify', this.modifylist); 66 } 67 } 68 }); 69 var app = new Vue({ 70 el: '#app', 71 data: { 72 isActive: false, // 是否显示弹窗 73 selected: -1, // 选择了哪条记录 74 selectedlist: {}, // 选中的信息 75 slist: [], 76 searchlist: [], 77 list: [ 78 { 79 username: 'aaaaa', 80 email: '123@qq.com', 81 sex: '男', 82 province: '北京市', 83 hobby: ['篮球', '读书', '编程'] 84 }, 85 { 86 username: 'bbbbb', 87 email: 'bbbbbbb@163.com', 88 sex: '女', 89 province: '河北省', 90 hobby: ['弹琴', '读书', '插画'] 91 }, 92 { 93 username: 'aaabb', 94 email: 'abababab@qq.com', 95 sex: '女', 96 province: '重庆市', 97 hobby: ['篮球'] 98 }, 99 { 100 username: 'cccccc', 101 email: '123@qq.com', 102 sex: '男', 103 province: '北京市', 104 hobby: ['篮球', '读书', '编程'] 105 }, 106 { 107 username: 'dddddd', 108 email: 'bbbbbbb@163.com', 109 sex: '女', 110 province: '河北省', 111 hobby: ['弹琴', '读书', '插画'] 112 }, 113 { 114 username: 'eeeee', 115 email: 'abababab@qq.com', 116 sex: '女', 117 province: '重庆市', 118 hobby: ['篮球'] 119 } 120 ] 121 }, 122 created() { 123 this.setSlist(this.list); 124 }, 125 methods: { 126 // 修改数据 127 showOverlay(index) { 128 this.selected = index; 129 this.selectedlist = this.list[index]; 130 this.changeOverlay(); 131 }, 132 // 点击保存按钮 133 modify(arr) { 134 if (this.selected > -1) { 135 Vue.set(this.list, this.selected, arr); 136 this.selected = -1; 137 } else { 138 this.list.push(arr); 139 } 140 this.setSlist(this.list); 141 this.changeOverlay(); 142 }, 143 add: function() { 144 this.selectedlist = { 145 username: '', 146 email: '', 147 sex: '男', 148 province: '北京市', 149 hobby: [] 150 }; 151 this.selected = -1; 152 this.isActive = true; 153 }, 154 // delete list in index location 155 del(index) { 156 this.list.splice(index, 1); 157 this.setSlist(this.list); 158 }, 159 changeOverlay() { 160 this.isActive = !this.isActive; 161 }, 162 // 获取需要渲染到页面中的数据 163 setSlist(arr) { 164 this.slist = JSON.parse(JSON.stringify(arr)); 165 }, 166 // 搜索 167 search(e) { 168 var v = e.target.value, 169 self = this; 170 self.searchlist = []; 171 if (v) { 172 var ss = []; 173 // 过滤需要的数据 174 this.list.forEach(function(item) { 175 if (item.username.indexOf(v) > -1) { 176 if (self.searchlist.indexOf(item.username) == -1) { 177 self.searchlist.push(item.username); 178 } 179 ss.push(item); 180 } else if (item.email.indexOf(v) > -1) { 181 if (self.searchlist.indexOf(item.email) == -1) { 182 self.searchlist.push(item.email); 183 } 184 ss.push(item); 185 } 186 }); 187 this.setSlist(ss); // 将过滤后的数据给了slist 188 } else { 189 // 没有搜索内容,则展示全部数据 190 this.setSlist(this.list); 191 } 192 } 193 }, 194 watch: {} 195 });
(详情请看原著(转自):https://www.xiabingbao.com/vue/2017/07/10/vue-curd.html)
点击链接查看demo【//www.xiabingbao.com/demos/20190304/vue-curd.html】。