vue计算属性computed && 侦听器watch

一、计算属性

1.vue中的计算属性:

(1)提供了和data数据属性一样的属性,页面渲染调用数据时使用一样的语法规则(直接调用属性值,不需要再执行方法)

<body>
//调用data变量
   <p>data-info:{{ info }}</p>
//调用computed变量
   <p>computed-msg:{{ msg }}</p>
</body>
<srcipt>
    createApp({
            data() {
                return {
                    info: "data属性info",
                }
            },
            computed: {
                // key 属性名,value是执行方法,但必须存在return提供属性返回值
                msg: function () {
                    return "计算属性msg"
                }
            }
</script>

(2)但是又能兼顾vue方法属性中的逻辑操作(计算属性中的this指向vue的当前应用实例)

2.计算属性的特性:

(1)默认情况下计算属性构建的变量为只读变量,只能读取,不能修改;当通过页面来试图修改计算属性的变量值时,会打印 readonly 警告!

(2)通过对象取值的配置,可以实现计算属性的双向操作功能(即页面修改能修改计算属性变量,计算属性变量渲染到页面)

3.应该场景:

(1)可以将页面的相关赋值逻辑操作定义在计算属性中,页面直接调用计算属性的返回值来达到控制逻辑的效果,简化页面模板语法的定义;

(2)计算属性具有缓存特性,可以通过缓存规则,减少多次调用属性时的逻辑操作方法的调用的次数,提升运行性能;

       计算属性的缓存功能,在所依赖的变量没有发生变化时,计算属性不会触发重新计算,只有当计算属性所依赖的变量变化时,他才会再次触发计算属性;

(3)通过计算属性的双向操作功能(对象形式取值,通过get(),set()方法),可以将页面具有双向功能,但是逻辑不同的操作模拟成普通属性的双向功能;

<p>username:{{ username }}</p>
<input type="text" v-model="username">
//input框修可以通过set方法来修改username的值
<script type="module">
     createApp({
        data(){
           _username:'测试数据'
        },
        computed: {
             username:{
                    get:function(){
                        // 计算属性的取值操作
                        return this._username
                    },
                    set:function(nv){
                        // 计算属性的赋值操作
                        console.log(nv);
                        this._username = nv;
                    }
                }
            },
        }
<script>

4.不可使用计算属性来替代方法属性的场景(计算属性无法传参)

        当页面需要计算的数据为循环的临时变量时,此时的计算功能只能使用methods方法属性来实现,因为在计算属性中的函数是无法传参的;

<ul>
      <!-- 将list数据以百分比的形式渲染在页面上 -->
      <li v-for="(item, index) in list" :key="index">{{ percent(item) }}</li>
</ul>
<script>
     createApp({
      data(){
        return {
          list:[0.5,0.3,0.6,1]
        }
      },
     methods: {
        percent(v){
          return v * 100 + "%"
        }
      },
    }).mount("#app")
</script>

二、侦听器 watch

数据侦听器:当我们想对某一变量的变化进行实时监听状态时,需要使用vue的侦听器

                        数据可以是data数据变量,也可以是计算属性中的变量;

1.基本数据类型监听,浅监听就可以解决;

2.引用数据类型监听,需要深度监听;

语法结构:

watch:{ 需要监听的变量:Function(newValue,oldValue){ 函数体 } }

watch:{ 需要监听的变量:{ handler: Function(newValue,oldValue){ 函数体 }  } ,[options]   }

简单代码示例如下:

<body>
  <div id="app">
    <!-- 
      数据侦听器:
        在vue中,当我们想对某一变量的变化实现监听它的状态时,侦听器可以实现;(数据可以是data数据,也可以是计算属性中的数据)
     -->
     <!-- 1.基本数据类型 -->
     <p>msg:{{ msg }}</p>
     <input type="text" v-model=" msg ">

     <!-- 2.引用数据类型===数组 -->
     <p>arr:{{ arr }}</p>
     <input type="button" @click=" arr = ['张三','李四']" value="替换数组">
     <input type="button" value="修改arr[0]" @click=" arr[0] = 88">

     <!-- 3.引用数据类型====对象 -->
     <pre>user:{{ user }}</pre>
     <input type="text" v-model="user.name" placeholder="user.name">
     <input type="text" v-model="user.age" placeholder="user.age">
  </div>
  <script type="module">
    import { createApp } from '../assets/vue/3.0/vue.esm-browser.js'
    createApp({
      data(){
        return {
          msg:'测试数据',
          arr:[1,2,3],
          user:{ 
            name:'tom',
            age:18
          },
         info:"info"
        }
      },
      watch:{ 
        /* watch是以对象的形式呈现,那么watch中的语法 key--value值
          key==> 需要监听的变量名
          value===> 取值为函数,当监听的数据发生变化时,函数被调用
                  函数有两个固定形参(newValue,oldValue),代表变化前的值和变化后的值
        */
       // 1.默认浅监听
       msg:function(nv,ov){
        console.log('msg监听器触发',nv,ov);
       },
       arr:{ 
        handler:function(nv,ov){
          console.log('watch-arr监听器触发',nv,ov);
        },
        //deep配置项取值是Boolean值,默认为false,表示浅监听,true时表示深度监听,即可以监听引用数据类型的堆内存中的值的变化;
        deep:true
       },
       user:{ 
        handler:function(nv,ov){
          console.log('watch-user监听器触发',nv,ov);
        },
        deep:true
       },
       //单独监听对象的具体项,使用 .key的方式来
       "user.name":{
          handler:function(nv,ov){
            console.log('watch-user.name监听器触发',nv,ov);
          },
          deep:true
       },
       //默认监听是 在第一次加载的时候,不会触发监听器,只有在所监视的数据发生变化的时候,监听器才会被触发,immediate 默认值false , 页面首次加载不会执行该监视方法
       info:{
             handler(nv,ov){
                 console.log("watch-info=变量发生变换",nv,ov);
             },
                immediate:true
         }
      }

    }).mount("#app")
  </script>
</body>

三、this.$watch

通过vue提供的应用实例方法 $watch 完成变量监视器的定义;

$watch定义的监视器会返回一个 关闭该监视器的回调方法;

语法:

 vue实例.$watch(expOrFn, callback, [options])

                + expOrFn : 接收被监控的变量的名称 或者 和监控变量有关的方法

                                + 定义字符串表达式时,等效于对变量直接完成监控控制

                                 + 定义方法且方法返回值绑定了相关变量,等同于对绑定的所有变量统一完成监控

                + callback : 变量发生变化时执行的回调函数

                + options : 取值 Object ,用于定义除handler以外的其它监视配置(深度监控,初始调用……)

 问题引入:

vue中如何同时对多个变量定义统一监控方法?

                方式1:通过计算属性

                方式2:通过$watch完成监控

<body>
    <div id="app">
        <p>num1:{{ num1 }}</p>
        <input type="number" v-model.number="num1">
        <p>num2:{{ num2 }}</p>
        <input type="number" v-model.number="num2">
        <p>求和:{{ num1+num2 }}</p>
        <p>求和:{{ sum }}</p>
        <hr>
        <p>msg:{{ msg }}</p>
        <input type="text" v-model="msg">
        <br>
        <input type="button" value="绑定msg监视" @click="addWatch()">
        <input type="button" value="解绑msg监视" @click="removeWatch()">
        <hr>
        <p>num3:{{ num3 }}</p>
        <input type="number" v-model.number="num3">
        <p>num4:{{ num4 }}</p>
        <input type="number" v-model.number="num4">
        <p>求和:{{ num3+num4 }}</p>
        <input type="button" value="绑定num3+num4求和监视" @click="addNumWatch()">
    </div>

    <script type="module">
        import { createApp } from "../assets/vue/3.0/vue.esm-browser.js";
        var vm = createApp({
            data() {
                return {
                    num1: 10,
                    num2: 20,
                    num3: 30,
                    num4: 40,
                    msg: "msg",
                }
            },
            computed: {
                sum() {
                    return this.num1 + this.num2
                }
            },
            watch: {
                sum(nv, ov) {
                    console.log("num1+num2求和结果变化:", nv, ov);
                }
            },
            methods: {
                addWatch() {
                    // 在应用根属性上添加一个用于中转,但不需要劫持的变量数据 - 为其他区域提供调用支持
                    //      这种中转数据变量 在vue 开发规范中建议 以 $ 开头,实现和普通劫持变量的区分
                    if(this.$unwatch) return;
                    this.$unwatch = this.$watch("msg", (nv, ov) => {
                        console.log("$watch 监控的msg发生变化", nv, ov);
                    })
                    // console.log(unwatch);
                    console.log(this);
                },
                removeWatch(){
                    if(!this.$unwatch) return;
                    this.$unwatch();
                    this.$unwatch = undefined;
                },
                addNumWatch() {
                    this.$watch(
                        () => {
                            // return this.num3+this.num4
                            // return [this.num3,this.num4]
                            return {
                                num3:this.num3,
                                num4:this.num4
                            }
                        },
                        (nv, ov) => {
                            // console.log("$watch 监控的num3+num4发生变化", nv, ov);
                            // console.log("$watch 监控的[num3,num4]发生变化", nv, ov);
                            console.log("$watch 监控的{num3,num4}发生变化", nv, ov);

                        }
                    )
                }
            }
        }).mount("#app")
    </script>
</body>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值