20231014-黑马Vue学习笔记-第二天

指令修饰符

①按键修饰符
	@keyup.enter -> 键盘回车监听
②v-model修饰符
	v-model.trim -> 去除首尾空格
	v-model.number -> 转数字
③事件修饰符
	@事件名.stop -> 阻止冒泡
	@事件名.prevent -> 阻止默认行为

v-bind操作CSS

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

  <style>
    .box {
      width: 100px;
      height: 100px;
      border: 1px solid black;
      text-align: center;
    }

    .bgColor {
      background-color: aquamarine;
    }

    .bigger {
      width: 200px;
      height: 200px;
    }
  </style>
</head>

<body>
  <!-- 适用场景:一个类名 来回切换 -->
  <!-- <div id="box" class="box" :class="{bgColor:false,bigger:true}"> -->

  <!-- 适用场景:批量添加或删除类 -->
  <div id="box" class="box" :class="['bgColor','bigger']">
    Nice day!
  </div>

  <!-- 操作style <div class="box" :style="{CSS属性名1:'CSS属性值',CSS属性名2:'CSS属性值'}"></div> -->

  <script>
    const app = new Vue({
      el: "#box",
      data: {

      }
    });
  </script>
</body>

</html>

案例-京东秒杀Tab导航高亮

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <style>
    li {
      list-style: none;
      display: inline-block;
      width: 120px;
      height: 50px;
      margin-right: 20px;
      text-align: center;
    }

    a {
      text-decoration: none;
      color: black;
      font-size: 25px;
      line-height: 50px;
    }

    .active {
      background-color: red;
    }
  </style>
</head>

<body>
  <div id="nav">
    <ul>
      <li v-for="(item,index) in list" @click="activeIndex=index">
        <a href="#" :class="{active:(index===activeIndex)}">{{item.name}}</a>
      </li>
    </ul>
    <hr>
  </div>

  <script>
    const app = new Vue({
      el: "#nav",
      data: {
        list: [
          { id: 1, name: '京东秒杀' },
          { id: 2, name: '每日特价' },
          { id: 3, name: '品类秒杀' }
        ],
        activeIndex: 0
      }
    });
  </script>
</body>

</html>

案例-小黑学习网(v-model应用于其他表单元素)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <style>
    #app {
      width: 640px;
      height: 480px;
      background-color: aquamarine;
      margin: 100px auto;
    }
  </style>
</head>

<body>
  <div id="app">
    <h1>小黑学习网</h1>

    姓名:
    <input type="text" v-model="username">
    <br><br>

    是否单身:
    <input type="checkbox" name="" id="" v-model="isSingle">
    <br><br>

    性别:
    <input type="radio" name="sex" value="1" v-model="gender">♂男
    <input type="radio" name="sex" value="0" v-model="gender">♀女
    <br><br>

    所在城市:
    <select name="" id="" v-model="city">
      <option value="北京">北京</option>
      <option value="上海">上海</option>
      <option value="成都">成都</option>
      <option value="南京">南京</option>
    </select>
    <br><br>

    自我描述:
    <textarea name="" id="" cols="30" rows="10" style="resize: none;" v-model="desc"></textarea>
    <br><br>

    <button @click="sign">立即注册</button>
    <br><br>
  </div>

  <script>
    const app = new Vue({
      el: '#app',
      data: {
        username: '',
        isSingle: false,
        gender: '1',
        city: '北京',
        desc: ''
      },
      methods: {
        sign() {
          if (this.username === '' || this.desc === '') {
            alert('请输入完整信息!!!');
            return;
          }
          alert(
            '姓名:' + this.username + '\n' +
            '性别:' + (this.gender === '1' ? '男' : '女') + '\n' +
            '是否单身:' + (this.isSingle ? '是' : '否') + '\n' +
            '所在城市:' + this.city + '\n' +
            '自我介绍:' + this.desc + '\n' +
            '注册成功!!!'
          );
        }
      }
    });
  </script>
</body>

</html>

computed计算属性-简略写法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>

