熬夜梳理一下Vue 3 中setup函数及周边

53 阅读4分钟

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函数中)
beforeMountonBeforeMount
mountedonMounted
beforeUpdateonBeforeUpdate
updatedonUpdated
beforeDestroyedonBeforeUnmount
destroyedonUnmounted

3. setup 可以接受哪些参数

setup函数的参数说明
props子组件接收的从父组件传递过来的属性
context.attrs父组件传递过来的非props的属性
context.slots父组件传递过来的插槽
context.emit组件内部需要发出事件时会用
setup(props, context){}

3.1 props

  • 第一个参数props,是一个对象,包含了父组件传递给子组件的所有数据,在子组件中使用props进行接收,包含配置声明并传入的所有的属性的对象;
  • props是响应式的,传入新的prop时,将被更新。不能使用ES6解构,因为解构会消除响应式;

解构赋值语法是一种 Javascript 表达式。通过解构赋值,可以将属性/值从对象/数组中取出,赋值给其他变量

  • 控制台打印出的props

image.png

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

image.png

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 上的数据,都是可读可写的(双向的)