vue爬坑之路4----计算属性

计算属性

  •   基础例子

        <div id="example">

            <p>Original message:"{{ message }}"</p>

            <p>Computed reversed message:"{{ reversedMessage}}"</p>

        </div>

 

 

        var vm = new Vue{{

              el:'#exammple',

              data:{

                message:'Hello'

              },

              computed:{

          // a computed getter

            reversedMessage:function(){

          //'this' points to the vm instance

          return this.message.split('').reverse().join('')

      }

    }

  })

          结果:

            Original message:"Hello"

            Computed reversed message:"olleH"

    这里我们声明了一个计算属性 reversedMessage 。我们提供的函数将用作属性 vm.reversedMessagegetter

          console.log(vm.reversedMessage)  // ->'olleH'

            vm.message = 'Goodbye'

          console.log(vm.reversedMessage) // ->'eybdooG'

 

    打开浏览器的控制台,修改vmvm.reservedMessage 的值始终取决于 vm.message的值。

 

 

        

  •   计算缓存 vs Methods

        通过调用表达式中的method也可以达到同样的效果:

          <p>Reversed message:"{{ reverseMessage() }}"</p>

 

          //in comonet

          methods:{

            reverseeMessage:function(){

              return.message.split('').reverse().join('')

            }

          }

        不经过计算属性,我们可以再method中定义一个相同的函数来代替它。两种方式最终的结果是相同的。但是,不同点在于计算属性是基于它的依赖缓存。计算属性只有在它的相关依赖发生改变时才会重新取值。这就意味着只要message没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,不必再次执行函数。

        这意味着下面的计算属性将不会更新,因为 Data.now() 不是响应式依赖:

          computed:{

            now: function (){

              return Data.now()

            }

          }

          Data.now()  :  返回当前时间字符串

        相比而言,每当重新渲染的时候,method调用总会执行函数。

    关于缓存。假设有一个重要的计算属性A,这个计算属性需要一个巨大的数组遍历和大量的计算。然后还可能会有其他的计算属性依赖于A。如果没有缓存,我们将重复多次执行A的getter。如果不希望有缓存,用method代替。

  •   计算属性 vs Watched Property

        Vue.js提供了一个方法 $watch,用于观察Vue实例上的数据变动。当一些数据需要根据其他数据变化时,$watch可以胜任。不过,通常更好的办法是用用计算属性而不是一个命令式的$watch回调。思考下面的例子:

        <div id='demo'>{{ fullName }}</div>

        var  vm = new Vue{(

          el:'#domo',

          data: {

            firstName:'Foo',

            lastName:'Bar',

            fullNae:'Foo Bar'

        },

          watch: {

            firstName: function (val) {

              this.fullName = val + ' '+this.lastName

            },

            lastName: function (val) {

              this.fullName = this.firstName + ' ' +val

            }

            }

    })

        上面的代码时命令时的和重复的。与计算属性相比:

          var vm = new Vue({

            el:'#demo',

            data: {

              firstName: 'Foo',

              lastName: 'Bar'

             },

            computed: {

              fullName: function () {

                return this.firstName + ' ' +this.lastName

                }

              }

            })

        这样更好。

  •   计算 setter

        计算属性默认只有geter,不过在需要时我们也可以增加一个setter:

          

            //...

            computed:{

              fullName: {

                  //getter

                get: function (){

                  return this.firstName +' '+ this.lastName 

                  },

                set: function (newValue){

                  var names = newValue.split('  ')

                  this.firstName = names[0]

                  this.lastName = names[names.length - 1 ]

                }

               }

              }

            //...

          现在在运行 vm.fullName = 'John Doe'时,setter会被调用,John Doe会被存入setter,vm.firstName和vm.lastName也会被对应更新。

 

观察 watchers

        虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的watcher。这是为什么Vue提供一个通用的方法通过watch选项,来响应数据的变化。当你想要在数据变化响应时,执行一步操作或开销较大的操作,这是很有用的。

    例如:

          <div id='watch-example'>

              <p>

                Ask a yes/no question:

              <input v-model='question'>

              </p>

              <p>{{ answer }}</p>

            </div>

 

 

          <script src='https://unpkg.com/axios@0.12.0/dist/axios.min.js></script>

          <script src='http://unpkg.com/lodash@4.13.1/lodash.min.js'></script>

          <script>

            var watchExampleVM = new Vue({

                el:'#watch-example',

                data: {

                    question: ' ',

                    answer: 'I cannot give you an answer until you ask a question'

                  },

                watch: {

                     //如果question发生改变,这个函数就会运行

                  question: function (newQuestion){

                      this.answer = 'Waiting for you to stop typing...'

                      this.getAnswer()

                    }

                  },

                 method:{

          //.debounce 是一个通过lodash限制频率的函数。

          //在这个例子中,我们希望限制访问yesno.wtf/api的频率

          //ajax请求知道用户输入完毕才会发出

          getAnswer:_.debounce(

            function () {

                if(this.questuon.indeOf('?') === -1){

                  this.answer = 'Questions usually contain a question mark.;-)'

                  return

                }

                this.answer='Thinking...'

                var vm = this 

                 axios.get('https://yesno.wtf/api')

                    .then(function (response){

                      vm.answer=_.capitalize(response.data.answer)

                    })

                    .catch(function (error){

                       vm.answer = 'Error! Could not  reach the API.'+error

                    })

                },

           这是我们为用户停止输入等待的毫秒数

          )

        }

      })

    </script>

 

  在这个实例中,使用watch选项允许我们执行异步操作(访问一个API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这是计算属性无法做到的。

posted @ 2017-04-05 11:11  我爱米稀饭  阅读(173)  评论(0编辑  收藏  举报