这个小案例巩固了vue的基础知识,主要涉及了各种指令的操作,自定义指令、生命周期、侦听器、过滤器、计算属性等的实践。完成的功能有对图书的增删改和统计图书的总量。

功能介绍:

  • 添加图书:输入编号和名称点击提交按钮即可添加图书,这里在名称表单中有一个监听器(name),如果名称相同提交按钮就失效,主要是使用数组的push()方法;
  • 修改图书:点击修改按钮将图书的信息填充到表单中,但是编号不能修改,使用disabled=‘true’来使其失效,然后修改名称之后再点击提交进行修改。将数据填充到表单使用数组的filter()方法,然后使用some()方法来对数组进行遍历,修改指定索引的图书信息;
  • 删除图书:方法一是通过获取删除图书的id来进行删除,使用的是数组的findIndex()方法,再使用splice()方法进行删除;方法二通过数组的filter()方法来进行过滤。
  • 自定义指令:使用Vue.directive()定义一个获取焦点的全局指令(v-focus)并应用在输入编号的表单中;
  • 过滤器:使用Vue.filter()定义一个过滤器(format)将将日期转为自己想要的格式;
  • 计算属性:在vue实例中添加一个参数属性computed来统计图书的总数量,直接统计图书的长度即可实现;
  • 侦听器:在vue实例中添加一个参数属性watch来验证图书是否存在,并且应用在输入名称的表单里,如果图书已经存在则提交按钮则会失效。
  • 生命周期:使用mounted()钩子函数将数据填充到模板中。

页面展示:
在这里插入图片描述
HTML静态模板结构:

 <div id="app">
        <div class="title">图书管理</div>
        <div class="book">
            <label for="id">编号:</label>
            <input type="text" id="id" v-model='id' :disabled='flag' v-focus>
            <label for="name">名称:</label>
            <input type="text" id="name" v-model='name'>
            <button @click='handle' :disabled='handleflag'>提交</button>
        </div>
        <div class="total">
            <span>图书总量:</span>
            <span>{{total}}</span>
        </div>
        <table cellspacing="0">
            <tr>
                <th>编号</th>
                <th>名称</th>
                <th>时间</th>
                <th>操作</th>
            </tr>
            <tr :key='item.id' v-for='item in books'>
                <td v-cloak>{{item.id}}</td>
                <td v-cloak>{{item.name}}</td>
                <td v-cloak>{{item.date | format('yyyy-MM-dd')}}</td>
                <td><button @click='edit(item.id)'>修改</button> | <button @click='del(item.id)'>删除</button></td>
            </tr>
        </table>
    </div>

css样式结构:

<style>
        * {
            padding: 0;
            margin: 0;
        }
        
        #app {
            width: 1200px;
            margin: 100px auto;
            text-align: center;
        }
        
        .title {
            font-size: 25px;
        }
        
        .book {
            margin-top: 20px;
        }
        
        table {
            margin: 30px 0 0 410px;
        }
        
        table tr:first-child {
            background-color: peru;
        }
        
        tr td,
        th {
            width: 100px;
            border: 1px dotted peru;
        }
        
        button {
            /* background-color: pink; */
            border: none;
        }
        
        .total {
            margin-top: 20px;
            background-color: orange;
            width: 100px;
            margin-left: 548px;
        }
    </style>

js代码:

<script>
        // 定义一个带参数的过滤器
        Vue.filter('format', function(value, arg) {
            if (arg == 'yyyy-MM-dd') {
                return value.getFullYear() + '-' + (value.getMonth() + 1) + '-' + value.getDate();
            }
        });
        // 自定义全局指令`v-focus`
        Vue.directive('focus', {
            bind: function(el) {
                // 只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
            },
            //当被绑定的元素插入到 DOM 中时……
            inserted: function(el) {
                // 获得焦点
                el.focus();
            },
            update: function() {
                // 所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
            }
        });
        var vm = new Vue({
            el: '#app',
            data: {
                id: '',
                name: '',
                date: new Date(),
                flag: false,
                handleflag: false,
                books: []
            },
            methods: {
                handle: function() {
                    if (this.id == '' || this.name == '') {
                        alert("请输入内容!!!");
                    } else if (this.flag) {
                        //修改后重新提交
                        this.books.some(item => {
                            if (item.id == this.id) {
                                item.name = this.name;
                                item.date = this.date;
                                //完成更新后终止循环遍历
                                return true;
                            };
                        })
                        this.flag = false;
                    } else {
                        //添加图书
                        var book = {};
                        book.id = this.id;
                        book.name = this.name;
                        book.date = this.date;
                        this.books.push(book);
                    }
                    this.id = '';
                    this.name = '';
                },
                edit: function(id) {
                    //禁止修改编号
                    this.flag = true;
                    //根据ID编辑数据
                    //点击修改后将数据填充到表单进行修改
                    var book = this.books.filter(function(item) {
                        return item.id == id;
                    });
                    this.id = book[0].id;
                    this.name = book[0].name;
                },
                del: function(id) {
                    //删除图书
                    // 方法一:根据id从数组中查找元素的索引
                    // var index = this.books.findIndex(function(item) {
                    //     return item.id == id;
                    // });
                    // //根据索引删除数组元素
                    // this.books.splice(index, 1);
                    //方法二 通过数组的filter方法
                    this.books = this.books.filter(function(item) {
                        return item.id != id;
                    });
                }
            },
            computed: {
                total: function() {
                    //利用计算属性统计书本的总量
                    return this.books.length;
                }
            },
            watch: {
                name: function(val) {
                    //验证图书是否存在
                    var flag = this.books.some(function(item) {
                        return item.name == val;
                    });
                    if (flag) {
                        this.handleflag = true;
                    } else {
                        this.handleflag = false;
                    }
                }
            },
            mounted: function() {
                //该生命周期函数被触发的时候,模板已经可以使用
                //一般此时用于获取后台数据,然后把数据填充到模板
                var data = [{
                    id: 1,
                    name: '水浒传',
                    date: new Date()
                }, {
                    id: 2,
                    name: '三国演义',
                    date: new Date()
                }];
                this.books = data;
            }

        })
    </script>
Logo

前往低代码交流专区

更多推荐