美文网首页
vue3 computed计算属性 和 watch监听器

vue3 computed计算属性 和 watch监听器

作者: 暴躁程序员 | 来源:发表于2023-04-07 19:53 被阅读0次

一、vue3 中 computed 计算属性

  1. 通过 computed() 组合 API 定义计算属性
  2. 传入箭头函数只定义 getter 方法,传入对象定义 getter setter 方法
  3. computed() 监听的是响应式数据的原始值的变化
<template>
  <div>
    <h1>computed getter ref</h1>
    <input type="text" v-model="a" />
    <input type="text" v-model="suffixValueA" />
    <hr />
    <h1>computed getter reactive</h1>
    <input type="text" v-model="count1.originalValue" />
    <input type="text" v-model="count1.suffixValue" />
    <input type="text" v-model="computedValue" />
    <hr />
    <h1>computed getter setter</h1>
    <input type="text" v-model="count2.originalValue" />
    <input type="text" v-model="count2.suffixValue" />
  </div>
</template>

<script setup>
import { computed, reactive, ref } from 'vue'

/* computed getter ref */
const a = ref(1)
const suffixValueA = computed(() => a.value + '元')
console.log(a.value)

/* computed getter reactive */
const count1 = reactive({
  originalValue: 100,
  suffixValue: computed(() => count1.originalValue + '元')
})
const computedValue = computed(() => count1.originalValue + '元')

/* computed getter setter */
const count2 = reactive({
  originalValue: 100,
  suffixValue: computed({
    get() {
      return count2.originalValue + '元'
    },
    set(v) {
      count2.originalValue = v.split('元')[0]
    }
  })
})
</script>

二、vue3 中 watch 监听器

1. 监听响应式对象的属性

  1. 通过 watch() 定义监听器,watch() 作为组合 api 可以同时定义多个
  2. 当侦听一个响应式对象的属性时,watch 的第一个参数必须是函数返回值的方式
  3. watch()函数接受三个参数
    第一个参数是监听的目标对象:可以是函数返回值,可以是单个响应式数据,可以是多个响应式数据组成的数组
    第二个参数是发生变化时要调用的回调函数:接受三个参数分别为新值、旧值、一个用于注册副作用清理的回调函数
    第三个参数: 组件初始化时是否执行一次和是否进行深度监听:{ immediate: true, deep: true }
<template>
  <div>书名:《{{ books.name }}》</div>
  <div>单价:¥{{ books.price }}</div>
  <div>数量:{{ books.num }}本</div>
  <div>合计:{{ books.total }}</div>
  <hr />
  <button @click="handleNumSubstract">num --</button>
  <button @click="handlePriceSubstract">price --</button>
</template>
<script setup>
import { reactive, toRefs, computed, watch } from "vue";

const state = reactive({
  books: {
    name: "三国演义",
    price: 50,
    num: 5,
    total: computed(() => books.value.price * books.value.num + "元"),
  },
});

const handleNumSubstract = () => {
  state.books.num -= 1;
};
watch(
  () => state.books.num,
  (num, prevNum) => {
    console.log(num, prevNum);
    num < 0 && (state.books.num = 0);
  }
);

const handlePriceSubstract = () => {
  state.books.price -= 10;
};
watch(
  () => state.books.price,
  (num, prevNum) => {
    console.log(num, prevNum);
    num < 0 && (state.books.price = 0);
  }
);

const { books } = toRefs(state);
</script>

2. 监听响应式对象本身

当侦听一个响应式对象时,watch() 的第一个参数可以是函数返回值的方式,也可以是响应式对象本身

<template>
  <div>书名:《{{ books.name }}》</div>
  <div>单价:¥{{ books.price }}</div>
  <div>数量:{{ books.num }}本</div>
  <hr />
  <button @click="handleNumSubstract">num --</button>
</template>
<script setup>
import { reactive, toRefs, watch } from "vue";

const state = reactive({
  books: {
    name: "三国演义",
    price: 50,
    num: 5,
  },
});

const handleNumSubstract = () => {
  state.books.num -= 1;
};

watch(
  // state,  // 当直接侦听一个响应式对象时,侦听器会自动启用深层模式
  () => state,
  (state, prevState) => {
    console.log(state);
    console.log(prevState);
    state.books.num < 0 && (state.books.num = 0);
  },
  { immediate: true, deep: true }
);
const { books } = toRefs(state);
</script>

3. 终止侦听器

const stop = watch(source, callback) // 当已不再需要该侦听器时: stop()

三、vue3 中 watchEffect 监听器

立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行

  1. 通过 watchEffect() 定义监听器,watchEffect() 作为组合 api 可以同时定义多个
  2. 组件初始化时 watchEffect() 默认执行一次(非惰性)
  3. 无需指定监听的对象,默认监听所有出现在 watchEffect 内部的响应式数据和响应式数据的属性(所以可以将 setup 中的所有 watchEffect 合并成一个)
<template>
  <div>书名:《{{ books.name }}》</div>
  <div>单价:¥{{ books.price }}</div>
  <div>数量:{{ books.num }}本</div>
  <div>合计:{{ books.total }}</div>
  <hr />
  <button @click="handleNumSubstract">num --</button>
  <button @click="handlePriceSubstract">price --</button>
</template>
<script setup>
import { reactive, toRefs, computed, watchEffect } from "vue";

const state = reactive({
  books: {
    name: "三国演义",
    price: 50,
    num: 5,
    total: computed(() => books.value.price * books.value.num + "元"),
  },
});

const handleNumSubstract = () => {
  state.books.num -= 1;
};
watchEffect(() => {
  state.books.num < 0 && (state.books.num = 0);
  console.log(state.books.price); // 可监听到
  console.log(state.books); // 可监听到
});

const handlePriceSubstract = () => {
  state.books.price -= 10;
};
watchEffect(() => {
  state.books.price < 0 && (state.books.price = 0);
});

const { books } = toRefs(state);
</script>
  1. 终止监听器
const stop = watchEffect(source, callback) // 当已不再需要该侦听器时: stop()

相关文章

网友评论

      本文标题:vue3 computed计算属性 和 watch监听器

      本文链接:https://www.haomeiwen.com/subject/kxfmddtx.html