Vue(事件处理、计算属性、监视属性)

一、事件处理

 1. 语法

Vue模板

  • v-on:xxx="处理函数"

  • @xxx(作为绑定事件的简写)="处理函数"

  • xxx指代的都是事件名

Vue实例

  • 必须使用methods配置对象(配置多个函数方法)

  • methods中配置函数,都是Vue所管理,this的指向是vm或组件实例对象

  • 不能使用箭头函数,否则this指向不是vm

  • 注意事件处理函数可以分为带参和不带参数,带参如果是事件对象就用“,$”分割

    • @click="demo"

    • @click="demo($event)

 <div id="root">
      <h2>欢迎来到{{name}}</h2>
      <!-- 简写:v-on: 相当于@ -->
      <button @click="showInfo1">点我提示信息</button>
      <!-- ,隔开可以使用$获取事件对象 -->
      <button @click="showInfo2(66,$event)">点我提示信息</button>
    </div>
  </body>
  <script>
    Vue.config.production = false;
    /*
    注意绑定事件的执行函数不能直接在script标签内声名(报错)
    function showInfo() {
      alert("你好");
    } */
    const vm = new Vue({
      el: "#root",
      data: {
        name: "云贵川",
      },
      methods: {
        showInfo1() {
          alert("你好");
          //   console.log(a, b, c, d);
          //   console.log(this === vm); //普通函数此处的this指向的是vm
        },
        // 如果使用箭头函数this会指向window
        /*  showInfo: (e) => {
          console.log(this);
        }, */
        showInfo2(number, event) {
          console.log(number, event);
          alert("同学!!");
        },
      },
    });
  </script>

2. 事件修饰符

  • prevent:阻止默认事件

  • stop:阻止事件冒泡

  • once:事件只触发一次(常用)

  • capture:使用事件的捕获模式

  • self:只有event.target是当前操作元素时才触发事件

  • passive:事件的默认行为立即执行(比如滚轮执行无需等待回调执行就会执行事件),无需等待事件回调执行完毕

  • 修饰符可以连续写

 <div id="root">

      <!-- 阻止默认事件 -->
      <a href="http://www.baidu.com" @click.prevent="showInfo">点击提示</a>

      <!-- 阻止事件冒泡:使用在内层事件-->
      <div class="demo1" @click="showInfo">
        <button @click.stop="showInfo">点击提示</button>
        <a href="http://www.baidu.com" @click.stop.prevent="showInfo">点击提示</a>
      </div>

      <!-- 事件只触发一次 -->
      <button @click.once="showInfo">点击提示</button>

      <!-- 使用事件的捕获模式:使用在外层事件 -->
      <div class="box1" @click.capture="showMsg(1)">
        div1
        <div class="box2" @click="showMsg(2)">div2</div>
      </div>

      <!-- 只有event.target是当前操作元素时才触发事件 -->
      <div class="demo1" @click.self="showInfo">
        <button @click="showInfo">点击提示</button>
      </div>

      <!-- 事件的默认行为立即执行:优先使用滚动(移动端使用) -->
      <!-- scroll:(滚动条)滚动到最后位置就会停止 -->
      <!-- wheel:(滚轮)鼠标滚动轮滚动:会一直触发 -->
      <ul @wheel.passive="demo" class="list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
      </ul>
    </div>
<script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        name: "xue",
      },
      methods: {
        showInfo(e) {
          alert("同学你好");
          //   e.stopPropagation(); //阻止事件冒泡
          console.log(e.target);
        },
        showMsg(msg) {
          console.log(msg);
        },
        demo() {
          for (let i = 0; i < 10000; i++) {
            console.log("#");
          }
          console.log("运行结束");
        },
      },
    });
  </script>

 3. 键盘事件(按下键盘或者键盘弹起执行事件)

  • 回车: => enter

  • 删除: => delete (捕获“删除”和“退格键”)

  • 退出: => esc

  • 空格: => space

  • 换行: => tab  (注意使用keydown事件进行配合)

  • 上: => up

  • 下: => down

  • 左: => left

  • 右: => right

  • Vue未提供别名的按键,可以使用按键原始的key值去绑定,但注意要为kebab-case(横线拼接小写英文命名)

<input type="text" placeholder="按下回车提示输入" @keyup.caps-lock="showInfo" />
系统修饰键:ctrl 、 alt、shift、meta(通过链式指定配合按键)
            (1)配合keyup使用,按下修饰键的同时,再按下(任意)其他键,最后释放其他键,事件才被触发(不太好:键盘事件弹起就会执行修饰键工作)
            (2)配合keydown使用,正常触发事件(简便)
