从vue3.0开始,想必大家会经常在各大资料上看到组合式api、响应式数据等新鲜的关键词。看了那么多资料,在我看来,这些关键词的出现恰巧说明了vue3.x对数据在组件间的传递和组件的复用逻辑做了进一步的优化。其中, 组合式 API 提供了一种更加灵活和可组合的方式来定义组件逻辑并且更好地处理组件间通信的问题,而setup函数就是组合式API的入口。vue3.0是通过setup()函数来定义组合式api;从vue3.2起则是通过<script setup>来实现。
想知道自己的项目到底是哪个版本,可以去vue.config.js配置文件里查看(我是用vuecli3脚手架开发项目的!!!)
1、vue3.0 setup()
// model模型
<script>
import { lowercase } from '@/utils/lowercase.js'
import Home from '@/components/Home'
import { ref } from 'vue'
export default{
name: "Home",
// 注册组件
components: {
Home
},
// props对象的定义
props: {
num: {
type: Number,
default: 1
}
},
setup (props, context) {
// 定义变量
const numb = ref(1)
// 使用外部文件
const lowercase1 = lowercase
const name = ref('MYNAME')
console.log(props)
// 接收父组件传递而来的值
const prop = toRefs(props)
// 事件的定义和向父组件发送事件信号
const sendNum = () => {
context.emit('sendNum', 1200)
}
return {
numb,
lowercase1,
name,
prop,
sendNum,
}
}
}
</script>
// view页面
<template>
<div>
<h1>使用了setup()</h1>
<p>numb:{{ numb }}</p>
<p> {{lowercase1(name)}}</p>
<p>渲染父组件传递的值:{{ prop }}</p>
<button @click='sendNum'>向父组件发送触发信号</button>
// 使用组件
<Home>我是Home组件</Home>
</div>
</template>
2、vue3.2 <script setup>
大家先来对比两段代码的不同:
// model模型
<script setup>
import { lowercase } from '@/utils/lowercase.js'
import Home from '@/components/Home'
import { ref, defineProps, defineEmits, defineExpose } from 'vue'
// 变量的定义
const numb = ref(1)
const name = ref('MYNAME')
// 使用defineProps接口定义props对象
const prop = defineProps({
num: {
type: Number,
default: 1
}
})
// 使用defineEmits接口定义emits对象
const emit = defineEmits(['submit'])
const sendNum = () => {
emit('submit', 1000)
}
// 主动向父组件暴露本组件的响应式数据等
defineExpose({
numb,
name
})
</script>
// view页面
<template>
<div>
<h1>使用了<script setup></h1>
<p>numb:{{ numb }}</p>
<p> {{lowercase1(name)}}</p>
<p>渲染父组件传递的值:{{ prop }}</p>
<button @click='sendNum'>向父组件发送触发信号</button>
<Home>我是Home组件</Home>
</div>
</template>
3、两者的差别
可以看出,setup()函数和script setup在使用上还是有较大的差别:
(1)、变量的定义与使用:
setup()函数需要繁琐将声明的变量、函数以及 import 引入的内容通过return一个对象、向外暴露,才能在<template/>使用的问题;而script setup不需要
(2)、组件使用:
使用setup()函数需要在引入组件后,通过 components:{ }注册组件才能使用,但<script setup>引入组件后将自动注册,可直接使用
(3)、组件通信:
a、在<script setup>中必须使用 defineProps 和 defineEmits接口来替代 props 和 emits
b、使用 <script setup> 的组件,父组件是无法通过ref 或者 $parent 获取到子组件的ref等响应数据,需要通过defineExpose 主动暴露;相反setup()函数可以通过ref属性获取子组件的响应式数据
TIPS:
在开发项目时最好统一语法糖,要么使用setup(),要么使用<script setup>。不然很容易将自己绕进去。
4、注意
其实并非所有<script>都可改为script setup语法,比如:
(1)无法在 <script setup> 中声明的选项,例如 inheritAttrs 或插件的自定义选项。
(2)声明模块的具名导出 (named exports)。
(3)运行只需要在模块作用域执行一次的副作用,或是创建单例对象。
故需要和<script>一起使用