<body>
  <div id="box">
    <h1>小黑的礼物清单</h1>
    <table border="1" width="300">
      <tr>
        <th>名字</th>
        <th>数量</th>
      </tr>
      <tr v-for="(item,index) in list" :key="item.id">
        <td>{{item.name}}</td>
        <td>{{item.num}}</td>
      </tr>
    </table>
    <p>礼物总数:{{totalCount}}个</p>
  </div>
  <script>
    const app = new Vue({
      el: "#box",
      data: {
        list: [
          { id: 1, name: "蓝球", num: 1 },
          { id: 2, name: "玩具", num: 2 },
          { id: 3, name: "铅笔", num: 5 },
        ]
      },
      computed: {
        totalCount() {
          let total = this.list.reduce((sum, item) => sum + item.num, 0);
          return total;
        }
      }
    });
  </script>
</body>

</html>

computed计算属性和methods方法的区别

computed 计算属性:
作用:封装了一段对于数据的处理,求得一个结果。
语法:
① 写在 computed 配置项中
② 作为属性,直接使用 → this.计算属性 {{ 计算属性 }}
缓存特性(提升性能):
计算属性会对计算出来的结果缓存,再次使用直接读取缓存,
依赖项变化了,会自动重新计算 → 并再次缓存
methods 方法:
作用:给实例提供一个方法,调用以处理业务逻辑。
语法:
① 写在 methods 配置项中
② 作为方法,需要调用 → this.方法名( ) {{ 方法名() }} @事件名=“方法名”

computed计算属性-完整写法

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>

<body>
  <div id="box">
    姓:<input type="text" v-model="firstName">+
    名:<input type="text" v-model="lastName">=
    <span>{{fullName}}</span>
    <br><br>
    <button @click="changeName">改名卡</button>
  </div>

  <script>
    const app = new Vue({
      el: "#box",
      data: {
        firstName: '刘',
        lastName: '备'
      },
      methods: {
        changeName() {
          this.fullName = "张飞";
          console.log("改名");
        }
      },
      computed: {
        // 简写 -> 获取,没有配置设置的逻辑
        // fullName() {
        //   return this.firstName + this.lastName;
        // }

        // 完整写法 -> 获取 + 设置
        fullName: {
          get() {
            return this.firstName + this.lastName;
          },
          set(value) { //被修改赋值时执行
            this.firstName = value.slice(0, 1);
            this.lastName = value.slice(1);
          }
        }
      }
    });
  </script>
</body>

</html>

成绩案例

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>

  <style>
    .red {
      color: red;
    }
  </style>
</head>

<body>
  <div id="box">
    <div>
      <table border="1" width="400">
        <tr>
          <th>编号</th>
          <th>科目</th>
          <th>成绩</th>
          <th>操作</th>
        </tr>
        <tbody v-if="list.length>0">
          <tr v-for="(item,index) in list" :key="item.id">
            <td>{{index+1}}</td>
            <td>{{item.subject}}</td>
            <td :class="{red:item.score<60}">{{item.score}}</td>
            <td><button @click="Remove(item.id)">删除</button></td>
          </tr>
        </tbody>
        <tbody v-else>
          <td colspan="4" style="text-align: center;">暂无数据</td>
        </tbody>
      </table>
      <span>总分:{{Total}}</span>
      <span>平均分:{{Average}}</span>
    </div>
    <div>
      科目:<input type="text" v-model.trim="subject">
      分数:<input type="text" v-model.number="score">
      <button @click="Add">添加</button>
    </div>
  </div>

  <script>
    const app = new Vue({
      el: "#box",
      data: {
        list: [
          { id: 1, subject: '语文', score: 20 },
          { id: 7, subject: '数学', score: 99 },
          { id: 12, subject: '英语', score: 70 },
        ],
        subject: '',
        score: ''
      },
      methods: {
        Remove(id) {
          this.list = this.list.filter(item => item.id != id);
        },
        Add() {
          if (!this.subject) {
            alert("请输入科目!");
            return;
          }
          if (typeof this.score !== 'number') {
            alert('请输入正确的成绩!');
            return;
          }
          this.list.unshift({ id: +new Date(), subject: this.subject, score: this.score });
          this.subject = '';
          this.score = '';
        }
      },
      computed: {
        Total() {
          return this.list.reduce((sum, item) => sum + item.score, 0);
        },
        Average() {
          if (this.list.length === 0)
            return 0;
          return (this.Total / this.list.length).toFixed(2);
        }
      }
    });
  </script>

