使用vue实现简单的图书管理

    技术2022-07-31  74

    这个小案例巩固了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>
    Processed: 0.017, SQL: 9