computed 计算属性
计算属性是当依赖的属性的值发生变化的时候,才会触发他的更改,如果依赖的值没变化的时候,使用的是缓存中的属性值。
基本用法
函数形式 (只能读取值)
<template>
name:{{ name }}
<hr>
newName:{{ newName }}
</template>
<script setup lang='ts'>
import { ref, computed } from 'vue'
const name = ref('小刘')
const newName = computed<string>(() => {
return "我不是" + name.value
})
</script>
对象形式 (可以修改值)
<template>
name:{{ name }}
<hr>
newName:{{ newName }}
<div>
<button @click="edit">修改</button>
</div>
</template>
<script setup lang='ts'>
import { ref, computed } from 'vue'
const name = ref('小刘')
const newName = computed({
get: () => {
return name.value
},
set: (value) => {
name.value = value
console.log("修改了", value);
}
})
const edit = () => {
newName.value = "修改" + newName.value
}
</script>
watch 侦听器
侦听一个或多个响应式数据源,并在数据源变化时调用所给的回调函数。
watch() 接收三个参数
第一个是需要侦听的数据源
第二个是数据源变化的时候执行的callback
第三个是一个对象,是可选的,配置项有
immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined。
deep:开启深度监听,reactive 创建的响应式数据自动开启。
flush:调整回调函数的更新时机,pre:组件更新前,sync:同步执行,post:组件更新后
onTrack / onTrigger:调试侦听器的依赖
基本用法
<template>
name: <input v-model="name" />
</template>
<script setup lang='ts'>
import { ref, watch } from 'vue'
const name = ref('小刘')
watch(name, (newval, oldval) => {
console.log("newval:", newval);
console.log("oldval:", oldval);
})
</script>
监听多个数据源时,使用数组的方式传入,也是通过数组得到新旧value
const name = ref('小刘')
const name2 = ref('小刘22')
watch([name, name2], ([newval1, oldval1], [newval2, oldval2]) => {
console.log("newval1:", newval1);
console.log("oldval1:", oldval1);
console.log("newval2", newval2);
console.log("oldval2:", oldval2);
})
当一个对象里面有多个属性,只想监听其中一个的话,可以使用函数返回的形式传入要监听的数据源
例如有 name 和 age,我只想监听 name
const person = reactive({
foo: {
bar: {
name: "小刘",
age: 20
}
}
})
watch(() => person.foo.bar.name, (newval, oldVal) => {
console.log('newval:', newval)
console.log('oldVal:', oldVal)
})
第三个参数示例
如果要监听这种深层次对象的话,我们需要开启 deep 深度监听 (通过 reactive 实现的响应式数据会默认开启)
这样写的时候,修改 name 值不会触发监听
<template>
name: <input v-model="person.foo.bar.name" />
</template>
<script setup lang='ts'>
import { ref, watch } from 'vue'
const person = ref({
foo: {
bar: {
name: "小刘"
}
}
})
watch(person, (newval, oldVal) => {
console.log('newval:', newval)
console.log('oldVal:', oldVal)
})
</script>
使用 deep 深度监听,就可以监听到变化了。
watch(person, (newval, oldVal) => {
console.log('newval:', newval)
console.log('oldVal:', oldVal)
}, {
deep: true // 开启深度监听
})
watchEffect 高级侦听器
非惰性的,会立即运行一次函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。
watchEffect 接收两个参数,第一个要执行的函数(自动侦听函数内用的响应式数据),第二个是配置项
使用示例
<template>
num: <input v-model="num" />
</template>
<script setup lang='ts'>
import { ref, watchEffect } from 'vue'
const num = ref(1)
watchEffect(() => {
console.log(num.value);
})
</script>
配置项
flush:调整回调函数的更新时机,pre:组件更新前,sync:同步执行
onTrack(): 开发环境中方便调试,立即执行
onTrigger(): 开发环境中方便调试,更新时执行
watchEffect(() => {}, {
flush: 'post',
onTrack(e) {
debugger
},
onTrigger(e) {
debugger
}
})
副作用清除
watchEffect 函数里有一个参数 oninvalidate,在数据变化时,会在函数内先执行
const num = ref(1)
watchEffect((oninvalidate) => {
oninvalidate(() => {
console.log("before");
})
console.log(num);
})
停止跟踪,watchEffect 返回一个函数,调用之后将停止监听
<template>
num: <input v-model="num" />
<button @click="stop">停止监听</button>
</template>
<script setup lang='ts'>
import { ref, watchEffect } from 'vue'
const num = ref(1)
const stop = watchEffect((oninvalidate) => {
oninvalidate(() => {
console.log("before");
})
console.log(num);
})
</script>