<input type="text" placeholder="按下回车提示输入" @keyup.ctrl="showInfo" />
<input type="text" placeholder="按下回车提示输入" @keydown.ctrl="showInfo" />
  • (NO)也可以使用keyCode指定具体的按键值(不推荐键码)

<input type="text" placeholder="按下回车提示输入" @keydown.13="showInfo" />
  • (NO)Vue.config.keyCodes.自定义键名 = 键码,可以定制按键别名

<input type="text" placeholder="按下回车提示输入" @keydown.13="showInfo" />

<!--以下是在vue中自定义键名-->
Vue.config.keyCodes.huiche = 13; //自定义按键别名

二、计算属性

输入并实现插值语法拼接效果

 1.使用插值语法进行拼接:优势:缓存优势

 <body>
    <div id="root">
      姓:<input type="text" v-model="firstName" />
      <br />
      名:<input type="text" v-model="lastName" />
      <br />
      <!-- 截取指定位置的字符串拼接 -->
      全名:<span>{{firstName.slice(0,3)}}-{{lastName}}</span>
    </div>
  </body>
  <script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        firstName: "张",
        lastName: "三",
      },
    });
  </script>

 2. 使用methods实现拼接(插值语法调用方法需要带()

 <div id="root">
      姓:<input type="text" v-model="firstName" />
      <br />
      名:<input type="text" v-model="lastName" />
      <br />
      <!-- 插值语法中使用方法必须使用() -->
      全名:<span>{{fullName()}}</span> <br />
       <!--调用多少次methods就会执行多少次:没有缓存-->
      全名:<span>{{fullName()}}</span> <br />
      全名:<span>{{fullName()}}</span> <br />
      全名:<span>{{fullName()}}</span>
  </div>
 
<script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        firstName: "张",
        lastName: "三",
      },
      methods: {
        fullName() {
          // 以下输出语句证明:data数据修改之后函数重新调用(说明模板重新解析)
          console.log("@-------------------");
          return this.firstName + "-" + this.lastName;
        },
      },
    });
  </script>

3. 计算属性实现拼接:cumputed注意要有返回值

  • 底部规则使用的还是Object.defineProperty中的getter

  • 优势:计算属性中的方法的依赖数据有缓存属性,在执行多次输出相同结果调用时候只需要执行一次计算

    <div id="root">
      姓:<input type="text" v-model="firstName" />
      <br />
      名:<input type="text" v-model="lastName" />
      全名:<span>{{fullName}}</span><br />
    </div>
 computed: {
        // 具有缓存属性,当出现模板中相同代码片段时候直接从缓存处读取
        fullName: {
          // get作用:当有人读取fullName,get就会被调用,并且返回值就是fullName的值
          // get什么时候调用
          /* 
          1. 初次读取fullName时候调用
          2. 所依赖的数据发生变化
          */
          //  ----------------------
          // 注意以下的get和set不可以使用箭头函数,this的指向变成window
          get() {
            // console.log(this);//此处的this指向vm
            console.log("get调用");
            return this.firstName + "-" + this.lastName + a;
          },
          // 如果计算属性会被修改就必须存在setter
          //当fullName被修改时候会被调用
          set(value) {
            console.log("set", value);
            // 字符产转为数组
            const arr = value.split("-");
            this.firstName = arr[0];
            this.lastName = arr[1];
          },
        },
      },

 定义:要用的属性不存在,要通过已有的属性计算得来

  • 原理:底层借用了Object.defineproperty方法提供的getter和setter

  • get函数什么时候执行

            (1)初次读取会执行一次

            (2)当数据发生变化时候会被再次调用

  • 优势:与methods实现相比,内部有缓存机制(可复用),效率高,调用方便

  • 备注:

          1. 计算属性最终会出现在vm上,直接读取使用即可

          2. 如果计算属性要被修改,必须写set函数相应修改,并且set中要应用引起计算时依赖的数据发生改变

如果计算属性确定只读不改:那么只编译getter

 全名:<span>{{fullName}}</span>

//
computed: {
  // 简写:没有set  只读不取
  // 将原先的函数简写以下格式
  // 此处将函数放在vm实例中
  fullName() {
    console.log("get调用");
    return this.firstName + "-" + this.lastName;
  },
},

三、监视属性

