组合式API
组合式API其实从字面上看就是把各种方式组合起来,像搭积木那样的。使用组合式API我们需要知道以下几个知识点:
setup组件选项
setup就是组合式api的入口,和vue2中的data、computed、watch、methdos一样,定义了一个组合式API的入口。大致代码如下:
<template>
<div>
{{counter}}
</div>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'Home',
setup(props,context){
console.log(props,context)
const counter = ref(0)
return {
counter
}
}
}
</script>
上面的setup里面的就是组合式API。组合式API其实就是把之前Vue2分散在data、生命周期、watch、computed、methods中的部分现在全部整合到一起放到了setup中,这样的好处就是我们可以把一些业务或者逻辑抽离出来,然后那个地方需要就直接引入,比vue2中的方便了一些。
script setup 语法糖
setup script就是vue3新出的一个语法糖,使用方法就是在书写script标签的时候在其后面加上一个setup修饰。
代码如下:
<template>
<div>
{{counter}}
</div>
</template>
<script setup>
import { ref } from 'vue'
const counter = ref(0)
</script>
setup script 的好处
- 自动注册组件
- 属性和方法无需返回
使用 this
在 setup() 内部,this 不是该活跃实例的引用,因为 setup() 是在解析其它组件选项之前被调用的,所以 setup() 内部的 this 的行为与其它选项中的 this 完全不同。这使得 setup() 在和其它选项式 API 一起使用时可能会导致混淆。
响应式变量的定义
1. ref() 函数
ref() 函数用来根据给定的值创建一个响应式的数据对象,传入的为基本数据类型,例如字符串、数字、boolean 等,返回值是一个对象,这个对象上只包含一个 value 属性
ref定义的变量,改变值要.value,而且在template中不用写.value
<template>
<div>{{count}}</div>
<button @click="setCount">修改</button>
</template>
<script setup>
import { ref } from 'vue'
import HelloWorld from '@/components/HelloWorld.vue'
// 定义
const count = ref(0)
// 修改
const setCount = () => {
count.value = count.value + 1
}
</script>
2. reactive() 函数
reactive() 函数传入的为引用类型,例如数组、对象等,但不能代理基本类型值,返回一个响应式的数据对象,
想要使用reactive()函数创建的响应式数据也很简单,创建出来之后直接在template中调用即可。
<template>
<div>{{state.msg}}</div>
<button @click="setMsg()">修改</button>
</template>
<script setup>
import { reactive } from 'vue'
//定义
const state = reactive({
msg: '你好',
msg2:'hello'
})
//修改
const setMsg = () => {
state.msg = 'msg被改了'
}
</script>
3. 为子组件或html元素绑定refs
<template>
<div>哈哈哈</div>
<HelloWorld ref='helloWorldRef'></HelloWorld>
</template>
<script setup>
import { ref } from 'vue'
import HelloWorld from '@/components/HelloWorld.vue'
const helloWorldRef = ref()
</script>
在setup 中使用watch
在setup中watch作为一个函数接受三个参数:监听的值、回调、可选的配置。实例如下:
<script setup>
import { ref, watch } from 'vue'
const counter = ref(0)
watch(counter, (newValue, oldValue) => {
console.log(counter.value)
})
</script>
在setup中使用computed
<script setup>
import { ref, computed } from 'vue'
const counter = ref(0)
const twiceTheCounter = computed(() => counter.value * 2)
counter.value++
console.log(counter.value) // 1
console.log(twiceTheCounter.value) // 2
</script>
生命周期钩子
| 选项式 API | 调用时机 | setup |
|---|---|---|
| beforeCreate | 在实例初始化之后、进行数据侦听和事件/侦听器的配置之前同步调用。 | 不需要 |
| created | 在实例创建完成后被立即同步调用 | 不需要 |
| beforeMount | 在挂载开始之前被调用 | onBeforeMount |
| mounted | 在实例挂载完成后被调用 | onMounted |
| beforeUpdate | 在数据发生改变后,DOM 被更新之前被调用 | onBeforeUpdate |
| updated | 在数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用 | onUpdated |
| beforeUnmount | 在卸载组件实例之前调用 | onBeforeUnmount |
| unmounted | 卸载组件实例后调用 | onUnmounted |
| errorCaptured | 在捕获一个来自后代组件的错误时被调用 | onErrorCaptured |
| renderTracked | 跟踪虚拟 DOM 重新渲染时调用 | onRenderTracked |
| renderTriggered | 当虚拟 DOM 重新渲染被触发时调用 | onRenderTriggered |
| activated | 被 keep-alive 缓存的组件激活时调用。 | onActivated |
| deactivated | 被 keep-alive 缓存的组件失活时调用。 | onDeactivated |
defineProps 和 defineEmits
在
<script setup>中必须使用defineProps和defineEmitsAPI 来声明props和emits,它们具备完整的类型推断并且在<script setup>中是直接可用的:
<script setup>
const props = defineProps({
foo: {
type: String, // 类型
required: true, // 是否必填
default: "请输入" // 默认值
}
})
const emit = defineEmits(['change', 'delete'])
// setup code
</script>
defineProps和defineEmits都是只在<script setup>中才能使用的编译器宏。他们不需要导入且会随着<script setup>处理过程一同被编译掉。defineProps接收与props选项相同的值,defineEmits也接收emits选项相同的值。
defineExpose
使用
<script setup>的组件是默认关闭的,也即通过模板 ref 或者$parent链获取到的组件的公开实例,不会暴露任何在<script setup>中声明的绑定。为了在
<script setup>组件中明确要暴露出去的属性,使用defineExpose编译器宏:
<script setup>
import { ref } from 'vue'
const a = 1
const b = ref(2)
defineExpose({
a,
b
})
</script>
当父组件通过模板 ref 的方式获取到当前组件的实例,获取到的实例会像这样 { a: number, b: number } (ref 会和在普通实例中一样被自动解包)