VUE - 5 - VUE的计算属性和侦听器

本文通过一个综合案例详细介绍了Vue.js中计算属性computed和侦听器watch的使用,包括它们的定义、工作原理及应用场景。计算属性提供缓存机制,适用于基于响应式数据的简单计算;侦听器则用于监听特定属性的变化,执行自定义操作。在选择计算属性和侦听器时,推荐优先使用计算属性。文章还对比了计算属性与表达式、方法以及侦听器的区别,并提供了多种实现同一效果的不同方式。
摘要由CSDN通过智能技术生成

综合案例

先看一个综合的案例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性和侦听器</title>
    <link rel="icon" href="../logo.svg">
</head>
<body>    
    <div id="root">
        <input type="text" v-model="title" />
        <h1>表达式:{{title.split('').reverse().join('')}}</h1>
        <h1>计算属性:{{reTitle}}</h1>
        <h1>方法:{{reverTitle() }}</h1>
        <h1>侦听器:{{reverseTitle}}</h1>
    </div> 
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    Vue.config.productionTip=false;
    var vm = new Vue({
        el:"#root",
        data:{ //数据
            title:"Hello World!",
            msg:"Vue",
            reverseTitle:"",//侦听器需要提提前定义好一个承接新数据的属性
        },
        computed:{ //计算属性
            reTitle(){return this.title.split('').reverse().join('')}
        },
        methods: {//方法
            reverTitle(){return this.title.split('').reverse().join('')}
        },
        watch:{ //侦听器
            title:{
                deep: true,
                immediate: true,
                handler:function(val, oldVal){
                    this.reverseTitle= this.title.split('').reverse().join('');
                }
            }
        }
    })
</script>
</body>
</html>

结果:
在这里插入图片描述

计算属性 computed

  • 需要的属性不存在,要通过已有的响应式属性计算得到。
  • 原理:借助底层Object.defineproperty方法提供的getter和setter。
  • get函数执行的时机
    • 初次读取时会执行一次。
    • 当依赖的数据发生变化时会被再次调用。
  • 注意:
    • 因为 getter 和 setter 的 this 上下文自动地绑定为 Vue 实例,所以getter 和 setter 函数不可以用箭头函数,否则this不再指向vue实例。
    • 计算属性默认只有 getter,不过在需要时你也可以提供一个 setter。
    • 当计算属性只需要一个getter时,可以简写成一个函数。
    • 计算属性会最终出现在vm实例上,直接读取使用即可。
    • 计算属性的结果会被缓存,除非依赖的响应式 property 变化才会重新计算(非响应式的会更新)。
  • computed的两种写法:
    <div id="root">  
        <p>姓:<input type="text" v-model="firstName"></p>       
        <p>名:<input type="text" v-model="lastName"></p>       
        <P>全名:{{fullName}}</P>
        <P>全名:{{fullName2}}</P>
    </div> 
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        Vue.config.productionTip=false;
        var vm = new Vue({
            el:"#root",
            data:{
                firstName:"张",
                lastName:"三",
    
            },
            computed:{
                // 完整写法
                fullName:{
                    get(){
                        return this.firstName + "-" + this.lastName;
                    }
                    ,set(value){
                        this.firstName = value.split("-")[0];
                        this.lastName = value.split("-")[1];
                    }
                }
                // 简写:只需要读取,不可修改时用简写形式。
                ,fullName2(){
                    return this.firstName + this.lastName;
                }
            }
        })
    </script>
    
    效果:在这里插入图片描述

侦听器 watch

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。计算属性和侦听器都可以实现的就选择计算属性。

  • 选项/ 数据/ watch

    • { [key: string]: string | Function | Object | Array }
  • 实例 property / vm.$watch

    • vm.$watch( expOrFn, callback, [options] )
    • 参数:
      • {string | Function} expOrFn
      • {Function | Object} callback
      • {Object} [options]
        • {boolean} deep
        • {boolean} immediate

案例代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>计算属性和侦听器</title>
    <link rel="icon" href="../logo.svg">
</head>
<body>    
    <div id="root">  
        <h1>{{title}}</h1>
        <p>姓:<input type="text" v-model="student.firstName"></p>       
        <p>名:<input type="text" v-model="student.lastName"></p>       
        <P>全名:{{student.firstName}}{{student.lastName}}</P>
    </div> 
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script>
        Vue.config.productionTip=false;        
        var vm = new Vue({
            el:"#root",
            data:{
                title:"侦听器",
                student:{
                    firstName:"张",
                    lastName:"三"
                }
            },
            watch:{
                title(val,oldValue){
                    console.log("title")
                    console.log('title: new: %s', val, ' old: %s', oldValue)
                },
                'student.lastName':{
                    immediate:true,
                    deep:true,
                    handler(val,oldVal){
                        console.log("lastName---")
                        console.log('lastName: new: %s', val, ' old: %s', oldVal)
                    }
                }
            }
        })
        /* //第一个参数可以是字符串:被监视vm的属性
        vm.$watch('student.firstName',function (newVal, oldVal){
            this.likes = newVal;
            console.log("firstName监视被触发:newVal ,oldVal =>",newVal, oldVal);            
        },{immediate:true, deep:true,})
        */
        //第一个参数可以是函数:侦听该函数返回的值
        var unwatch= vm.$watch(function(){
            //也可以侦听一个计算出来结果,就像监听一个未被定义的计算属性
            return this.student.firstName; //监听此函数的返回值。
        },function (newVal, oldVal){
            this.likes = newVal;
            console.log("firstName监视被触发:newVal ,oldVal =>",newVal, oldVal);            
        },{immediate:true,deep:true}) 
        // vm.$watch 返回一个取消观察函数,用来停止触发回调:之后取消观察, unwatch()
    </script>
</body>
</html>

结果展示:
在这里插入图片描述


回顾一下开始的综合案例,一个效果可以通过很多办法实现,可以在模板语法内部直接用表达式写逻辑,可以用方法,可以用计算属性,也可以用侦听器,条条大路通罗马。但是每一个方法之间还是有区别的。

计算属性 VS 侦听器

  • 计算属性 VS 表达式
    • 模板内虽然可以用表达式处理简单的逻辑,但是这样会导致代码的易读性太差。
    • 所以模板内最好只放数值或字符串类型的值。
  • 计算属性 VS 方法
    • 在表达式中调用方法可以达到同样的效果。
    • 但是计算属性是基于它们的响应式依赖进行缓存的。
    • 每当触发重新渲染时,调用方法将总会再次执行函数。
  • 计算属性 vs 侦听属性:
    • 当有一些数据需要随着其它数据变动而变动时,如果计算属性和侦听器都可以实现,就选择计算属性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值