前言
Vue3相较于Vue2来说,带来了许多新的API,这为开发者提供了更多的可能性和便利性,同时在使用新的api进行组件开发时也采用了不一样的方式,在这篇文章中,我们讲解一下这些新增的组合式API。
什么是组合式API
Vue3的组合式API是在Vue2的基础上新增的API,它通过提供一组函数式API来让开发者更方便地组合和复用组件逻辑。
相较于Vue2的选项式API,组合式API更加灵活和易于理解,同时也提供了更好的类型提示和代码重用性。
常用的组合式API
setup
setup
是Vue3中新增的钩子函数,它是所有组合式API的执行入口,我们的变量、方法都在该函数中进行定义,setup
钩子函数主要有以下几种使用方式。
1、在选项式API组件中使用:
在基于选项式API的组件中用来支持组合式API,可以直接定义一个setup的钩子函数,用法如下:
<template>
<div id="app">
<p>{{ number }}</p>
<button @click="increment">增加</button>
</div>
</template>
<script lang="js">
import {ref} from 'vue'
export default {
name: 'App',
setup(props, context) {
const number = ref(0)
function increment() {
number.value++
}
return { number, add }
}
}
</script>
2、在script标签内使用
在vue
的单文件组件中,还可以使用一种更简洁的<script setup>
语法,这样可以将函数和变量定义放在同一个标签内,可以让代码更加简洁易读,示例如下:
<template>
<div id="app">
<p>{{ number }}</p>
<button @click="add">增加</button>
</div>
</template>
<script lang="js" setup>
import { ref } from 'vue'
const count = ref(0)
const add = () => {
count.value++
}
</script>
在上面的例子中,我们使用<script setup>
标签来定义count
和increment
变量,然后在模板中直接使用这些变量,而不需要在setup
函数中返回一个对象。这样可以让代码更加简洁易读,同时也可以避免一些常见的错误和问题,比如忘记返回响应式数据等等。
setup钩子函数的参数
setup
函数目前会传入两个参数:props
和context
。
props
是组件的属性对象,它包含了所有传递给组件的属性。在setup
函数中,我们可以通过props
来获取这些属性,并进行相应的操作。
context
是一个包含了许多有用方法和属性的对象,它可以让我们更方便地访问到许多Vue的内置特性。
具体的使用方法如下:
attrs
:透传 Attributes(非响应式的对象,等价于 $attrs)slots
:插槽(非响应式的对象,等价于 $slots)emit
:触发事件(函数,等价于 $emit)expose
:暴露公共属性(函数)
使用方法如下:
<template>
<div>
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
message: String
},
setup(props, context) {
console.log(props.message) // 输出传递过来的 message 属性
console.log(context.attrs) // 透传 Attributes(非响应式的对象,等价于 $attrs)
console.log(context.slots) // 插槽(非响应式的对象,等价于 $slots)
console.log(context.emit) // 触发事件(函数,等价于 $emit)
console.log(context.expose) // 暴露公共属性(函数)
}
}
</script>
在上述代码中,我们可以通过props.message
获取传递给组件的属性,通过context.attrs
来获取传递给组件的非响应式属性,通过context.slots
来获取插槽内容,通过context.emit
来触发事件,通过context.expose
来暴露公共属性。
ref
ref
是 Vue3 中新增的一个 API,它可以用来创建一个响应式数据引用,可以用于存储和操作简单的数据类型,如字符串、数字、布尔值等。
使用示例:
import { ref } from 'vue'
// 声明ref
const count = ref(0)
// 打印ref
console.log(count.value) // 输出 0
// 修改ref
count.value++ // 将 count 的值加 1
在上述代码中,我们通过 count.value
的方式来访问 ref
对象的值,输出结果为 0
,并且如果需求修改count
的值,我们通过count.value++
将count
的值加1
。
使用场景:
ref
可以用于存储和操作简单的数据类型,如字符串、数字、布尔值等,在以下场景下可以使用 ref
:
- 存储和操作简单的数据类型
- 作为
reactive
数据对象的属性
问题:
- 在使用
ref
时,需要注意不能直接修改ref
对象本身,而是应该修改ref
对象的value
属性,否则不会触发视图更新。 - 在模板中使用
ref
对象时,需要通过value
属性来访问ref
对象的值,否则会报错。
reactive
reactive
主要用于创建响应式数据对象,可以用于存储和操作复杂的数据类型,如对象、数组等,建议统一使用ref
一把梭,因为ref
既可以用来存储和操作简单的数据类型,也可以用来存储和操作复杂的数据类型,同时也可以统一vue中的赋值语法,极大地提高代码的可维护性。
reactive
函数接收一个普通的 JavaScript 对象(或数组)作为参数,并返回一个响应式的代理对象,这个代理对象会监视原始对象的变化,当原始对象发生变化时,代理对象也会自动更新。
使用示例:
import { reactive } from 'vue'
// 声明一个响应式数据对象
const state = reactive({
count: 0,
name: 'Tom',
isShow: true,
list: [1, 2, 3]
})
// 打印响应式数据对象
console.log(state)
// 修改响应式数据对象
state.count++ // 将 count 的值加 1
state.name = 'Jerry' // 修改 name 的值
state.isShow = false // 修改 isShow 的值
state.list.push(4) // 向 list 数组中添加一个新元素
在上述代码中,我们使用reactive
函数来创建一个响应式数据对象,并对其进行了打印和修改,可以看到在修改数据对象时,代理对象也会自动更新。
使用场景:
reactive
可以用于存储和操作复杂的数据类型,如对象、数组等,在以下场景下可以使用reactive
:
- 存储和操作复杂的数据类型,如对象、数组等
- 作为整个应用的状态管理对象
问题:
- 在使用
reactive
时,需要注意不能直接修改响应式数据对象本身,而是应该通过修改响应式数据对象的属性来实现数据的变更,否则不会触发视图更新。 - 在模板中使用响应式数据对象时,需要使用对象的属性来访问响应式数据,否则会报错。
watch和watchEffect
watch
和watchEffect
都是Vue3中用于监听响应式数据变化的API,它们之间的区别在于触发时机和使用方式不同。
watch
watch
函数用于监听一个响应式数据的变化,当数据发生变化时,会触发指定的回调函数。其使用方式如下:
import { ref, watch } from 'vue'
const count = ref(0)
watch(
// 监听的响应式数据
() => count,
// 回调函数
(newValue, oldValue) => {
// 处理逻辑
console.log('watch count', count.value)
}
)
count.value++
在上述代码中,我们使用watch
函数来监听state.count
的变化,当count
的值发生变化时,就会触发回调函数,并且将新的值和旧的值传递给回调函数。在回调函数中,我们可以处理相应的逻辑。
watchEffect
watchEffect
函数用于监听一个响应式数据的变化,并在响应式数据变化时立即触发回调函数。其使用方式如下:
import { watchEffect } from 'vue'
const count = ref(0)
watchEffect(() => {
// 处理逻辑
console.log('watch count', count.value)
})
count.value++
在上述代码中,我们使用watchEffect
函数来监听响应式数据的变化,并在响应式数据变化时立即触发回调函数。在回调函数中,我们可以处理相应的逻辑。
watchEffect
和watch
的主要区别在于触发时机和使用方式。watchEffect
会在响应式数据变化时立即触发回调函数,而watch
需要显式地指定要监听的响应式数据,并在数据变化时触发回调函数。同时,watchEffect
不支持传递旧值,而watch
支持传递旧值。
在实际开发中,我们可以根据具体的需求来选择使用watch
还是watchEffect
。如果我们需要监听一个响应式数据的变化并在变化时立即触发回调函数,那么可以使用watchEffect
;如果我们需要监听一个响应式数据的变化,并且需要在数据变化时执行一些复杂的逻辑,那么可以使用watch
。
原文链接:https://juejin.cn/post/7233307834456506425 作者:小熊崽