Vue3_setup的两个注意点

466 阅读2分钟

引入

setup是Vue3中一个新的配置项,值为一个函数,它是组件API“表演的舞台”,组件中所用到的数据方法等等都配置在setup中,setup存在两种返回值。若返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用。若返回一个渲染函数:则可以自定义渲染内容。

setup的两个注意点

1. setup执行的时机

在Vue2.0中,我们所了解到的生命周期中的一个中执行的函数是beforeCreate,但在Vue3中,我们的setup函数的执行时机要在beforeCreate之前,这也是为什么组件实例对象this是undefined,因为组件对象this还没有被创建出来,所以this是undefined,所以也不能通过this访问Vue2中的一些配置(data、methos、computed...)。

可以通过如下代码观察到setup的执行顺序在beforeCreate之前,以及打印的this是undefined。

import {reactive} from 'vue'
export default {
  name: 'DEMO',
   beforeCreate(){
     console.log('---beforeCreate---');
   },
    setup(){
     console.log('---setup---',this);

     let person =reactive({
        // 数据
         name:'张三',
         age:18
     })

     return {
       person
     }
   }
 }

显示如下:

2023-02-25.png

2. setup的参数

使用setup时会接受两个参数 propscontext

  • props值为对象,包含了组件外部传递过来的数据,以及组件内部声明接受了的数据。

示例代码如下:

组件外部

<template>
  //msg就是组件外部传递的数据
  <Demo msg="你好啊"/>
</template>

<script>
    import Demo from './components/Demo'
    export default {
      name:"App",
      components:{Demo}
    }
</script>

组件内部

import {reactive} from 'vue'
export default {
  name: 'DEMO',
  //组件内部的props接受组件外部传递过来的数据
  props:['msg'],
  emits:['hello'],
    setup(){
     console.log('---setup---',props);

     let person =reactive({
        // 数据
         name:'张三',
         age:18
     })

     return {
       person
     }
   }
 }
  • context:上下文对象

    • attrs: 值为对象,包含:组件外部传递过来,但没有在props配置中声明的属性, 相当于 this.$attrs
    • emit: 分发自定义事件的函数, 相当于 this.$emit
    • slots: 收到的插槽内容, 相当于 this.$slots

示例代码如下:

组件外部

<template>
  <!-- 组件里面写自定义事件 -->
  <Demo @hello="showTest" msg="你好啊" school="尚硅谷">
    <template v-slot:qwe>
      <span>尚硅谷</span>
    </template>
    <template v-slot:awd>
      <span>尚硅谷</span>
    </template>
  </Demo>
</template>

<script>
  import Demo from './components/Demo'
  export default {
    name:'App',
    components:{Demo},
    setup(){
      function showTest(value) {
        alert(`你好啊,我收到的参数是:${value}`)
      }
      return {
        showTest
      }
    }
  }
</script>

组件内部

<template>
  <h1>一个人的信息</h1>
  <h2>姓名:{{ person.name }}</h2>
  <h2>年龄:{{ person.age }}</h2>
  <button @click="test">触发一下Demo组件中的showTest事件</button>
</template>

<script>
import {reactive} from 'vue'
export default {
  name: 'DEMO',
  props:['msg','school'],
  emits:['hello'],
  // beforeCreate(){
  //   console.log('---beforeCreate---');
  // },
  // setup在beforeCreate之前,有两个参数,第一个参数props用来传递数据
  setup(props,context){
    console.log('---setup---',props);
    console.log('---setup---',context);
    console.log('---setup---',context.attrs);   //相当于Vue2中的$attrs
    console.log('---setup---',context.emit);   //触发自定义事件
    console.log('---setup---',context.slots);    //插槽
    let person =reactive({
      // 数据
        name:'张三',
        age:18
    })

    // 方法
    function test(){
      context.emit('hello',666)
    }
    return {
      person,
      test
    }
  }
}
</script>