computed 和 watch的区别以及如何使用?

1,828 阅读1分钟

1.computed 和 watch的区别以及特点

  1. computed是计算属性,watch是监听

  2. computed是用来计算一个值的,有缓存(依赖不变,值不重新计算) 不需要加括号

  3. watch有俩选项, deep:true 监听对象时候是否要看对象里面的属性 immediate:true 表示第一次渲染的时候执行函数 某个属性变化了,就执行一个函数

2.computed

举个例子,根据需要显示性别,点击按钮男,显示全部男性,点击女显示全部女性,点击全部显示所有人, 实现该功能分别,不使用computed和使用computed,区别如下:

不使用computed

// 引用完整版 Vue
import Vue from "vue/dist/vue.js";

Vue.config.productionTip = false;
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("小乔", "女")
      ],
      displayUsers: []
    };
  },
  created() {
    this.displayUsers = this.users;
  },
  methods: {
    showMale() {
      this.displayUsers = this.users.filter(u => u.gender === "男");
    },
    showFemale() {
      this.displayUsers = this.users.filter(u => u.gender === "女");
    },
    showAll() {
      this.displayUsers = this.users;
    }
  },

  template: `
    <div>
      <div>
      <button @click="showAll">全部</button>
      <button @click="showMale">男</button>
      <button @click="showFemale">女</button></div>
      <ul>
        <li v-for="(u,index) in displayUsers" :key="index">{{u.name}} - {{u.gender}}</li>
      </ul>
      
    </div>
  `
}).$mount("#app");

使用computed的

import Vue from "vue/dist/vue.js";
// 讲计算属性的computed的
Vue.config.productionTip = false;
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((u) => u.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('famale')">女</button>
        </div>
        <ul>
          <li v-for="(u,index) in displayUsers" :key="index">{{u.name}}---{{u.gender}}</li>
        </ul>
    </div>
  `
}).$mount("#app");

3.watch

1.用途

当数据变化时候,执行一个函数

例子:实现一个撤销功能,代码如下:

1.初始状态:

image.png

2.点击+1按钮之后:

image.png

3.点击撤销,又回到上一步:

image.png

代码如下所示:

import Vue from "vue/dist/vue.js";

// 讲计算属性的computed的

Vue.config.productionTip = false;


new Vue({

data: {

n: 0,

history: [],

inUndoMode: false

},

watch: {

n(newValue, oldValue) {

if (!this.inUndoMode) {

this.history.push({ from: oldValue, to: newValue });

}

}

},

template: `

<div>

{{n}}

<hr/>

<button @click="add1">+1</button>

<button @click="add2">+2</button>

<button @click="minus1">-1</button>

<button @click="minus2">-2</button>

<hr/>

<button @click="undo">撤销</button>

<hr/>

{{history}}

</div>

`,

methods: {

add1() {

this.n += 1;

},

add2() {

this.n += 2;

},

minus1() {

this.n -= 1;

},

minus2() {

this.n -= 2;

},

undo() {

const last = this.history.pop();

this.inUndoMode = true;

const old = last.from;

this.n = old;

this.$nextTick(() => {

this.inUndoMode = false; //让上面的先执行

});

}

}

}).$mount("#app");

\

2.watch的deep选项

deep:true 监听的时候不仅看值,还看地址是否变了

(PS:简单类型是看值,复杂类型比较地址)

3.immediate:true (第一次渲染是否运行)