简介
说明
本文介绍Vue的computed与watch的区别。
官网
计算属性和侦听器 — Vue.js
API — Vue.js
computed与watch对比
| 项 | computed | watch | 
| 使用的格式 | 必须监听存在的属性(data、props、computed) | 不能和data定义的变量相同 | 
| 类型 | 是一个函数。 | 函数或者是对象。 | 
| 异步 | 不支持异步。 在computed里面操作异步无效。 | 支持异步 | 
| 触发时机 | 初始化时就可被监听到并且计算 | 发生改变的时候才会触发 | 
| 缓存 | 支持缓存。 依赖数据发生改变才重新计算。 | 不支持缓存。 每次都重新计算。 | 
| 依赖的数量 | 依赖的数据可以是1个,也可以是多个。 | 依赖的数据是1个。 | 
| 使用场景 | 一个属性依赖于多个属性。 | 某个属性变动时进行一些操作。 | 
computed
简介
computed是一个函数,要有返回值。
函数的返回值就是属性的属性值。
默认走getter(必须有返回值)。
示例
代码
Demo.vue
<template>
  <div class="hello">
    <input v-model.number="num1" type="number">+
    <input v-model.number="num2" type="number">=
    {{ num3 }}
  </div>
</template>
<script>
export default {
  name: 'Demo',
  data() {
    return {
      num1: 0,
      num2: 0
    }
  },
  computed: {
    num3() {
      return this.num1 + this.num2
    }
  },
}
</script>
<style scoped>
</style>路由(store/index.js)
import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})测试
访问:http://localhost:8080/#/demo

输入数字
watch
简介
watch可以是函数,也可以是对象。
如果是函数
监听的函数接收两个参数,第1个参数是新值;第2个参数是旧值。
如果是对象
有三个属性:handler、immediate、deep。
- handler
- 是监听的处理器。
- 跟函数写法基本一样。也是:第1个参数是新值;第2个参数是旧值。
- immediate
- 默认第一次绑定的时候不执行函数。即:默认为false。
- 如果想要绑定时就执行可设置immediate属性为true。
- deep
- 深度监听
- 如果监听一个对象,对象里的某个属性发生变化是触发不到函数的。
- 加上deep:true可以监听到对象里的属性。但是这样会为该对象中的所有属性都添加上该属性,任何属性发生变化都会触发函数。
- 若只监听某个属性,可采用"对象名.属性名"的字符串作为监听对象属性。
- 一维二维数组是不需要深度监听的,但是数组里面有对象也是需要深度监听的。
示例:函数写法
代码
Demo.vue
<template>
  <div class="hello">
    <input v-model.number="num1" type="number">+
    <input v-model.number="num2" type="number">=
    {{ num3 }}
  </div>
</template>
<script>
export default {
  name: 'Demo',
  data() {
    return {
      num1: 0,
      num2: 0,
      num3: 0
    }
  },
  watch: {
    num1(newVal, oldVal) {
      console.log('num1=> oldVal: ' + oldVal);
      console.log('num1=> newVal: ' + newVal);
      this.num3 = this.num1 + this.num2
    },
    num2(newVal, oldVal) {
      console.log('num2=> oldVal: ' + oldVal);
      console.log('num2=> newVal: ' + newVal);
      this.num3 = this.num1 + this.num2
    }
  },
}
</script>
<style scoped>
</style>路由(store/index.js)
import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})测试
测试1:访问
访问:http://localhost:8080/#/demo

测试2:修改属性的值
示例:对象写法
代码
Demo.vue
<template>
  <div class="hello">
    <input v-model.number="num1" type="number">+
    <input v-model.number="num2" type="number">=
    {{ num3 }}
  </div>
</template>
<script>
export default {
  name: 'Demo',
  data() {
    return {
      num1: 0,
      num2: 0,
      num3: 0
    }
  },
  watch: {
    num1: {
      // 这里第一个参数是新值,第二个是老值。
      handler(newVal, oldVal) {
        console.log('num1=> oldVal: ' + oldVal);
        console.log('num1=> newVal: ' + newVal);
        this.num3 = this.num1 + this.num2;
      },
      immediate: true
    },
    num2: {
      // 这里第一个参数是新值,第二个是老值。
      handler(newVal, oldVal) {
        console.log('num2=> oldVal: ' + oldVal);
        console.log('num2=> newVal: ' + newVal);
        this.num3 = this.num1 + this.num2;
      }
    },
  },
}
</script>
<style scoped>
</style>路由(router/index.js)
import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})测试
测试1:访问
访问:http://localhost:8080/#/demo

可以看到,如果设置了immediate为true,则一进去就会触发。
测试2:修改属性值
示例:对象写法(监听部分属性)
代码
Demo.vue
<template>
  <div class="hello">
    <input v-model.number="data1.num" type="number">+
    <input v-model.number="data2.num" type="number">=
    {{ num3 }}
  </div>
</template>
<script>
export default {
  name: 'Demo',
  data() {
    return {
      data1: {
        num: 0,
      },
      data2: {
        num: 0,
      },
      num3: 0
    }
  },
  watch: {
    'data1.num': {
      // 这里第一个参数是新值,第二个是老值。
      handler(newVal, oldVal) {
        this.num3 = this.data1.num + this.data2.num;
      },
      immediate: true
    },
    'data2.num': {
      // 这里第一个参数是新值,第二个是老值。
      handler(newVal, oldVal) {
        this.num3 = this.data1.num + this.data2.num;
      }
    },
  },
}
</script>
<style scoped>
</style>路由(router/index.js)
import Vue from 'vue'
import Router from 'vue-router'
import Demo from "../views/Demo";
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/demo',
      name: 'Demo',
      component: Demo,
    }
  ],
})测试
访问:http://localhost:8080/#/demo









