方法 methods

  • 每次渲染都会执行一次
  • 事件处理函数或普通函数
    • 事件处理函数:若把函数写在 method 外,则会报错:[函数] is not defined
    • 普通函数:可代替 filters
  1. new Vue({
  2. data() {
  3. return {
  4. n:0,
  5. array: [1, 2, 3, 4]
  6. }
  7. },
  8. template:`
  9. <div>
  10. {{n}}
  11. <button @click="add"> +1 </button>
  12. <br>
  13. {{ filter() }}
  14. </div>
  15. `,
  16. methods: {
  17. add() {
  18. this.n += 1
  19. },
  20. // methods 方法每次渲染都会执行一次,因此点击 +1 button, add 与 filter 方法都会执行
  21. filter() {
  22. return this.array.filter(i => i % 2 === 0)
  23. }
  24. }
  25. })

计算属性 computed

  • vue 的计算选项,用于存放计算出来的属性
  • 根据依赖是否变化来缓存
  • getter/setter 默认不做缓存,Vue 做了特殊处理

实现字符串反转功能:

  1. <div id="app">
  2. <p>
  3. Original message: "{{ message }}"
  4. </p>
  5. <p>
  6. Reversed message: "{{ reverseMessage }}"
  7. </p>
  8. </div>
  1. var vm = new Vue({
  2. el: '#app',
  3. data: {
  4. message: 'Hi'
  5. },
  6. computed: {
  7. // 作用于 vm.reverseMessage 的 getter 函数
  8. reverseMessage: function() {
  9. return this.message.split(''.reverse().join(''))
  10. }
  11. }
  12. })
  13. console.log(vm.reverseMessage) // "iH"
  14. // vm.reverseMessage 的值依赖于 vm.message
  15. // vm.message 发生改变时,vm.reverseMessage才发生变化
  16. vm.message = 'Ha'
  17. console.log(vm.reverseMessage) // "aH"

也可以通过方法实现同样功能:

  1. <p>
  2. {{reverseMessage}}
  3. </p>
  1. methods:{
  2. reverseMessage: function(){
  3. return this.message.split('').reverse().join('')
  4. }
  5. }

计算属性的 setter

  1. var vm = new Vue({
  2. el: '#demo',
  3. data: {
  4. firstName: 'Foo',
  5. lastName: 'Bar',
  6. fullName: 'Foo Bar'
  7. },
  8. computed: {
  9. fullName: {
  10. // getter
  11. get: function(){
  12. return this.firstName + ' ' + this.lastName
  13. },
  14. // setter
  15. set: function(newValue){
  16. var names = newValue.split(' ')
  17. this.firstName = names[0]
  18. this.lastName = names[names.length - 1]
  19. }
  20. }
  21. }
  22. })
  23. vm.fullName = 'John Doe'
  24. console.log(vm.firstName, vm.lastName)

监听属性 watch

  • 监听的数据改变就执行回调
  • Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个 property
  • 类型{ [key: string]: string | Function | Object | Array }
  • watch 是异步的
  • 默认第一次变化不监听,若要监听,加上 immediate: true
  • 监听数据变化:默认只监听栈内存中的数据,若要监听堆内存数据,加上 deep: true
  • 不使用箭头函数,箭头函数中得 this 指向全局对象;function 中的 this 默认指向当前 Vue 实例

语法1:

  1. var vm = new Vue({
  2. data: {
  3. a: 1,
  4. b: 2,
  5. c: 3,
  6. d: 4,
  7. e: {
  8. f: {
  9. g: 5
  10. }
  11. }
  12. },
  13. watch: {
  14. a: function (newVal, oldVal) {
  15. console.log('new: %s, old: %s', newVal, oldVal)
  16. },
  17. // 方法名
  18. b: 'someMethod',
  19. // 该回调会在任何被侦听的对象的 property 改变时被调用,不论其被嵌套多深
  20. c: {
  21. handler: function (val, oldVal) { /* ... */ },
  22. deep: true
  23. },
  24. // 该回调将会在侦听开始之后被立即调用
  25. d: {
  26. handler: 'someMethod',
  27. immediate: true
  28. },
  29. // 你可以传入回调数组,它们会被逐一调用
  30. e: [
  31. 'handle1',
  32. function handle2 (val, oldVal) { /* ... */ },
  33. {
  34. handler: function handle3 (val, oldVal) { /* ... */ },
  35. /* ... */
  36. }
  37. ],
  38. // watch vm.e.f's value: {g: 5}
  39. 'e.f': function (val, oldVal) { /* ... */ }
  40. }
  41. })
  42. vm.a = 2 // => new: 2, old: 1

语法2:vm.$watch('data', fn, {deep: true, immediate: true})

data 可以

  1. new Vue({
  2. data: {
  3. n: 0
  4. }
  5. created(){
  6. this.$watch('n', function(){
  7. console.log('n 变了')
  8. }, {immediate: true})
  9. }
  10. }).$mount("#app")

三者的区别

  • computed:计算属性,将计算结果进行缓存,只有在它的响应式依赖改变时才会重新计算,不支持异步
  • methods:方法, 在每次触发重新渲染时都会执行函数,开销更大,支持异步
  • watch: 监听属性,当监听的 data 改变就执行回调,有两个选项:deep 与 immediate,支持异步