computed

computed:相当于method,返回function内return的值赋值在html的DOM上。但是多个{{}}使用了computed,computed内的function也只执行一次。仅当function内涉及到Vue实例绑定的data的值的改变,function才会从新执行,并修改DOM上的内容。

computed和method的对比

<div id="example">
  {{ message.split('').reverse().join('') }}
</div>

这个是vue官网一直拿来作为例子的代码。在{{}}可以很方便的放入单个表达式,但是当一个HTML的DOM里面存在太多的表达式,程序会变得很笨重难于维护。

html

<div id="app9">
    9、method与computed的区别<br/>
    fullName<br/>
    {{fullName}}<br/>
    fullName2<br/>
    {{fullName}}<br/>
    fullNameMethod<br/>
    {{getFullName()}}<br/>
    fullNameMethod2<br/>
    {{getFullName()}}<br/>
</div>

js

var app9 = new Vue({
    el: '#app9',
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    methods:{
        getFullName:function () {
            console.log("执行了methods")
            return this.firstName+" " +this.lastName;
        }
    },
    computed: {
        fullName: function () {
            console.log("执行了computed")
            return this.firstName + ' ' + this.lastName
        }
    }
})
setTimeout('app9.firstName="Foo2"',3000);

控制台输出的结果
执行了computed
执行了methods
执行了methods
执行了computed
执行了methods
执行了methods

由此可见使用computed,function只会执行一次。当Vue实例中绑定的data数据改变的时候,computed也相对应的只改变一次。

相同点:在以上代码中,两个p标签都会打印出同样被反转的Hello。
不同点:
使用了methods的:HTML中,每一个调用了Vue的methods的方法,都需要执行一遍reversedMessage()这个方法;
而使用computed计算属性的,只执行一遍将结果保存在缓存中。

computed和watch的对比

html

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

js

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: '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
    }
  }
})

watch可以监听数据的改变(不能监测数据内部的改变),但是如果使用不当就是多此一举了。
比如以上这个例子,使用watch监听firstName和lastName两个数据,其实就相当于computed,function内使用了Vue实例绑定的firstName和lastName。

setter

computed有getter属性也有setter属性,默认只有getter。
这个比较简单,贴个官网的代码就好了。

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}
vm.fullName = 'John Doe';//此时触发set函数

watch

比较适合watch的场景,监听input的输入

<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="https://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()
    }
  },
  methods: {
    getAnswer: _.debounce(
      function () {
        if (this.question.indexOf('?') === -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
          })
      },
      // 这是我们为用户停止输入等待的毫秒数
      //_.debounce 0.5秒内刷新就不执行函数
      500
    )
  }
})
</script>
Logo

前往低代码交流专区

更多推荐