一. 介绍
》使用传统的option配置方法写组件的时候问题,随着业务复杂度越来越高,代码量会不断的加大;由于相关业务的代码需要遵循option的配置写到特定的区域,导致后续维护非常的复杂,同时代码可复用性不高,而composition-api就是为了解决这个问题而生的。
》Composition API字面意思是组合APl,它是为了实现基于函数的逻辑复用机制而产生的。主要思想是,我们将它们定义为从新的 setup函数返回的JavaScript变量,而不是将组件的功能(例如state、method、computed等)定义为对象属性。
体验
1. 首先创建一个vue脚手架, 我们在About组件中进行操作
在export default配置项中,我们不用写传统的vue配置项格式了,而使用setup函数来代替,这里我们创建一个对象,需要写在reactive方法里,reactive方法需要从vue中引入,然后在末尾用return返回
import {reactive} from 'vue'
export default {
setup(){
const data = reactive({
count:0
})
return {data} //返回出去了才能访问到
}
}
在页面中访问:
<h3>count:{
{data.count}}</h3>
2. 如果我们使用一个简单的计算属性(这里是一个方法),可以将计算属性返回的结果直接保存至变量中,注意计算属性也是需要引入的
import {reactive, computed} from 'vue'
export default {
setup(){
const data = reactive({
count:0,
double:computed(()=>data.count*2)
})
return {data}
}
}
<h3>count:{
{data.count}}</h3>
<h3>double:{
{data.double}}</h3>
3. 定义方法,方法也是定义在setup里,通过return返回,因为setup本身就是一个方法,这里就不能简写add方法了,完整代码↓
<h3>count:{
{data.count}}</h3>
<h3>double:{
{data.double}}</h3>
<h3><button @click="add">增加</button></h3>
import {reactive, computed} from 'vue'
export default {
setup(){
const data = reactive({
count:0,
double:computed(()=>data.count*2)
})
function add(){
data.count++;
}
return {data,add}
}
二. 使用详解
1. setup方法应用
》setup()函数是vue3中专门新增的方法,可以理解为Composition Api的入口.
》执行时机在beforecreate之后,create之前执行.
setup函数在创建组件之前被调用,所以在setup被执行时,组件实例并没有被创建。因此在setup函数中,我们将没有办法获取到this
export default {
name:'SubComp',
props:{
one:{
type:String
},
two:{
type:String
}
}
setup(){
// 在创建组件之前调用的,没有this
console.log('setup');
console.log(this); //undifined
},
beforeCreate() {
console.log('beforeCreate--');
},
created() {
console.log('Created--');
console.log(this); //Proxy {…}
},
}
但是setup函数提供了两个参数:props和context,用来访问其他组件传过来的数据
props:在父组件向子组件传值时,子组件用props属性接收到的数据,可以通过setup中的props参数访问
export default {
name:'SubComp',
props:{
one:{
type:String
},
two:{
type:String
}
},
setup(props){
console.log(props.one+props.two);
}
}
context:上下文对象,大致包含context.attrs、context.slot、context.parent、context.root、context.emit、context.refs这些属性
export default {
name:'SubComp',
props:{
one:{
type:String
},
two:{
type:String
}
},
setup(props,context){
console.log(props.one+props.two);
//当子组件没有用props接收的时候,可以用attrs访问父组件中的数据
console.log(context.attrs.desc);
// 获取父组件插槽的内容
console.log(context.slots.default());
//向父类传数据
context.emit('myadd','向父组件传数据')
}
}
我们也可以把context解构出来方便使用
setup(props,{attrs,slots,emit}){
// 在创建组件之前调用的,没有this
console.log('setup');
console.log(this);
console.log(props.one+props.two);
//当子组件没有用props接收的时候,可以用attrs访问父组件中的数据
console.log(attrs.desc);
// 获取父组件插槽的内容
console.log(slots.default());
emit('myadd','向父组件传数据')
},
2. Composition常用的API工具
ref()函数
在setup中声明一个变量num,以及一个函数,在函数中更改num的值,return出去的num的值并没有变化,原因就在于:原生变量的数据是没有响应式的
export default {
name:'ComApi',
setup(){
let num=1;
let myfun=()=>{
num++;
console.log(num); //2
}
return{
num, //1
myfun
}
}
}
如果我们要声明一个数据是响应式的变量&#