Vue3的部分Composition API的简单使用( part 2 )

1,270 阅读2分钟

组合API

1 computed函数

作用

根据已有数据生成新的响应式数据,与vue2选项功能类似

步骤

1.导入computed函数
2.在setup函数中执行,传入一个函数,在函数中定义计算规则,并返回结果
3.把computed函数调用完的执行结果放到setup的retur值对象中

格式

import { computed }

const computedName = computed (()=>{
  return ...
})

实例

<template>
  <p>姓名:{{name}}, 公司:{{company}}, 月薪:{{salary}}, 年薪{{total}}</p>
  <button @click="double">月薪double</button>
</template>
<script>
import { ref, computed } from 'vue'
export default {
  name: 'App',
  setup () {
    // 定义响应式对象
    const company = ref('DiDi')
    const name = ref('小王')
    const salary = ref(18000)
    const double = () => {
      salary.value *= 2
    }
    const total = computed(() => 12 * salary.value)
    
    return {  
      name, 
      company,
      total,
      salary,
      double
    }
  }
}
</script>

image.png

2 computed完整用法

格式

const computedName = computed({
  get () {
    // 当获取值自动调用
  },
  set (val) {
    // 当设置值自动调用,val会自动传入
  }
})

实例

<template>
  <div class="container">
    月薪:{{stu}},年薪:{{total}} <input v-model="total"/>
    <button @click="double">月薪double</button>
  </div>
</template>
<script>
// reactive: 是除了ref之外的第二种申明响应式数据的方式

import { reactive, computed } from 'vue'
export default {
  setup () {
  
    const stu = reactive({ // 复杂数据
      name: 'baidu',
      salary: 18000,
      address: '北京-?'
    })
    const double = () => {
      stu.salary *= 2
      console.log(stu.salary)
    }
    // 定义计算属性: 普通的写法:只使用了get
    // const total = computed(() => {
    //   return stu.salary * 12
    // })

    // 定义计算属性: 高阶的写法:使用了get + set
    const total = computed({
      get() { return stu.salary * 12 },
      set(val) { 
        // 设置计算属性的值,会自动调用,并传入val
        console.log('要设置的值...', val)
        stu.salary = val/12
      }
    })
    
    return { double, stu, total}
  }
}
</script>

image.png

小结

1.给computed传入函数,返回值就是计算属性的值
2.给computed传入对象,get获取计算属性的值,set监听计算属性改变

3 watch函数

作用

基于响应式数据的变化执行回调逻辑,和vue2中的watch的应用场景完全一致

步骤

1.导入watch函数
2.在setup函数中执行watch函数并开启响应式数据的监听
3.watch函数接收三个常规参数

侦听单个数据

<template>
  {{ age }}
  <button @click="age++">change age</button>
</template>

<script>
import { ref, watch } from 'vue'
export default {
  setup() {
    const age = ref(18)
    watch(() => {
      // 返回你想要监听的响应式数据
      return age
    }, (newVal, oldVal) => {
      // 数据变化之后的回调函数
      console.log('age发生了变化')
    })
    return {
      age
    }
  }
}
</script> 

侦听多个数据

<template>
   {{salary}}-{{age}}
  <button @click="age++">age++</button>
  <button @click="salary+=100">salary++</button>
 
</template>
<script>
import {ref, watch} from 'vue'
export default {
  setup(){
    let salary = ref(1800)
    let age = ref(20)
    
    watch([salary, age],(newVal, oldVal)=>{
      console.log('stu变化了', newVal, oldVal,newVal === oldVal)
    }, {immediate:true, deep:true})

    return {salary,age}
  }
}
</script>

立即执行?深度监听?

// 对象,要监听的响应式数据
// 数组,每个元素是响应式数据
// 函数,返回你要监听变化的响应式数据
watch ( 数据 | 数组 | get函数 , ( newVal,oldVal ) => {} , {
  // 默认状态下,只有监听的数据发生变化才会执行回调,如果你需要立即执行,需要配置immediate
  immediate:true|false
  // 默认情况下,对象内部的属性发生变化是不会被侦听到的,如果想要对象下面的所有属性都能听得到,需要开启deep配置
  deep: true|false}
} )

监听复杂数据

如果watch的第一个参数是响应数据的话,它会默认监听其下所有属性的变化,这样消耗比较大

<template>
  姓名:{{ stu.name }},公司:{{ stu.company }}
  月薪 {{ stu.money.salary }}
  <button @click="stu.company ='didi'">跳槽到DIDI</button>
</template>

<script>
import { reactive, toRefs, watch } from 'vue'
export default {
  setup() {
    const stu = reactive({
      name: '小王',
      company:'JD',
      money: {
        salary: 1800
      }
    })
    watch(stu, () => {
      // 数据变化之后的回调函数
      console.log('stu发生了变化')
    })
    return { stu }
  }
}
</script> 

所以如果使用watch尽量详细的表明你到底要监听哪个属性,避免使用deep引起的性能问题,比如,仅想在stu对象的money属性的salary变化的时候执行回调

<template>
  姓名:{{ stu.name }},公司:{{ stu.company }}
  月薪 {{ stu.money.salary }}
  <button @click="stu.money.salary*=2">工资double</button>
</template>

<script>
import { reactive, watch } from 'vue'
export default {
  setup() {
    const stu = reactive({
      name: '小王',
      company:'JD',
      money: {
        salary: 1800
      }
    })
    watch(() => {
      return stu.money.salary
    }, () => {
      // 数据变化之后的回调函数
      console.log('stu.money.salary发生了变化')
    }, {
      deep: true
    })
    return {
      stu
    }
  }
}
</script>