- 本文旨在为大家快速梳理常用的组合式API作用和用法。主要包括ref,reactive,defineProps,defineEmits,watch,watchEffect。如有不甚详尽之处请各位大佬多多指出。
- 本文将使用
<script setup>作示例代码写法,<script setup>可以让代码变得更加精简,这也是现在开发 Vue 3 项目必备的写法。
ref
接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。
import {ref} form 'vue';
export default {
setup() {
let count = ref(0);
const handleClick = ()=>{
count.value +=1;
}
return {
count,
handleClick
}
}
}
注意:
- 当你使用
ref定义简单类型状态,不能使用解构取值(像这样const {value}=count),而必须使用xx.value(像这样count.value),否则会失去响应式!!
这是因为JS中简单类型是存放在栈(栈堆是什么?)中的简单数据段,无法添加属性和方法。而使用解构实际上就是生成新对象,新对象的每个属性对应一个Ref对象,原响应式属性的操作被代理到新对象的ref上了。 - 当你使用
ref定义对象(或引用类型),ref底层会将改对象通过reactive转为具有深层次响应式的对象。若要避免这种深层次的转换,请使用shallowRef()来替代。
reactive()
reactive()是提供实现响应式数据的方法。
reactive接收一个对象或数组的值,返回一个源对象的proxy对象。
import { reactive } from 'vue'
const objDemo = reactive({title: 'how',use:'some'})
const arrDemo = reactive([1, 2, 3])
csont funReact = () => {
arr = [4,5,6]
objDemo.title = 'what'
}
注意:
1.基本类型数据不建议用reactive,会失去响应式并且报警告value cannot be made reactive: xx。
ref和reactive()对比
defineProps、defineEmits父子组件通信
// 父组件
<template>
<Son :title=msg @edit="handleSonEdit"></Son>
</template>
<script setup>
import {ref} from 'vue'
import Son from './Son.vue'
const msg = ref(111)
const handleSonEdit = () =>{...}
</script>
// 子组件
<script setup>
import {ref,defineProps, defineEmits} from 'vue';
const props = defineProps(['title'])
const handleSomething = () => {
console.log(props.title) //子组件取值
defineEmits(["edit"]) // 把事件暴露出去
}
</script>
computed 计算属性
computed返回一个只读(或可写)的响应式ref对象,接收一个getter函数。也可以接收一个get加set函数(返回可写ref对象)。
<script setup>
import {ref, computed} from 'vue';
const count = ref(1)
let firstName = ref('Hazel')
let lastName = ref('cheng')
// 情况1. 只读对象-------
const plusOne = computed(() => count.value + 1)
// 此时的plusOne.value是只读的,不允许重新赋值
console.log(plusOne.value) // 打印结果2
// 情况2. 可读写对象-------
let plusName = computed({
get: () => {return firstName + ' ' + lastName},
set: (newValue) => {
[firstName, lastName] = newValue.split(' ')
}
})
plusName.value = 'John Doe'
console.log(plusName.value) // John Doe
console.log(firstName) // John
</script>
监听watch和watchEffect
watch(dependencies,callback)侦听一个或多个响应式数据源,并在数据源变化时才执行回调函数。返回值是一个用来停止该监听的函数。
// watch
const count = ref(0)
watch(
count,
(count, prevCount) => {...},
{ deep: true } // 若监听引用类型要加deep,但reactive()无需加默认deep
)
const state = reactive({ count: 0 })
const myWatch = watch(
() => state.count,
(count, prevCount) => {...},
)
myWatch() //停止监听
watchEffect(dependencies,callback)侦听一个或多个响应式数据源,并在数据源变化时才执行回调函数。返回值是一个用来停止该监听的函数。默认情况下,侦听器将在组件渲染之前执行。设置 flush: 'post' 将会使侦听器延迟到组件渲染之后再执行。
const some = watchEffect(async (onCleanup) => {
const { response, cancel } = doAsyncWork(id.value)
onCleanup(cancel) // 未完成的请求,清除副作用
data.value = await response
},
{
flush: 'post',
}
)
some() // 当不再需要此侦听器时