Vue学习笔记——图书管理案例

    技术2025-03-19  28

    Vue学习笔记——图书管理案例

    效果:


    label for标签的作用: for 属性规定 label 与哪个表单元素绑定。 作用是 在点击label 时 会自动将焦点移动到绑定的 元素上JavaScript Array.some() 方法用法 定义和用法: some() 方法用于检测数组中的元素是否满足指定条件(函数提供)。 . some() 方法会依次执行数组的每个元素: 如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。 如果没有满足条件的元素,则返回false。 注意: some() 不会对空数组进行检测。 注意: some() 不会改变原始数组。箭头函数中的this指的是定义这个函数的父级作用域中的this。

    new 知识:

    数组变异方法 Vue将原生的api处理成了响应式的方式,会影响原始数据

    替换数组 filter()、concat()、slice()——它们都是方法哦! 不会改变原始数组,但总是返回一个新数组

    filterfilter()方法创建一个新的数组,新数组中的元素 是通过检查指定数组中符合条件的所有元素concatconcat( )方法用于连接两个或多个数组。该方法不会改变现有的数组sliceslice( )方法可从已有的数组中返回选定的元素。该方法并不会修改数组,而是返回一个子数组 修改响应式数据(数组响应式变化) Vue.set(vm.items,indexOfItem,newValue)vm.$set(vm.items,indexOfItem,newValue) 参数①——要处理的数组名称 参数②——要处理的数组的索引 / 对象的属性 参数③——要处理的数组的值

    用索引的方式修改的数据不是响应是的,所以要用上面的方法👆,可进行修改也可以添加

    修改下面图书为例子:

    Vue.set(vm.books,2,{id:9, name:'坏小孩', date:new Date()}) //因为这个数组里是每一个对象,所以参数三直接传入对象就可以,不需要引号 vm.$set(vm.books,1,{id:1, name:'坏小孩', date:new Date()})

    添加对象属性

    vm.$set(vm.info,'gender','female');

    功能分析:

    实现静态列表效果(基于数据实现模板效果)增加图书操作处理每行的操作按钮(修改、删除)

    步骤:

    1. 准备好一些数据

    数据存放在vue 中的 data 属性中

    2. 把提供好的数据渲染到页面上

    利用 v-for循环 遍历 books 将每一项数据渲染到对应的数据中 <tbody> <tr :key='item.id' v-for='item in books'> <!-- 对应的id 渲染到页面上 --> <td>{{item.id}}</td> <!-- 对应的name 渲染到页面上 --> <td>{{item.name}}</td> <td>{{item.date}}</td> <td> <!-- 阻止 a 标签的默认跳转 --> <a href="" @click.prevent>修改</a> <span>|</span> <a href="" @click.prevent>删除</a> </td> </tr> </tbody>

    使用 @click 不一定就要绑定函数的,可以只为了阻止默认事件

    3. 添加图书

    通过双向数据绑定获取到输入框中的输入内容给按钮添加点击事件把输入框中的数据存储到 data 中的 books 里面 <div> <h1>图书管理</h1> <div class="book"> <div> <label for="id">编号:</label> <!-- 3.1、通过双向绑定获取到输入框中的输入的 id --> <input type="text" id="id" v-model='id'> <label for="name">名称:</label> <!-- 3.2、通过双向绑定获取到输入框中的输入的 name --> <input type="text" id="name" v-model='name'> <!-- 3.3、给按钮添加点击事件 --> <button @click='handle'>提交</button> </div> </div> </div> <script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ books:[{ id:1, name:'家', date:'' },{ id:2, name:'春', date:'' },{ id:3, name:'秋', date:'' },{ id:4, name:'飘', date:'' }], id:'', name:'', }, methods:{ submit:function(){ // 3.4 定义一个新的对象abook 存储 获取到输入框中 书 的id和名字 var abook = { }; if(this.id !=''&& this.name !=''){ abook.id = this.id; abook.name = this.name; abook.date = ''; this.books.push(abook); console.log('提交成功'); }else{ alert('请输入内容后提交'); } } } }) </script>

    4. 修改图书 ▲

    点击修改按钮的时候,获取到要修改的书籍名单 ① 给修改按钮添加点击事件,需要把当前的图书的id传递过去,这样才知道需要修改的是哪一本书籍把需要修改的书籍名单填充到表单里面 ② 根据传递过来的id查出books中 对应的书籍详细信息 (怎么查啊?) this.books.filter( function( item ) ){ 用来写过滤条件 }) ③ 把获取到的信息填充到表单编辑状态下,书籍的id不能进行修改(控制书籍编号的输入框禁用)复用添加方法 用户点击提交的时候 依然执行 handle 中的逻辑。如果flag为true 即表单处于不可输入状态 此时执行的是用户编辑数据 <a href="" @click.prevent='edit(item.id)'>修改</a> <script type="text/javascript"> var vm = new Vue({ el:'#app', data:{ books:[省略了,看前面], id:'', name:'', flag:false, //布尔值不需要加‘’ }, methods:{ submit:function(){ if(this.flag){ //编辑操作 //根据当前的id去更新数组中对应的数据(遍历) this.books.some((item)=>{ //箭头函数中的this指的是定义这个函数的父级作用域中的this。(这里的父级作用域是submit的作用域,submit中的this指的是Vue实例本身 if(item.id==this.id){ item.name= this.name; //完成更新操作之后,需要终止循环 return true; } }); this.flag=false; }else{ var abook = { }; if(this.id !=''&& this.name !=''){ abook.id = this.id; abook.name = this.name; abook.date = ''; this.books.push(abook); console.log('提交成功'); }else{ alert('请输入内容后提交'); } } //清空表单 this.id=''; this.name=''; }, edit:function(id){ this.flag=true; // console.log(id); var book = this.books.filter(function(item){ return item.id == id; //这句话有点不太理解 }); console.log(book); //把获取到的信息填充到表单 this.id=book[0].id; this.name=book[0].name; } } }) </script>

    5. 删除图书

    给删除按钮添加点击事件 把当前需要删除的书籍id 传递过来根据id从数组中查找元素的索引根据索引删除数组元素 <a href="" @click.prevent='deleteBook(item.id)'>删除</a> <script> deleteBook:function(idx){ // //根据id从数组中查找元素的索引 // var index = this.books.findIndex(function(item){ // return item.id == idx; // }) // //根据索引删除数组元素 // this.books.splice(index,1); // ------------------ // 法二: this.books = this.books.filter(function(item){ return item.id != idx; }) } </script>

    6. 常用特性应用场景

    1. 过滤器——时间格式

    <td>{{item.date|format('yyyy-MM-dd hh:mm:ss')}}</td> <script type="text/javascript"> Vue.filter('format',function(value,arg){ function dateFormat(date, format) { if (typeof date === "string") { var mts = date.match(/(\/Date\((\d+)\)\/)/); if (mts && mts.length >= 3) { date = parseInt(mts[2]); } } date = new Date(date); if (!date || date.toUTCString() == "Invalid Date") { return ""; } var map = { "M": date.getMonth() + 1, //月份 "d": date.getDate(), //日 "h": date.getHours(), //小时 "m": date.getMinutes(), //分 "s": date.getSeconds(), //秒 "q": Math.floor((date.getMonth() + 3) / 3), //季度 "S": date.getMilliseconds() //毫秒 }; format = format.replace(/([yMdhmsqS])+/g, function(all, t) { var v = map[t]; if (v !== undefined) { if (all.length > 1) { v = '0' + v; v = v.substr(v.length - 2); } return v; } else if (t === 'y') { return (date.getFullYear() + '').substr(4 - all.length); } return all; }); return format; } //调用别人写好的方法 return dateFormat(value,arg); }) </script>

    2. 自定义指令——focus

    <label for="id">编号:</label> <input type="text" id="id" v-model='id' :disabled='flag' v-focus> <script> Vue.directive('focus',{ inserted:function(el){ el.focus(); } }); </script>

    3. 计算属性——书本总数

    <div class="total"> <span>图书总数:</span> <span>{{total}}</span> </div> <script> computed:{ total:function(){ return this.books.length; } } </script>

    完整代码:

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> .gird{ margin: auto; width: 530px; text-align: center; } .gird table{ width: 100%; border-collapse: collapse; border-top: 1px solid #C2D89A; } .gird th,td{ padding: 10; height: 35px; line-height: 35px; border:1px dashed orange; } .gird th{ background-color: orange; } .gird .book{ padding-bottom: 10px; padding-top: 5px; background-color: orange; } .gird .total { height: 30px; line-height: 30px; background-color: orange; border-top: 1px solid #C2D89A; } </style> </head> <body> <div id="app"> <div class="gird"> <div > <h1>图书管理</h1> <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'> <input type="button" value="提交" @click='submit'> </div> </div> <div class="total"> <span>图书总数:</span> <span>{{total}}</span> </div> <table> <thead> <tr> <th>编号</th> <th>名称</th> <th>时间</th> <th>操作</th> </tr> </thead> <tbody> <tr :key='item.id' v-for='(item,index) in books'> <td >{{item.id}}</td> <td>{{item.name}}</td> <td>{{item.date|format('yyyy-MM-dd hh:mm:ss')}}</td> <td> <a href="" @click.prevent='edit(item.id)'>修改</a> <span>|</span> <a href="" @click.prevent='deleteBook(item.id)'>删除</a> </td> </tr> </tbody> </table> </div> </div> <script type="text/javascript" src="js/vue.js"></script> <script type="text/javascript"> Vue.filter('format',function(value,arg){ function dateFormat(date, format) { if (typeof date === "string") { var mts = date.match(/(\/Date\((\d+)\)\/)/); if (mts && mts.length >= 3) { date = parseInt(mts[2]); } } date = new Date(date); if (!date || date.toUTCString() == "Invalid Date") { return ""; } var map = { "M": date.getMonth() + 1, //月份 "d": date.getDate(), //日 "h": date.getHours(), //小时 "m": date.getMinutes(), //分 "s": date.getSeconds(), //秒 "q": Math.floor((date.getMonth() + 3) / 3), //季度 "S": date.getMilliseconds() //毫秒 }; format = format.replace(/([yMdhmsqS])+/g, function(all, t) { var v = map[t]; if (v !== undefined) { if (all.length > 1) { v = '0' + v; v = v.substr(v.length - 2); } return v; } else if (t === 'y') { return (date.getFullYear() + '').substr(4 - all.length); } return all; }); return format; } return dateFormat(value,arg); }); Vue.directive('focus',{ inserted:function(el){ el.focus(); } }); var vm = new Vue({ el:'#app', data:{ books:[{ id:1, name:'家', date:new Date(), },{ id:2, name:'春', date:new Date(), },{ id:3, name:'秋', date:new Date(), },{ id:4, name:'飘', date:new Date(), }], id:'', name:'', flag:false, //布尔值不需要加‘’ }, methods:{ submit:function(){ if(this.flag){ //编辑操作 //根据当前的id去更新数组中对应的数据(遍历) this.books.some((item)=>{ if(item.id==this.id){ item.name= this.name; //完成更新操作之后,需要终止循环 return true; } }); this.flag=false; }else{ var abook = { }; if(this.id !=''&& this.name !=''){ abook.id = this.id; abook.name = this.name; abook.date = new Date(); this.books.push(abook); console.log('提交成功'); }else{ alert('请输入内容后提交'); } } //清空表单 this.id=''; this.name=''; }, edit:function(id){ this.flag=true; // console.log(id); var book = this.books.filter(function(item){ return item.id == id; }); console.log(book); //把获取到的信息填充到表单 this.id=book[0].id; this.name=book[0].name; }, deleteBook:function(idx){ // //根据id从数组中查找元素的索引 // var index = this.books.findIndex(function(item){ // return item.id == idx; // }) // //根据索引删除数组元素 // this.books.splice(index,1); // ------------------ // 法二: this.books = this.books.filter(function(item){ return item.id != idx; }) } }, computed:{ total:function(){ return this.books.length; } } }) </script> </body> </html>
    Learning from Vue 全家桶
    Processed: 0.013, SQL: 9