vue实现对数据的增删改查(CURD)

回到文章
<div class="container" id="app">
    <div>
        <input type="text" placeholder="search" @input="search" list="cars" class="search">
        <datalist id="cars">
            <option v-for="item in searchlist" :value="item"></option>
        </datalist>
        <input type="button" class="add" @click="add" value="新增">
    </div>
    <div>
        <table>
            <tr>
                <th>id</th>
                <th>用户名</th>
                <th>邮箱</th>
                <th>性别</th>
                <th>省份</th>
                <th>爱好</th>
                <th>操作</th>
            </tr>
            <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>
        </table>
    </div>
    <model :list='selectedlist' :isactive="isActive" v-cloak @change="changeOverlay" @modify="modify"></model>
</div>
[v-cloak] {
    display: none
}
table {
    border: 1px solid #ccc;
    padding: 0;
    border-collapse: collapse;
    table-layout: fixed;
    margin-top: 10px;
    width: 100%;
}
table td,
table th {
    height: 30px;
    border: 1px solid #ccc;
    background: #fff;
    font-size: 15px;
    padding: 3px 3px 3px 8px;
}
table th:first-child {
    width: 30px;
}
.container,
.st {
    width: 1000px;
    margin: 10px auto 0;
    font-size: 13px;
    font-family: 'Microsoft YaHei'
}
.container .search {
    font-size: 15px;
    padding: 4px;
}
.container .add {
    padding: 5px 15px;
}
.overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 6;
    background: rgba(0, 0, 0, 0.7);
}
.overlay td:first-child {
    width: 66px;
}
.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);
    /*margin-top: -150px;*/
    padding: 20px;
}
Vue.component('model', {
    props: ['list', 'isactive'],
    template: `<div class="overlay" v-show="isactive">
                    <div class="con">
                    <h2 class="title">新增 | 修改</h2>
                    <div class="content">
                    <table>
                    <tr>
                    <td>用户名</td>
                    <td><input type="text" v-model="modifylist.username"></td>
                    </tr>
                    <tr>
                    <td>邮箱</td>
                    <td><input type="text" v-model="modifylist.email"></td>
                    </tr>
                    <tr>
                    <td>性别</td>
                    <td>
                    <label><input type="radio" name="sex" value="男" v-model="modifylist.sex">男</label>
                    <label><input type="radio" name="sex" value="女" v-model="modifylist.sex">女</label>
                    <label><input type="radio" name="sex" value="未知" v-model="modifylist.sex">未知</label>
                    </td>
                    </tr>
                    <tr>
                    <td>省份</td>
                    <td>
                    <select name="" id="" v-model="modifylist.province">
                    <option value="北京市">北京市</option>
                    <option value="河北省">河北省</option>
                    <option value="河南省">河南省</option>
                    <option value="重庆市">重庆市</option>
                    <option value="广东省">广东省</option>
                    <option value="辽宁省">辽宁省</option>
                    </select>
                    </td>
                    </tr>
                    <tr>
                    <td>爱好</td>
                    <td>
                    <label><input type="checkbox" v-model="modifylist.hobby" value="篮球">篮球</label>
                    <label><input type="checkbox" v-model="modifylist.hobby" value="读书">读书</label>
                    <label><input type="checkbox" v-model="modifylist.hobby" value="插画">插画</label>
                    <label><input type="checkbox" v-model="modifylist.hobby" value="编程">编程</label>
                    <label><input type="checkbox" v-model="modifylist.hobby" value="弹琴">弹琴</label>
                    </td>
                    </tr>
                    </table>
                    <p>
                    <input type="button" @click="changeActive" value="取消">
                    <input type="button" @click="modify" value="保存">
                    </p>
                    </div>
                    </div>
                </div>`,
    computed: {
        modifylist() {
            return this.list;
        }
    },
    methods: {
        changeActive() {
            this.$emit('change');
        },
        modify() {
            this.$emit('modify', this.modifylist);
        }
    }
});
var app = new Vue({
    el: '#app',
    data: {
        isActive: false,
        selected: -1,
        selectedlist: {},
        slist: [],
        searchlist: [],
        list: [
            {
                username: 'aaaaa',
                email: '123@qq.com',
                sex: '男',
                province: '北京市',
                hobby: ['篮球', '读书', '编程']
            },
            {
                username: 'bbbbb',
                email: 'bbbbbbb@163.com',
                sex: '女',
                province: '河北省',
                hobby: ['弹琴', '读书', '插画']
            },
            {
                username: 'aaabb',
                email: 'abababab@qq.com',
                sex: '女',
                province: '重庆市',
                hobby: ['篮球']
            },
            {
                username: 'cccccc',
                email: '123@qq.com',
                sex: '男',
                province: '北京市',
                hobby: ['篮球', '读书', '编程']
            },
            {
                username: 'dddddd',
                email: 'bbbbbbb@163.com',
                sex: '女',
                province: '河北省',
                hobby: ['弹琴', '读书', '插画']
            },
            {
                username: 'eeeee',
                email: 'abababab@qq.com',
                sex: '女',
                province: '重庆市',
                hobby: ['篮球']
            }
        ]
    },
    created() {
        console.log(Date.now());
        this.setSlist(this.list);
    },
    methods: {
        // 修改数据
        showOverlay(index) {
            this.selected = index;
            this.selectedlist = this.list[index];
            this.changeOverlay();
        },
        // 点击保存按钮
        modify(arr) {
            if (this.selected > -1) {
                Vue.set(this.list, this.selected, arr);
            } else {
                this.list.push(arr);
            }
            this.setSlist(this.list);
            this.changeOverlay();
        },
        add: function () {
            this.selectedlist = {
                username: '',
                email: '',
                sex: '男',
                province: '北京市',
                hobby: []
            };
            this.isActive = true;
        },
        // delete list in index location
        del(index) {
            this.list.splice(index, 1);
            this.setSlist(this.list);
        },
        changeOverlay() {
            this.isActive = !this.isActive;
        },
        // 获取需要渲染到页面中的数据
        setSlist(arr) {
            this.slist = JSON.parse(JSON.stringify(arr));
        },
        // 搜索
        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);
            }
        }
    },
    watch: {
    }
})