组合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>
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>
小结
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>