# 一、生命周期图示

# 1、vue2 回顾

# 2、对比图 1

  • 对比图 1 (选项式 vue3、vue2)

# 3、对比图 2

  • 对比图 2 (选项式 vue3、组合式 vue3)

# 二、setup()钩子

  setup() 自身并不含对组件实例的访问权,即在 setup() 中访问 this 会是 undefined。

  你可以在选项式 API 中访问组合式 API 暴露的值,但反过来则不行。

使用示例
<script>
const { createApp, ref, onMounted } = Vue

createApp({
  setup() {
    const count = ref(1)

    onMounted(() => {
      console.log('setup中:', this) // window

      // setup() 自身并不含对组件实例的访问权
      console.log('setup中:', this.message) // undefined
    })

    return {
      count
    }
  },

  data() {
    return {
      message: '欢迎访问!'
    }
  },

  mounted() {
    console.log(this) // {count: 1, message: "欢迎访问!"}
    // 可以在选项式 API 中访问组合式 API 暴露的值
    console.log(this.count)
  }
}).mount('#app')
</script>

  setup() 应该同步地返回一个对象。唯一可以使用 async setup() 的情况是,该组件是 Suspense (opens new window) 内置组件的后裔。

<script>
const { createApp, ref } = Vue

createApp({
  // warning:setup function returned a promise
  async setup() {
    //
  }
}).mount('#app')
</script>

# 1、使用示例

  下面简单看看,在 setup 中使用生命周期钩子和通过配置项使用生命周期钩子的区别:

<script>
  import { onMounted } from 'vue'
  export default {
    setup() {
      console.log('---setup---')

      // 生命周期钩子(回调形式)
      onMounted(() => {
        console.log('---onMounted---')
      })
    },

    // 生命周期函数(函数形式)
    mounted() {
      console.log('---mounted---')
    }
  }
</script>
---setup---

---onMounted---

---mounted---

  当然,在 setup 中使用生命周期钩子是也要有一些注意事项:

# 2、注意事项 ✨

setup 中是没有 onBeforeCreate、onCreated 钩子的。因为 setup 是围绕这俩的生命周期钩子运行的,所以不需要显示的定义,直接在 setup 函数中编辑即可。

vue3 中,beforeDestroy、destroyed 被改名为 beforeUnmount、unmounted

选项式 API 组合式 setup
beforeCreate → → →
created → → →
beforeMount → → → onBeforeMount
mounted → → → onMounted
beforeUpdate → → → onBeforeUpdate
updated → → → onUpdated
beforeUnmount → → → onBeforeUnmount
unmounted → → → onUnmounted

setup 中除了有 vue2 中常见的钩子,还有其他组合式生命周期钩子 (opens new window)

完整使用案例

  反正后面要将单文件组件,这里就先用一下吧:

  • App.vue
<template>
  <button @click="isShow = !isShow">创建与销毁组件</button>
  <Demo v-if="isShow"></Demo>
</template>

<script>
  import Demo from './components/Demo.vue'
  import { ref } from 'vue'

  export default {
    name: 'App',
    components: {
      Demo
    },
    setup() {
      let isShow = ref(true)

      return {
        isShow
      }
    }
  }
</script>
  • Demo.vue
<template>
  <div></div>
</template>

<script>
  import { onUnmounted } from 'vue'

  export default {
    name: 'Demo',
    setup() {
      // 对应的
      onUnmounted(() => {
        console.log('---onUnmounted---')
      })

      // 额外的
      // onActivated()
      // ……
    },

    // 1、setup中没有
    created() {
      console.log('---created---')
    },

    // 2、注意名称变化
    unmounted() {
      console.log('---unmounted---')
    }
  }
</script>

<style scoped>
  div {
    width: 300px;
    height: 200px;
    background: skyblue;
  }
</style>

# 3、setup 参数 🎈

  在 setup 中无法使用 this,那我们怎么使用 props、emit……?

答案:使用 setup 参数

  • props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性。
  • context:上下文对象,具体内容如下:
    属性 作用
    attrs 组件外部传递过来,但没有在 props 配置中声明的属性 相当于this.$attrs
    slots 收到的插槽内容 相当于 this.$slots
    emit 分发自定义事件的函数 相当于 this.$emit
<script>
  import { reactive } from 'vue'
  export default {
    props: ['msg', 'school'],

    // 这个😒(还要声明一下,不然有warning)
    emits: ['hello'],

    setup(props, context) {
      // 1、props参数
      console.log(props)

      // 2、context参数
      console.log(context)
    }
  }
</script>

# 4、拓展:依赖注入

  在上面的生命周期中我们已经接触到了 props 可以通过 setup 参数逐级透传,形成数据传递流。

  同 vue2 一样,在 vue3 中应该也有 provide 和 inject 供我们使用:

vue2 中的依赖注入
<script>
export default {
  // provide 提供给后代✨组件的数据/方法
  // provide: {
  //   message: 'provided by father'
  // }
  provide() {
    return {
      message: 'provided by father'
    }
  }
}
</script>
<script>
export default {
  // 使用 inject 选项来接收由provide提供的、当前组件✨需要的数据/方法
  inject: ['message']
}
</script>
<script>
import { provide } from 'vue'

export default {
  setup() {
    provide('name', 'lencamo')

    // vue3可以极简的解决provide的响应式问题
    const age = ref(22) // 采用响应式API即可
    provide('age', age)
  }
}
</script>
<script>
import { inject } from 'vue'

export default {
  setup() {
    // 在inject中还可以设置默认值
    const name = inject('name', 'lihua')

    const age = inject('age')
  }
}
</script>
更新于 : 8/7/2024, 2:16:31 PM