实现效果

 1. 利用计算属性进行:三元表达式利用方法切换布尔值

  <div id="root">
      <h2>今天天气很{{info}}</h2>
      <button @click="changeWeather">切换</button>
    </div>
  </body>
  <script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        isHot: true,
      },
      // 方法执行取反布尔值
      methods: {
        changeWeather() {
          this.isHot = !this.isHot;
        },
      },
      // 利用三元表达式进行计算并返回结果,也可以将计算表达式直接写入插值语法
      computed: {
        info() {
          return this.isHot ? "炎热" : "凉爽";
        },
      },
    });
  </script>

 2.理解:监视属性

watch:{

监视属性:{

immediate:true(默认false):初始化就调用一次

监视回调函数

}

}

  <div id="root">
      <h2>今天的天气很{{info}}</h2>
      <button @click="changeWeather">切换天气</button>
    </div>
    watch: {
        isHot: {
          immediate: true, //默认fasle,设置为true会初始化时候调用handler
          // 注意之前没有值就是undefined
          // handler什么时候调用?当isHot发生变化时候调用
          handler(newVlaue, oldValue) {
            console.log("inHot被修改了", newVlaue, oldValue);
          },
        },
      },
//在Vue实例之外配置watch属性
vm.$watch("isHot", {
  immediate: true,
  handler(newVlaue, oldValue) {
    console.log("inHot被修改了", newVlaue, oldValue);
  },
});

 简写监视属性:在没有immedit属性的时候才可以使用

  // 简写:绝不允许使用箭头函数(改变了this指向)
    vm.$watch("isHot", function (newVlaue, oldValue) {
      console.log("inHot被修改了", newVlaue, oldValue);
    });

3. 深度监视:监测到data对象中更深层对象的数据

deep:true : 监测深层

"numbers.a" :监测指定深层某个数据

<div id="root">
      <h2>今天的天气很{{info}}</h2>
      <button @click="changeWeather">切换天气</button>
      <hr />
      <h3>a的值是{{numbers.a}}</h3>
      <button @click="numbers.a++">点击让我+1</button>
      <h3>b的值是{{numbers.b}}</h3>
      <button @click="numbers.b++">点击让我+1</button>
      <!-- 此处使用新的对象:就更改了原先的地址值 -->
      <button @click="numbers = {a:666,b:888}">彻底替换number</button>
    </div>
 <script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        isHot: true,
        numbers: {
          a: 1,
          b: 1,
        },
      },
      computed: {
        info() {
          return this.isHot ? "炎热" : "寒冷";
        },
      },
      methods: {
        changeWeather() {
          this.isHot = !this.isHot;
        },
      },
      watch: {
        isHot: {
          handler(newVlaue, oldValue) {
            console.log("inHot被修改了", newVlaue, oldValue);
          },
        },

        // 以下是多级结构进行监视
        // 注意存在多个属性:所有的属性都添加到下main(太麻烦)
        "numbers.a": {
          handler() {
            console.log("a发生改变");
          },
        },
        "numbers.b": {
          handler() {
            console.log("b发生改变");
          },
        }, 
        // 此处检测的是整个对象(一个地址):但是添加deep属性就不一样了
        numbers: {
          deep: true,
          handler() {
            console.log("numbers改变了");
          },
        },
      },
    });
  </script>

4. 对比计算属性和监视属性

  • computed能完成的功能watch都可以完成

  • watch能完成的功能(主要优势异步任务),computed不一定能完成

  • 注意:

    • 所有被Vue管理的函数,最好写成普通函数,这样this的指向才是vm或者组件实例对象。

    • 所有不被Vue管理的函数(定时器回调函数,ajax回调函数,promise的回调函数),最好写成箭头函数,这样this的指向才是vm或组件实例对象

<div id="root">
      姓:<input type="text" v-model="firstName" />
      <br />
      名:<input type="text" v-model="lastName" />
      <br />
      全名:<span>{{fullName}}</span>
    </div>
  </body>
  <script>
    Vue.config.production = false;
    const vm = new Vue({
      el: "#root",
      data: {
        firstName: "张",
        lastName: "三",
        fullName: "张-三",
      },

      // 监视属性:拼接字符
      // 既需要监视姓也需要监视名(繁琐)
      // 优势:可以开启异步任务(计算属性不可以添加异步任务)
      // 注意:添加定时器时候回调函数应该是箭头函数:普通函数this指向window,箭头函数会向上找this,指向的是vm
      watch: {
        firstName(val) {
          setTimeout(() => {
            console.log(this);
            this.fullName = val + "-" + this.lastName;
          }, 1000);
        },
        lastName(val) {
          this.fullName = this.lastName + "-" + val;
        },
      },
    });
  </script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值