computed 计算属性 和 watch 侦听属性 (vue3)

415 阅读1分钟

1、computed函数 (计算属性 求和)

computed 函数调用时, 要接收一个处理函数, 处理函数中, 需要返回计算属性的值

1.1、传入一个函数 getter 返回一个值

求和可以不用变成响应式数据,因为没有改变数组的值

<template>
  <div>
    <p>求和:{{ sum }}</p>
  </div>
</template>

<script>
import { computed } from 'vue'

export default {
  setup () {
    const arr = [1, 2, 3, 4, 5]
    const sum = computed(() => {
      return arr.reduce((sum, item) => {
        return sum + item
      }, 0)
    })

    return { sum }
  }
}
</script>

使用 ref 函数 变成响应式数据 也可以求和

<template>
  <div>
    <p>求和:{{ sum }}</p>
  </div>
</template>

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

export default {
  setup () {
    const arr = ref([1, 2, 3, 4, 5])
    const sum = computed(() => {
      return arr.value.reduce((sum, item) => {
        return sum + item
      }, 0)
    })
    return { sum }
  }
}
</script>

1.2、传入一个对象, 包括 get 和 set

<template>
  <div>我今年的年纪 <input type="text" v-model="age"></div>
  <div>我明年的年纪 {{nextAge}}</div>
</template>

<script>
import { ref, computed } from 'vue'
export default {
  setup () {
    const age = ref(0)
    const nextAge = computed({
      get () {
        return +age.value + 1
      },
      set (value) {
        age.value = value - 1
      }
    })
    return { age, nextAge }
  }
}
</script>

2、watch 函数(侦听属性,值变化)

  • watch函数, 接收三个参数
    • 参数1: 侦听数据:对象、对象的属性、函数、数组等
    • 参数2: 回调函数,如何处理要侦听的数据
    • 参数3: 对象 {},对象里可以写深度侦听、立即侦听(额外的配置)

2.1、侦听简单数据类型:可以直接侦听到新旧值的变化

<template>
  <div>
    <p>价格:{{ price }}</p>
    <button @click="addFn">按钮</button>
  </div>
</template>

<script>
import { watch, ref } from 'vue'
export default {
  setup () {
    const price = ref(0)
    // 1.侦听简单值+可以获取新旧值
    watch(price, (newVal, oldVal) => {
      console.log(newVal, oldVal, '侦听 price 变化1')
    })
    const addFn = () => {
      price.value++
    }
    return { price, addFn }
  }
}
</script>

2.2、侦听复杂数据类型:侦听对象写的不是函数,可以直接侦听到属性内部,但只能侦听到新值

<template>
  <div>
    <p>我今年:{{ obj.age }}岁了</p>
    <button @click="addFn">按钮</button>
  </div>
</template>

<script>
import { watch, reactive } from 'vue'
export default {
  setup () {
    const obj = reactive({
      name: '张三',
      age: 18
    })
    // 2.侦听对象+只能获取新值
    watch(obj, (newVal, oldVal) => {
      console.log(newVal, oldVal, '侦听 obj 对象属性的变化2')
    })
    const addFn = () => {
      obj.age++
    }
    return { obj, addFn }
  }
}
</script>

<style lang="scss" scoped>
</style>

2.3、侦听复杂数据类型:侦听对象写的是函数,触发侦听器需要深度侦听,只能侦听到属性新值

<template>
  <div>
    <p>我今年:{{ obj.age }}岁了</p>
    <button @click="addFn">按钮</button>
  </div>
</template>

<script>
import { watch, reactive } from 'vue'
export default {
  setup () {
    const obj = reactive({
      name: '张三',
      age: 18
    })
    // 3.侦听函数+深度侦听+只能获取新值
    watch(() => obj, (newVal, oldVal) => {
      console.log(newVal, oldVal, '侦听 obj 函数的 变化3')
    }, { deep: true, immediate: true }// 深度侦听(也可以加上立即侦听,立即侦听可以侦听初始值,一进入页面就触发)
    )
    const addFn = () => {
      obj.age++
    }
    return { obj, addFn }
  }
}
</script>

2.4、侦听复杂数据类型:侦听对象写的是函数,并且是侦听对象的属性,可以触发侦听器,也可以获取新旧值

<template>
  <div>
    <p>我今年:{{ obj.age }}岁了</p>
    <button @click="addFn">按钮</button>
  </div>
</template>

<script>
import { watch, reactive } from 'vue'
export default {
  setup () {
    const obj = reactive({
      name: '张三',
      age: 18
    })
    // 4.侦听对象属性的函数+可以获取新旧值
    watch(() => obj.age, (newVal, oldVal) => {
      console.log(newVal, oldVal, '侦听 obj.age 函数的 变化4')
    })
    const addFn = () => {
      obj.age++
    }
    return { obj, addFn }
  }
}
</script>

2.5、侦听对象用数组包裹,都能触发侦听器,简单数据类型可以获取新旧值,复杂数据类型只能获得新值

<template>
  <div>
    <p>价格:{{price}}</p>
    <p>我今年:{{ obj.age }}岁了</p>
    <button @click="addFn">按钮</button>
  </div>
</template>

<script>
import { watch, reactive, ref } from 'vue'
export default {
  setup () {
    const price = ref(0)
    const obj = reactive({
      name: '张三',
      age: 18
    })
    // 侦听数组+简单数据类型可以获取新旧值+复杂数据类型只能获得新值
    watch([obj, price], (newVal, oldVal) => {
      console.log(newVal, oldVal, '侦听 obj,price 数组的 变化5')
    })
    const addFn = () => {
      price.value++
      obj.age++
    }
    return { price, obj, addFn }
  }
}
</script>