《computed和watch的区别》

262 阅读1分钟

英译:

  • computed:计算属性的意思。
  • watch:监听、观察的意思。

各自的区别:

computed

1、computed是用来计算出一个值的,我们在调用的时候是不需要加括号的,可以当属性那样用。

2、根据一览自动缓存,如果依赖不变的话,那么computed这个值不会重新计算

let id = 0;
const createUser = (name, gender) => {
  id += 1;
  return { id: id, name: name, gender: gender };
};
new Vue({
  data() {
    return {
      users: [
        createUser("帅哥", "男"),
        createUser("美女", "女"),
        createUser("靓仔", "男"),
        createUser("靓妹", "女")
      ],
      gender: ""
    };
  },
  computed: {
    displayUsers() {
      const hash = {
        male: "男",
        female: "女"
      };
      const { users, gender } = this;
      if (gender === "") {
        return users;
      } else if (typeof gender === "string") {
        return users.filter(x => x.gender === hash[gender]);
      } else {
        throw new Error("gender 的值是意外的值");
      }
    }
  },
  methods: {
    setGender(string) {
      this.gender = string;
    }
  },

  template: `
    <div>
      <div>
      <button @click="setGender('') ">全部</button>
      <button @click="setGender('male')">男</button>
      <button @click="setGender('female')">女</button></div>
      <ul>
        <li v-for="(x,index) in displayUsers" :key="index">{{x.name}} - {{x.gender}}</li>
        //这里的x只是一个随便定义的,当然你可以将它变成你所需要的
      </ul>
      
    </div>
  `
}).$mount("#app");

如果一个数据依赖于其他数据,那么把这个数据设计为 computed

watch

1、immediate:他表示是否在第一次渲染的时候,是否需要执行这个函数。

2、deep:如果我们监听一个对象的时候,是否需要看这个对象里面的一个变化。

加了immediate: true ,一次渲染的时候会触发watch。

new Vue({
  data: {
    user: {
      email: "3155xxxxx@qq.com",
      nickname: "靓仔",
      phone: "15600100010"
    },
    displayName: ""
  },
  watch: {
    "user.email": {
      handler: "changed",
      immediate: true // 第一次渲染是也触发 watch
    },
    "user.nickname": {
      handler: "changed",
      immediate: true // 第一次渲染是也触发 watch
    },
    "user.phone": {
      handler: "changed",
      immediate: true // 第一次渲染是也触发 watch
    }
  },
  // 不如用 computed 来计算 displayName
  template: `
    <div>
       {{displayName}}
       <button @click="user.nickname=undefined">remove nickname</button>
    </div>
  `,
  methods: {
    changed() {
      console.log(arguments);
      const user = this.user;
      this.displayName = user.nickname || user.email || user.phone;
    }
  }
}).$mount("#app");

加了deep:true ,deep会监听obj里面属性的变化。

Vue.config.productionTip = false;

new Vue({
  data: {
    n: 0,
    obj: {
      a: "a"
    }
  },
  template: `
    <div>
      <button @click="n += 1">n+1</button>
      <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
      <button @click="obj = {a:'a'}">obj = 新对象</button>
    </div>
  `,
  watch: {
    n() {
      console.log("n 变了");
    },
    obj:{
      handler(){
        console.log("obj 变了");
      },
      deep:true
    },
    "obj.a": function() {
      console.log("obj.a 变了");
    }
  }
}).$mount("#app");

定义:如果某个属性变化了,我就去执行一个函数。

总结:

computed:

1、 用来计算一个值,不需要加括号。
2、 根据依赖自动缓存。

watch:

1、 两个属性:immediate 和 deep。
2、 数据变化时会执行一个函数。