1. 为什么要用setup
- vue 2 采用的是选项式API,在对应的属性中写对应的功能模块,比如:
data定义数据、methods定义方法、computed定义计算属性、watch监听属性改变、生命周期函数
优点是容易理解,缺点也明显,就是应用大了,存在代码冗余和杂乱问题,因为相同的功能分散在不同的选项中,比较麻烦。 - vue 3 升级为组合式API,特定功能相关的东西都放在一起维护,相同功能相关的响应式数据,操作数据的方法等放在一起,这样不受应用大的限制,可快速定位到某个功能的所有相关代码,维护方便。组合式API要在setup函数中实际使用。
2. setup 用法
- setup 函数就是组件的另外一个选项;是启动页面后自动执行的函数
- 在 setup 中定义的变量、方法需要通过 return 返回出去才可以使用,否则无法在视图中使用。
- setup 函数位于 created 和 beforCreated 钩子之前,用来代替这两个钩子。
选项式API | 组合式API |
---|---|
beforeCreate | 不需要(直接写到setup函数中) |
created | 不需要(直接写到setup函数中) |
beforeMount | onBeforeMount |
mounted | onMounted |
beforeUpdate | onBeforeUpdate |
updated | onUpdated |
beforeDestroyed | onBeforeUnmount |
destroyed | onUnmounted |
3. setup 可以接受哪些参数
setup函数的参数 | 说明 |
---|---|
props | 子组件接收的从父组件传递过来的属性 |
context.attrs | 父组件传递过来的非props的属性 |
context.slots | 父组件传递过来的插槽 |
context.emit | 组件内部需要发出事件时会用 |
setup(props, context){}
3.1 props
- 第一个参数
props
,是一个对象,包含了父组件传递给子组件的所有数据,在子组件中使用props进行接收,包含配置声明并传入的所有的属性的对象; props
是响应式的,传入新的prop
时,将被更新。不能使用ES6解构,因为解构会消除响应式;
解构赋值语法是一种 Javascript 表达式。通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量
- 控制台打印出的
props
3.2 context
- 第二个参数
context
,普通的JS对象,context
不是响应式,可以解构
1) context.attrs
属性对象
attrs
(获取当前标签上的所有属性的对象)该属性是props中没有声明接收的所有的对象,attrs获取值是不需要props中没有声明接收;attrs
是有状态的对象 随组件本身更新而更新
2) context.emit
事件分发
emit事件分发,(传递给父组件需要使用该事件),emit可触发自定义事件的执行完成子传父
3) context.slots
插槽
slots是有状态的对象 随组件本身更新而更新
setup(props, { attrs, slots, emit }) {
...
}
- 控制台打印出的
context
4. setup函数的返回值
- setup的返回值可以在
模板template
中被使用; - 也就是说我们可以通过setup的返回值来替代data选项;
5. 父子通信
- 组件实例的作用域是孤立的。这就意味着不能在子组件的模板内直接引用父组件的数据。\
- 父传子是通过prop进行传入,子传父通过调用自定义事件完成\
- 父组件通过给子组件绑定属性的方式传值,在子组件中用props:[‘xxx’,‘xxx’] 接收,然后在子组件中直接通过
this.xxx
得到父组件出过来的数据
- 一个组件可以直接在模板里面渲染 data 中的数据;子组件不能直接在模板中渲染父组件的数据,必须通过 props 访问父组件数据
<div> {{ n }} </div>
<button @click='add'>+1</button>
const vm = new Vue({
data(){
return {n:0}
},
methods:{
add(){this.n += 1}
}
})
-
如果子组件想引用父组件的数据,可以在引用子组件的时候,通过
属性绑定(v-bind:)
的形式,把需要传递给子组件的数据,以属性绑定的形式传递到子组件的内部,供子组件使用。然后再把传递过来的属性
,在props数组
中定义一下,这样才能使用父组件中的数据。 -
组件中的 props:所有
props
中的数据都是只读的单向数据流(单向绑定),无法重新赋值; -
子组件中的
data
数据,并不是通过 父组件传递过来的,而是子组件 自身私有的,比如:子组件通过 ajax ,请求回来的数据,都可以放到 data 身上,data 上的数据,都是可读可写的(双向的)