Vue3 Watch 的使用

2022/8/18 Vue3watch

Vue3 Watch 的使用

  • newValue : 最新的值
  • oldValue : 上一个值
  • 上面两个参数可以随便写名字

# 函数返回reactive对象

注意如果不加deep的话 watch监听不到 按照官网的话来说就是

当使用 getter 函数作为源时,回调只在此函数的返回值变化时才会触发。如果你想让回调在深层级变更时也能触发,你需要使用 { deep: true } 强制侦听器进入深层级模式。在深层级模式时,如果回调函数由于深层级的变更而被触发,那么新值和旧值将是同一个对象。

这里的 newValue 和 oldValue 是相等的

<template>
  <div>
    {{ content }}
    <button @click="changContent">点击</button>
  </div>
</template>

<script>
import { ref, reactive, watch, isReactive } from "vue";
export default {
  setup(props, { attrs, slots, emit }) {
    let content = reactive({ name: 0 });
    const changContent = () => {
      content.name++;
    };
    watch(
      () => content,
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      },
      { deep: true }
    );
    return {
      content,
      changContent,
    };
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# 直接传入reactive对象

这里的 newValue 和 oldValue 是相等的

  • 直接传入的话 不需要加 deep 因为Vue会默认开启 (只要是响应式对象都会默认开启deep)
  • 在深层级模式时,如果回调函数由于深层级的变更而被触发,那么新值和旧值将是同一个对象
<template>
  <div>
    {{ content }}
    <button @click="changContent">点击</button>
  </div>
</template>

<script>
import { ref, reactive, watch, isReactive } from "vue";
export default {
  setup(props, { attrs, slots, emit }) {
    let content = reactive({ name: 0 });
    const changContent = () => {
      content.name++;
    };
    watch(content, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    });
    return {
      content,
      changContent,
    };
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 具体监听响应式对象的某个值

  • 这里的 newValue 和 oldValue 是不相等的
<template>
  <div>
    {{ content }}
    <button @click="changContent">点击</button>
  </div>
</template>

<script>
import { ref, reactive, watch, isReactive } from "vue";
export default {
  setup(props, { attrs, slots, emit }) {
    let content = reactive({ name: 0 });
    const changContent = () => {
      content.name++;
    };
    watch(
      () => content.name,
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      content,
      changContent,
    };
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 将reactive响应式对象转换成普通对象

  • 这里的 newValue 和 oldValue 是不相等的
<template>
  <div>
    {{ content }}
    <button @click="changContent">点击</button>
  </div>
</template>

<script>
import { ref, reactive, watch, isReactive } from "vue";
export default {
  setup(props, { attrs, slots, emit }) {
    let content = reactive({ name: 0, age: 20 });
    const changContent = () => {
      content.name++;
    };
    watch(
      () => ({ ...content }),
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
    return {
      content,
      changContent,
    };
  },
};
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 侦听多个源

<template>
  <div>
    {{ state }}
    {{ c }}
    <button @click="add">点击</button>
  </div>
</template>

<script>
import { ref, reactive, watch, toRefs, toRef } from "vue";
export default {
  setup(props, { attrs, slots, emit }) {
    const state = reactive({
      foo: 1,
      bar: 2,
    });
    let c = ref({ age: 0 });
    const add = () => {
      state.foo++;
      c.value.age++;
    };
    watch([state, c], ([newVal, oldVal], [val, old]) => {
      console.log(newVal, oldVal);
      console.log(val, old);
    });
    return {
      state,
      add,
      c,
    };
  },
};
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# reactive 使用watch

  • 直接传入 传入 reactive 响应式对象
  • newValue === oldValue
   let content = reactive({ name: 0, age: 20 });
    watch(content, (newValue, oldValue) => {
      console.log(newValue, oldValue);
    });
1
2
3
4

  • 用getter返回一个reactive 响应式对象
  • newValue === oldValue
   let content = reactive({ name: 0, age: 20 });
       watch(
      () => content,
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      },
      { deep: true }
    );
1
2
3
4
5
6
7
8

  • 监听响应式对象具体某个值
  • newValue !== oldValue
   let content = reactive({ name: 0, age: 20 });
    watch(
      () => content.name,
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
1
2
3
4
5
6
7

  • 将reactive响应式对象转换成普通对象
  • newValue !== oldValue
   let content = reactive({ name: 0, age: 20 });
    watch(
      () => ({ ...content }),
      (newValue, oldValue) => {
        console.log(newValue, oldValue);
      }
    );
1
2
3
4
5
6
7

# ref 使用watch

  • 直接传入一个 ref 对象 注意这里是一个对象不是一个值
  • newVal === oldVal
    let a = ref({ age: 0 });
    watch(
      a,
      (newVal, oldVal) => {
        console.log(newVal, oldVal);
      },
      { deep: true }
    );
1
2
3
4
5
6
7
8

  • 直接传入一个 ref
  • newVal != oldVal
   let a = ref(0);
    watch(a, (newVal, oldVal) => {
      console.log(newVal, oldVal);
    });

1
2
3
4
5

  • getter函数监听 ref 具体某个值
  • newVal !== oldVal
    let a = ref({ num: 0 });
    watch(
      () => a.value.num,
      (newVal, oldVal) => {
        console.log(newVal, oldVal);
      }
    );
1
2
3
4
5
6
7

  • getter函数返回一个 ref对象
  • newVal === oldVal
    let a = ref({ num: 0 });
    watch(
      () => a,
      (newVal, oldVal) => {
        console.log(newVal.value, oldVal.value);
      },
      { deep: true }
    );
1
2
3
4
5
6
7
8