前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue专题 02_计算属性(computed) VS 方法(methods)

Vue专题 02_计算属性(computed) VS 方法(methods)

作者头像
用户9999906
发布2022-09-26 11:34:26
3370
发布2022-09-26 11:34:26
举报
文章被收录于专栏:学编程的GISer

先来看看用计算属性方法来实现同一效果:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>watch和computed(computed实现)</title>
    <script src="./js/vue.js"></script>
  </head>
  <body>
    <div id="root">
      <p v-html="html"></p>
      姓:<input type="text" v-model="firstName" /><br />
      名:<input type="text" v-model="lastName" /><br />
      姓名:
      <h4>计算属性实现</h4>
      <h3>{{fullName}}</h3>
      <h4>方法实现</h4>
      <h3>{{getFullName()}}</h3>
    </div>
    <script>
      const vm = new Vue({
        el: '#root',
        data: {
          firstName: '张',
          lastName: '三',
        },
        computed: {
          fullName() {
            return this.firstName + '-' + this.lastName;
          },
        },
        methods: {
          getFullName() {
            return this.firstName + '-' + this.lastName;
          },
        },
      });
    </script>
  </body>
</html>

两种方式的最终结果都是完全相同的(这里解释一下为什么会相同:当计算属性所依赖的数据发生改变时,计算属性会重新调用;当data中的任何一个数据发生变化时,Vue的模板都会重新解析一遍(Vue都会拿过来模板整体再阅读一遍),所以方法也被调用了一次)

看起来用计算属性和方法好像都可以,其实它们两个有着本质的区别:

主要区别:

1. 调用方式不同

(以上边代码为例)

  • computed在HTML中的插值语法:{{fullName}} computed定义的方法是以属性的形式访问的,和data中的属性访问形式一样
  • methods在HTML中的插值语法:{{getFullName()}} methods定义的方法,必须加上()来调用,否则会出现如下情况:

2. 是否有缓存

computed是有缓存机制的,而methods没有

验证:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>watch和computed(computed实现)</title>
   <script src="./js/vue.js"></script>
 </head>
 <body>
   <div id="root">
    姓:<input type="text" v-model="firstName" /><br />
    名:<input type="text" v-model="lastName" /><br />
    姓名:
     <h4>计算属性实现:</h4>
     <h3>①{{fullName}}</h3>
     <h3>②{{fullName}}</h3>
     <h3>③{{fullName}}</h3>
     <h3>④{{fullName}}</h3>
     <h3>⑤{{fullName}}</h3>
     <h4>方法实现:</h4>
     <h3>⑥{{getFullName()}}</h3>
     <h3>⑦{{getFullName()}}</h3>
     <h3>⑧{{getFullName()}}</h3>
     <h3>⑨{{getFullName()}}</h3>
     <h3>⑩{{getFullName()}}</h3>
     <hr>
    测试计算属性和方法的调用机制:
     <h1>{{test}}</h1>
   </div>
   <script>
     const vm = new Vue({
       el: '#root',
       data: {
         firstName: '张',
         lastName: '三',
         test: 0,
      },
       computed: {
         fullName() {
           console.log('computed');
           return this.firstName + '-' + this.lastName;
        },
      },
       methods: {
         getFullName() {
           console.log('methods');
           
           return this.firstName + '-' + this.lastName;
        },
      },
    });
</script>
 </body>
</html>

可以看到,刷新页面,初始打印一个computed,五个methods。

这说明计算属性调用了缓存机制,只打印了一次,后边的四次{{fullName}}并没有被调用(因为后四次直接获取了第一次缓存下来的值,计算属性会立即返回之前的计算结果,而不必再次执行函数。),试想一下,如果我再html中写的不是5次<h3>{{fullName}}</h3>,而是10000次甚至100000000次,如果没有缓存机制,他会执行100000000次,而有了缓存机制,它只用执行一次,后边不管多少次,直接拿第一次缓存的值即可,这大大节省了运算时间(尤其是要多次计算一个很复杂的属性的时候);方法被调用了五次,因为方法没有缓存机制,写了几次调用,函数就执行几次。

缓存机制的另外一个好处就是,当你修改计算属性所依赖的数据时,计算属性同样只会执行一次,后边任意多少次只需要拿第一次缓存下来的值即可;而方法的话,修改任意data中的值,html中写了多少次调用,就会调用多少次,这也可以从我修改firstName的值的时候,只打印一次computed,打印五次methods来验证。

3. 调用的时机不同

计算属性:只有当你修改计算属性所依赖的数据时,才会被调用(如上GIF,当我修改test的值时,计算属性没有被调用,修改firstName时才会被调用)。比如:

代码语言:javascript
复制
computed: {
  fullName: function () {
    return Date.now()
  }
}

如果计算属性改成这个,那么便不会再执行,因为Date.now()不是响应式依赖。

方法:当data中的任何一个数据发生变化时,Vue的模板都会重新解析一遍(Vue都会拿过来模板整体再阅读一遍),同时方法也会被调用(如上GIF,当我修改test和firstName的值时,方法都会被调用)。

4. 是否可以传参

计算属性不可以传参,而方法可以传参。

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />
   <meta http-equiv="X-UA-Compatible" content="IE=edge" />
   <meta name="viewport" content="width=device-width, initial-scale=1.0" />
   <title>test3</title>
   <script src="../js/vue.js"></script>
 </head>
 <body>
   <div id="root">
     <!-- 计算属性不能传参: -->
     <h1>{{fullName}}</h1>
     <!-- 方法可以传参: -->
     <h1>{{getName('大潘')}}</h1>
   </div>
   <script>
     Vue.config.productionTip = false;
     const vm = new Vue({
       el: '#root',
       data: {
         eName: 'Dapan',
         cName: '潘潘',
      },
       computed: {
         fullName() {
           return this.eName + '-' + this.cName;
        },
      },
       methods: {
         getName(name) { //接收传过来的参数:'大潘'
           return this.eName + '-' + name;
        },
      },
    });
</script>
 </body>
</html>

其他说明

computed和methods不可以重名,Vue会把 methodsdata 里的东西,全部代理到Vue生成的对象中,这会将computed中重名属性覆盖。

计算属性的简写形式:

代码语言:javascript
复制
computed: {
  fullName() {
    return this.eName + '-' + this.cName;
  },
},

而计算属性的一般形式:

代码语言:javascript
复制
fullName: {
  get() {
    return this.eName + '-' + this.cName;
  },
  set(val) {
    // 代码
  },
},

在计算属性中传入的是一个属性,而在这个属性又有两个方法(getter和setter)。在读取数据时Vue自动调用getter,在设置值时使用setter,所以我们现在能够理解,为什么使用计算属性时不需要像调用方法时在后面跟上小括号,因为我们确实只是在使用属性而已。

关注公众号:学编程的GISer,获取更多干货知识!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 学编程的GISer 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 调用方式不同
  • 2. 是否有缓存
  • 3. 调用的时机不同
  • 4. 是否可以传参
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档