前言

vue 官方建议,如果是单文件组件,则推荐使用 <script setup>的写法。而 setup()钩子的写法用于:

  1. 在非单文件组件中使用组合式 API 的时候
  2. 需要在基于选项式 API 的组件中集成基于组合式 API 的代码时

    内部数据

    内部数据要在 setup函数中返回才能在模版中使用。
    1. import { ref } from "vue";
    2. export default {
    3. template: `
    4. <div>
    5. {{ count }}
    6. </div>
    7. `,
    8. setup() {
    9. const count = ref(0);
    10. return {
    11. count
    12. }
    13. }
    14. }

    内部方法

    内部方法也要在 setup中返回才能使用。
    1. import { ref } from "vue";
    2. export default {
    3. template: `
    4. <div>
    5. {{ count }}
    6. <button @click="add">加一</button>
    7. </div>
    8. `,
    9. setup() {
    10. const count = ref(0);
    11. const add = () => {
    12. count++;
    13. }
    14. return {
    15. count,
    16. add
    17. }
    18. }
    19. }

    外部数据

    外部数据通过 setup()函数的第一个参数传递进去。在 props选项上定义。
    在模版中访问外部数据时直接访问即可,在 setup()函数内访问时通过第一个参数访问。
    1. import { ref } from "vue";
    2. export default {
    3. template: `
    4. <div>
    5. {{ count }}
    6. <button @click="add">加一</button>
    7. </div>
    8. `,
    9. props: ["title"],
    10. setup(props) {
    11. const count = ref(0);
    12. const add = () => {
    13. count++;
    14. }
    15. console.log(props.title);
    16. return {
    17. count,
    18. add
    19. }
    20. }
    21. }

    透传 Attributes

    setup()函数里面访问透传 attributes 的话,可以和 <script setup>一样使用 useAttrs()API。也可以从第二个参数 ctx 上下文读取 attrs属性。
    1. import { useAttrs } from "vue";
    2. export default {
    3. setup(props) {
    4. const attrs = useAttrs();
    5. }
    6. }
    1. export default {
    2. setup(props, ctx) {
    3. // 透传 attribute 被暴露为 ctx.attrs
    4. console.log(ctx.attrs)
    5. }
    6. }

setup()函数用法中禁用 Attribute 继承的话,直接写选项式属性 inheritAttrs即可。

  1. export default {
  2. inheritAttrs: false,
  3. setup(){
  4. }
  5. }

抛出事件

setup()中抛出事件的话,需要使用 setup()函数的第二个参数 ctxcontext上下文的意思。
还需要在 emits选项定义事件。

  1. import { ref } from "vue";
  2. export default {
  3. template: `
  4. <div>
  5. {{ count }}
  6. <button @click="add">加一</button>
  7. </div>
  8. `,
  9. emits: ["add-one"],
  10. setup(props, ctx) {
  11. const count = ref(0);
  12. const add = () => {
  13. count++;
  14. ctx.emit("add-one");
  15. }
  16. return {
  17. count,
  18. add
  19. }
  20. }
  21. }

使用组件

setup()函数里面使用 app.component()全局注册的组件的话,直接使用即可。
如果是要使用局部的组件,需要注册后使用。要引入组件并在 components选项中定义,然后才能在模版中使用。

  1. import ComponentA from "./Component.vue";
  2. export default {
  3. template: `
  4. <div>
  5. <ComponentA />
  6. </div>
  7. `,
  8. components: {
  9. ComponentA: ComponentA,
  10. }
  11. }

生命周期

setup()函数的生命周期和<scirpt setup>的生命周期函数一样,都是从 Vue 里面获取对应的函数,传递回调执行。

  1. <script>
  2. import { onMounted } from 'vue'
  3. export default {
  4. setup() {
  5. onMounted(() => {
  6. console.log(`the component is now mounted.`)
  7. })
  8. }
  9. }
  10. </script>

暴露数据

在子组件使用 ref 属性的时候,可以直接拿到子组件的实例,此时可以访问子组件的一些数据和方法。使用 setup()方式的组件和 基于选项式的组件一样,实例就是组件内部的 this。可以访问子组件全部的数据。