computed

123 阅读1分钟

  computedmethodwatch都是vue中非常重要也是非常常用的几个API。他们三者之间有什么区别呢?首先我们来对比一下computedmethod,下面来看一个案例:

   <!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>Document</title>
      </head>
      <body>
        <script src="https://unpkg.com/vue@next"></script>
        <div id="app">
          <div>{{fristName + lastName}}</div>
          <div>{{getFullName()}}</div>
          <div>{{getFullName()}}</div>
          <div>{{getFullName()}}</div>
        </div>
        <script>
          Vue.createApp({
            data() {
              return {
                fristName: 'John',
                lastName: 'Doe',
              }
            },
            methods: {
              getFullName() {
                return `${this.fristName} ${this.lastName}`
              },
            },
          }).mount('#app')
        </script>
      </body>
    </html>

  我们尝试将fullName渲染出来,一种是直接将fristNamelastName拼接,另一种方法是使用method返回以一个方法将两者拼接。虽然是同样的效果,显然第二种方法更有封装性。那么这样是最好的解决方案吗?并不是。在这个案例上,method有两个缺点。第一fullName明明是一个属性值,而我们却使用调函数的方法来返回它,这不是非常的合适。第二如果我们要多次使用fullName时,那么method将会调用多次,这会造成性能的浪费。 截屏2022-04-27 21.06.02.png

  所以我们可以使用我们的computed计算属性来完成这个案例:

   <!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>Document</title>
      </head>
      <body>
        <script src="https://unpkg.com/vue@next"></script>
        <div id="app">
          <div>{{fristName + lastName}}</div>
          <div>{{ fullName }}</div>
          <div>{{ fullName }}</div>
          <div>{{ fullName }}</div>
          <div>{{getFullName()}}</div>
          <div>{{getFullName()}}</div>
          <div>{{getFullName()}}</div>
        </div>
        <script>
          Vue.createApp({
            data() {
              return {
                fristName: 'John',
                lastName: 'Doe',
              }
            },
            methods: {
              getFullName() {
                console.log(`methods中的fullName`)
                return `${this.fristName} ${this.lastName}`
              },
            },
            computed: {
              fullName() {
                console.log(`computed中的fullName`)
                return `${this.fristName} ${this.lastName}`
              },
            },
          }).mount('#app')
        </script>
      </body>
    </html>

截屏2022-04-27 21.11.02.png

  computed就很好地解决了这个问题。如图计算属性fullName调用了多次而只打印了一次,具有缓存特性,且并不需要使用括号调用,更符合编程习惯。实际上上图的代码computed只是一个语法糖,他的完整写法是含有gettersetter的一个对象。

   computed: {
     fullName: {
       get(){
         console.log(`computed中的fullName`)
         return `${this.fristName} ${this.lastName}`
       },
       set(newValue){
         console.log(`computed中的fullName`)
         const names = newValue.split(' ')
         this.fristName = names[0]
         this.lastName = names[1]
       }
     }
   },