计算属性跟监视属性

38 阅读6分钟

计算属性

定义

计算属性是 Vue.js 中用于响应式计算的一种属性。它可以读取绑定到它上面的值,并根据这些值进行计算和更新。计算属性可以用于计算总和、平均值、计数等数据,非常适合用于响应式数据的计算。。与普通的函数方法不同,计算属性可以读取和修改其他组件或脚本的值,这使得它们非常适合用于组件之间的数据传递和更新。计算属性在 Vue.js 2.x 和 Vue.js 3.x 中都可以正常运行,并且具有很高的灵活性和可扩展性。

更简单的说:就是对其他属性进行一些列计算后得到的新的属性,它值的变化依赖于它使用的属性的值。

怎么定义一个计算属性:

 export default {  
   data() {  
     return {  
       myInputValue: ''  
     }  
   },  
   computed: {  
     myComputedProperty() {  
       return this.myInputValue.length > 0 ? this.myInputValue : 'None'  
     }  
   }  
 }

在上面的语法中,computed 是一个关键字,它告诉 Vue.js 这是一个计算属性。接着是 myComputedProperty 的名称,它是一个函数,用于计算输出值。在函数中,可以调用其他计算属性或方法,来获取输入值或上下文环境。

每当myInputValue发生改变时,myComputedProperty都会被重新计算,因此我们可以在模板中直接使用{ { myComputedProperty } }来显示全名。

总之,计算属性是 Vue.js 中非常有用的一种功能,它可以使响应式数据更加灵活和精细。通过使用计算属性,可以更快速地构建复杂的单页面应用程序。

  •  <script type="text/javascript">
     const vm = new Vue({
       el:'#root',
       data:{
         name:'aa',
         pass:'bb'
       },
     ​
       computed:{
         fullName:{
                 //计算属性(计算并返回一个新的值) fullName使用的属性为 name和pass ,
                 // name和pass也叫做fullName的依赖数据
           get(){
             return this.name + this.pass
           }
                 //set什么时候被调用?当fullName被修改的时,vm.fullName = 'section'
                 set(value){
                 this.name = value 
             }
        //注意:此处的方法 不要写成 set:()=>{}
         }        
       }
     ​
     })
     </script>
     //调用的时候 直接实例.计算属性 vm.fullName 就是输出 默认调用的get方法返回的值
     // vm.fullName = 'section' 就是赋值 默认调用 set方法
     // 没有写get() set()会报对应的错误
    

获取值的方法:通过get方法

get():当有人读取fullName时,get就会被调用,且返回值就是fullName的值

get()什么时候被调用?1:初次读取fullName的时候,2:所依赖的数据发生变化时

它跟方法的区别

计算属性是响应式的:计算属性的值会随着输入值的变化而自动更新。而普通方法则不是响应式的,每次调用都会重新计算并返回新的值

简写方式

当你的计算属性只有读取,没有设置时,才可以使用简写形式

 <script type="text/javascript">
     const vm = new Vue({
   el:'#root',
   data:{
     name:'aa',
     pass:'bb'
   },
   computed:{
        //此处的function() 就等同于 get()函数
         fullName:function(){
             return this.name + this.pass
         }
         //或者 
         fullName(){
           return this.name + this.pass
       }
     }
 </script>

监视属性

定义

监视属性是指一种能够观察对象或者数组变化的特殊属性。当对象或者数组发生变化时,监视属性会自动更新对应的视图,以保持视图和数据的同步。监视属性只能监视到对象或者数组本身的变化,而无法监视到对象或者数组中某个属性的变化。如果需要监视对象或者数组中某个属性的变化,可以使用计算属性或者使用Vue提供的$watch方法。

在 Vue.js 2.x 中,监视属性可以通过 Vue.set 和 this.$set 方法来实现。在 Vue.js 3.x 中,监视属性已经被移除,可以使用更简洁的语法来实现相同的功能。

举个例子,假设我们有一个data对象,其中包含一个名为message的属性:

 data: {
   message: 'Hello, Vue!'
 }

如果我们希望在message发生变化时执行某些操作,我们可以在Vue实例的watch选项中定义一个名为message的属性,对应的值是一个回调函数:

 watch: {
   message: function (newValue, oldValue) {
     console.log('message changed from', oldValue, 'to', newValue)
   }
 }

参数

当在watch选项中只传入一个参数时,该参数的值表示变化后的值。这是因为Vue会默认将变化前的值作为第一个参数,将变化后的值作为第二个参数传递给watch函数,而如果只传入一个参数,Vue会默认将其解析为变化后的值。

 watch: {
   message(newValue) {
     console.log('message changed:', newValue)
   }
 }
 // ---------------------------------------
 watch: {
   message(newValue, oldValue) {
     console.log('message changed from', oldValue, 'to', newValue)
   }
 } 

更多属性

deep跟immediate

如果要监视的不是对象,而是对象的某个子属性(或者说多级结构中某个属性的变化),则必须将deep属性设置为true。因为vue中的watch默认不监测对象内部值的改变,这是为了提高效率

 const vm = new Vue({
     el:'#root',
     data:{
         number:{
       a:1
     }
     }
     watch:{
       number:{
       // immediate 设置为true 则初始化时也会被监测
       immediate:true,
       // 将deep设置为true
         deep:true,
       handler(){
         console.log('number.a value has changed');
       }
     }
     //简写形式  如果只有一个handler函数则可以简写成以下形式
     number(){
       console.log('number.a value has changed');
     }
   }
 })

如果需要在初始化的时候,就进行监测则需要设置另一个属性,immediate-将其属性设置为true

计算属性跟监视属性的区别

  • 语法

计算属性和监视属性的语法不同。计算属性是一个带有computed选项的函数,而监视属性是一个带有watch选项的对象。

如何选择它们:当你需要使用异步请求时,选择监视属性watch,因为computed中无法开启异步任务

  • 用途

计算属性用于根据一个或多个已有的数据属性计算出一个新的数据属性,而监视属性用于监控数据属性的变化并执行相应的操作。计算属性的目的是为了方便模板中的数据展示和复杂逻辑的处理,而监视属性的目的是为了在数据变化时执行相应的操作,如异步请求数据等。

  • 性能与优化

计算属性有缓存机制,只有在计算属性依赖的数据发生变化时才会重新计算,否则会直接返回缓存的结果。而监视属性没有缓存机制,每次数据变化都会触发相应的回调函数,可能会影响性能。因此,如果需要频繁地访问一个数据属性,并且该属性的计算代价较大,可以使用计算属性来优化性能。

难点提升

 const vm = new Vue({
     el:'#root',
     data:{
         AA:'aa--',
         BB:'bb--'
     }
     watch:{
       AA(val){
         setTimeout(()=>{
                 this.AA = val + '_' + val
             },1000);
         // 若是不加箭头 则此时的this为windows
             setTimeout(function(){
                         this.AA = val + '_' + val
                     },1000);
     }
   }
 })

为什么此处使用的是=>函数?而不是非箭头函数

此处使用的函数setTimeout,虽然是在vue管理的函数watch中的,但执行确是js引擎(浏览器执行)执行,因此-此时this为windows 但如果,写成箭头函数,则this没有指向,它会向上层找this,而此处的上层是AA(){},此时的this是vue实例,所以写成=>后,this的指向是vue实例

一般来说vue管理的函数,如果写成普通函数,不加“=>”,则this的指向为vue实例或组件

但某个函数的执行者若是js引擎,则this的指向为window

推荐:不被vue所管理的函数,最好写成箭头函数