</body>

</html>

watch侦听器

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
</head>

<body>
  <div id="box">
    <input type="text" name="" id="" v-model="obj.words">
  </div>

  <script>
    const app = new Vue({
      el: "#box",
      data: {
        // words: ''
        obj: {
          words: ""
        }
      },
      watch: {
        // words(newValue, oldValue) { // oldValue 可省略
        //   console.log('变化了', newValue, oldValue);
        // }

        'obj.words'(newValue) {
          console.log('变化了', newValue);
        },

        // // 完整写法
        // obj: {
        //   deep: true, //深度监视
        //   immediate: true, //立刻执行,一进入页面就执行一次
        //   handle(newValue) { //数据修改时触发

        //   }
        // }

      }
    });
  </script>
</body>

</html>

案例-水果购物车

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  <style>
    td {
      text-align: center;
    }
  </style>
</head>

<body>
  <div id="box">
    <table border="1" width="1000">
      <thead>
        <tr>
          <th>选中</th>
          <th>水果</th>
          <th>单价</th>
          <th>个数</th>
          <th>小计</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody v-if="list.length===0">
        <td colspan="6">空空如也</td>
      </tbody>
      <tbody v-else v-for="(item,index) in list" :key="item.id">
        <tr>
          <td><input type="checkbox" v-model="item.isChecked"></td>
          <td>{{item.name}}</td>
          <td>{{item.price}}</td>
          <td>
            <button @click="item.num--" :disabled="item.num<=1">-</button>
            {{item.num}}
            <button @click="item.num++">+</button>
          </td>
          <td>{{item.price*item.num}}</td>
          <td><a href="https://www.baidu.com" @click.prevent="del(item.id)">删除</a></td>
        </tr>
      </tbody>
      <tfoot>
        <td><input type="checkbox" v-model="isAll">全选</td>
        <td colspan="3"></td>
        <td>总价:¥{{totalPrice}}</td>
        <td><button>结算{{totalCount}}</button></td>
      </tfoot>
    </table>
  </div>

  <script>
    const defaultArr = [
      { id: 1, name: '火龙果', isChecked: true, num: 2, price: 3 },
      { id: 2, name: '苹果', isChecked: false, num: 8, price: 7 },
      { id: 3, name: '香蕉', isChecked: false, num: 6, price: 5 },
      { id: 4, name: '葡萄', isChecked: false, num: 3, price: 10 },
      { id: 5, name: '香梨', isChecked: false, num: 9, price: 4 },
    ];
    const app = new Vue({
      el: "#box",
      data: {
        list: JSON.parse(localStorage.getItem('list')) || defaultArr
      },
      methods: {
        del(id) {
          this.list = this.list.filter(item => item.id != id);
        }
      },
      computed: {
        // isAll() {
        //   return this.list.every(item => item.isChecked === true);
        // }

        isAll: {
          get() {
            return this.list.every(item => item.isChecked === true);
          },
          set(value) {
            this.list.forEach(function (item) {
              item.isChecked = value;
            });
          }
        },
        totalCount() {
          return this.list.reduce((sum, item) => {
            if (item.isChecked) {
              return sum + item.num;
            }
            else {
              return sum;
            }
          }, 0);
        },
        totalPrice() {
          return this.list.reduce((sum, item) => {
            if (item.isChecked) {
              return sum + (item.num * item.price);
            }
            else {
              return sum;
            }
          }, 0);
        }
      },
      watch: {
        list: {
          deep: true,
          handler(newValue) {
            localStorage.setItem('list', JSON.stringify(newValue)); // 存到本地
          }
        }
      }
    });
  </script>
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值