我们会在一个vue文件中methods,computed,watch,data中等等定义属性和方法,共同处理页面逻辑,我们称这种方式为 Options API(选项式API)
Options优缺点:条例清晰:相同的放在相同的地方,
缺点:随着组件功能的增大,关联性会大大降低,组件的阅读和理解难度会增加,
逻辑过多是this会出现问题,比如指向不明
反复横跳:一个功能往往需要在不同的vue配置项中定义属性和方法,比较分散,需求复杂之后,就会多出watch,computed,inject,provide等配置,一个methods中可能含有很多方法,往往分不清楚哪个方法对应哪个功能,就需要在data,methods,computed里修改,滚动上下移动,反复横跳。
所以我们就要用到Composition API(组合式API)Composition就是为了解决这个问题,通过组合的方式,把零落在各个data,methods的代码,重新组合,一个功能的代码放一起维护,并且这些代码可以单独拆分成函数。
为什么要用Composition:因为选项是API(Options API)太繁琐
怎么使用Composition:
为了开始使用Composition API,我们需要有一个可以实际使用它编写代码的地方,在Vue组件中,这个位置就是setup函数;
setup其实就是组件的另外一个选项,这个选项强大到我们可以用它代替之前所编写的大部分其他选项:methods,computed,watch,data,生命周期等等
那setup是什么呢?
setup函数是vue3版本中,引入的一个新函数,引入的主要原因是为了使用组合式API,setup函数是Composition的入口。
setup有哪些特点呢?
1.setup函数是组合式Api入口
2.setup函数是启动页面后自动执行的函数
3.页面中涉及的变量和方法等,都需要写在setup函数中
4.在setup中定义的变,方法需要通过return返回出去才可以使用,否则无法在视图中使用,
5.setup函数位于created、beforCreated钩子之前,用于代替这两个钩子。
setup函数的参数:
1.props
2.context
1.setup函数的第一个参数是组件的props和标准的组件一致,一个setup函数的props是响应式的,并且会在传入新的props时同步更新
(对于props的类型,和之前一样,在props选项中定义,并且在template中依然时可以正常去使用peops中的属性,比如message)
(我们在setup函数中想要使用props,不可以通过this去获取)因为peops有直接作为参数传递到setup函数,所以我们直接通过参数来使用即可。
setup函数有哪些参数呢?
传入setup函数的第二个参数时一个Setup上下文contest对象。上下文对象暴露了其他一些在setup中可能会用到的值:
代码示例:
export default {
setup(props, context) {
// 透传 Attributes(非响应式的对象,等价于 $attrs)
//所有的非prop的attribute;
console.log(context.attrs)
// 插槽(非响应式的对象,等价于 $slots)
console.log(context.slots)
// 触发事件(函数,等价于 $emit)
console.log(context.emit)
// 暴露公共属性(函数)
console.log(context.expose)
}
}
setup函数的返回值:
是函数就会有返回值,那setup函数的返回值是用来做什么的呢?
setup的返回值可以在模板template中被使用,也就是说我们可以通过setup的返回值来替代data选项,甚至是我们可以返回一个执行函数来代替methods中定义的方法;
组件中所有的变量都要在setup函数中定义,并且需要在setup函数最后通过return返回,才可以在模板中使用。代码示例:
<template>
<h1>姓名:{{name}}</h1>
<h1>年龄:{{age}}</h1>
</template>
<script>
export default {
name:'Test',
setup() {
const name = '张三';
const age = 21;
return {name,age}
}
}
</script>
<style></style>
setup创建方法:方法需要在写setup函数当中的,同时和变量一样,需要return抛出次啊能使用,代码示例:
<template>
<h1>姓名:{{name}}</h1>
<h1>年龄:{{age}}</h1>
<button @click="changeName">改变姓名</button>
</template>
<script>
export default {
name:'Test',
setup() {
const name = '张三';
const age = 21;
function changeName(){
alert(1);
}
return {name,age,changeName}
}
}
</script>
<style></style>
如果我们想在changeName中修改name变量, 那它是响应式的吗?
答:不是响应式的,如果想让name变为响应式的,就需要使用到响应式的API
代码示例:
<template>
<h1>姓名:{{name}} </h1>
<h1>年龄:{{age}}</h1>
<button @click="changeName“>改变姓名</button>
</template>
<script>
export default{
name:'Test',
setup(){
const name = '张三';
const age = 21;
function changeName(){
name='李四'
}
return{name,age,changeName}
}
}
</script>
<style></style>
我们点击按钮, 页面的姓名还是张三,这也验证了name不是响应式的.
注意:setup不可以使用this官方关于this有这样一段描述(这段描述是我给官方提交了PR之后的一段描述):表达的含义是this并没有指向当前组件实例;并且在setup被调用之前,data、computed、methods等都没有被解析;所以无法在setup中获取this