一.指令补充
指令修饰符
v-bind对于style操作的增强
v-model应用于其他表单元素
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> textarea { display: block; width: 240px; height: 100px; margin: 10px 0; } </style> </head> <body> <div id="app"> <h3>小黑学习网</h3> 姓名: <input type="text" v-model="username"> <br><br> 是否单身: <input type="checkbox" v-model="isSingle"> <br><br> <!-- 前置理解: 1. name: 给单选框加上 name属性可以分组→同一组互相会互斥 2.value:给单选框加上value属性,用于提交给后台的数据 结合Vue使用→v-model --> 性别: <input v-model="gender" type="radio" name="gender" value="male">男 <input v-model="gender" type="radio" name="gender" value="female">女 <br><br> <!-- 前置理解: 1.option需要设置value值,提交给后台 2.select的value值,关联了选中的option 的 value 值 结合Vue使用→v-model --> 所在城市: <select v-model="cityId"> <option value="101">北京</option> <option value="102">上海</option> <option value="103">成都</option> <option value="104">南京</option> </select> <br><br> 自我描述: <textarea v-model="desc"></textarea> <button>立即注册</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { username:'', isSingle:false, gender:'female', cityId:'102', desc:"" } }) </script> </body> </html>
二.computed计算属性
基础语法
计算属性vs方法
完整写法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div id="app"> 姓:<input type="text" v-model="firstName"><br> 名:<input type="text" v-model="lastName"><br> <p>姓名:{{fullName}}</p> <button @click="changeName">修改姓名</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> const app = new Vue({ el: '#app', data: { firstName:'刘', lastName:'备' }, methods: { changeName(){ this.fullName='吕小布' } }, computed: { //简写->获取 没有配置设置的逻辑 // fullName(){ // return this.firstName+this.lastName // } //完整写法-》获取+设置 fullName:{ //(1)当fullName计算属性 被获取求值时 执行get(有缓存) //会将返回值作为,求值的结果 get(){ return this.firstName+this.lastName }, //(2)当fullName计算属性 被修改赋值时 执行set //修改的值 传递给set的形参 set(value){ // console.log(value) // console.log(value.slice(0,1)); // console.log(value.slice(1)); this.firstName=value.slice(0,1) this.lastName=value.slice(1) } } } }) </script> </body> </html>
三.watch侦听器
基础语法
完整写法
四.综合案例:水果购物车
渲染/删除/修改数量/全选反选/统计总价/持久化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="./css/inputnumber.css" /> <link rel="stylesheet" href="./css/index.css" /> <title>购物车</title> </head> <body> <div class="app-container" id="app"> <!-- 顶部banner --> <div class="banner-box"><img src="http://autumnfish.cn/static/fruit.jpg" alt="" /></div> <!-- 面包屑 --> <div class="breadcrumb"> <span>🏠</span> / <span>购物车</span> </div> <!-- 购物车主体 --> <div class="main" v-if="fruitList.length>0"> <div class="table"> <!-- 头部 --> <div class="thead"> <div class="tr"> <div class="th">选中</div> <div class="th th-pic">图片</div> <div class="th">单价</div> <div class="th num-th">个数</div> <div class="th">小计</div> <div class="th">操作</div> </div> </div> <!-- 身体 --> <div class="tbody"> <div v-for="(item,index) in fruitList" :key="item.id" class="tr" :class="{active:item.isChecked}"> <div class="td"><input type="checkbox" v-model="item.isChecked"/></div> <div class="td"><img :src="item.icon" alt="" /></div> <div class="td">{{item.price}}</div> <div class="td"> <div class="my-input-number"> <button :disabled="item.num<=1" class="decrease" @click="sub(item.id)"> - </button> <span class="my-input__inner">{{item.num}}</span> <button class="increase" @click="add(item.id)"> + </button> </div> </div> <div class="td">{{item.num*item.price}}</div> <div class="td"><button @click="del(item.id)">删除</button></div> </div> </div> </div> </div> <!-- 底部 --> <div class="bottom"> <!-- 全选 --> <label class="check-all"> <input type="checkbox" v-model="isAll"/> 全选 </label> <div class="right-box"> <!-- 所有商品总价 --> <span class="price-box">总价 : ¥ <span class="price">{{totalPrice}}</span></span> <!-- 结算按钮 --> <button class="pay">结算( {{totalCount}} )</button> </div> </div> </div> <!-- 空车 --> <div class="empty" v-else>🛒空空如也</div> </div> <script src="../vue.js"></script> <script> const defaultArr= [ { id: 1, icon: 'http://autumnfish.cn/static/火龙果.png', isChecked: true, num: 2, price: 6, }, { id: 2, icon: 'http://autumnfish.cn/static/荔枝.png', isChecked: false, num: 7, price: 20, }, { id: 3, icon: 'http://autumnfish.cn/static/榴莲.png', isChecked: false, num: 3, price: 40, }, { id: 4, icon: 'http://autumnfish.cn/static/鸭梨.png', isChecked: true, num: 10, price: 3, }, { id: 5, icon: 'http://autumnfish.cn/static/樱桃.png', isChecked: false, num: 20, price: 34, }, ], const app = new Vue({ el: '#app', data: { // 水果列表 fruitList:JSON.parse(localStorage.getItem('list'))||defaultArr }, computed:{ //默认计算属性,只能获取不能设置,要设置完整写法 // isAll(){ // //必须所有的小选框都选中 全选按钮才选中-> every // return this.fruitList.every(item=>item.isChecked) // } //完整写法 isAll:{ get(){ return this.fruitList.every(item=>item.isChecked) }, set(value){ // console.log(value); //基于拿到的布尔值 要让所有的小选框 同步状态 this.fruitList.forEach(item=>item.isChecked=value) } }, //统计选中的总数 reduce totalCount(){ return this.fruitList.reduce((sum,item)=>{ if(item.isChecked){ //选中->需要累加 return sum+item.num }else{ //没选中 return sum } },0) }, totalPrice(){ return this.fruitList.reduce((sum,item)=>{ if(item.isChecked){ return sum+(item.num*item.price) } else{ return sum } },0) } }, methods:{ del(id){ this.fruitList=this.fruitList.filter(item=>item.id!=id) }, add(id){ //1.根据id找到数组里的对应项->find const fruit=this.fruitList.find(item=>item.id===id) //2.操作num数量 fruit.num++ }, sub(id){ const fruit=this.fruitList.find(item=>item.id===id) //2.操作num数量 fruit.num-- } }, watch:{ fruitList:{ deep:true, handler(newValue){ //需要将变化后的newValue存入本地 localStorage.setItem('list',JSON.stringify(newValue)) } } } }) </script> </body> </html>