如何在Vue3中使用生命周期函数 - 知乎

vue2中使用composition-api - 掘金

什么是Composition API

如果你还不知道,Vue3 Composition API 附带了一个 setup() 方法。此方法封装了我们的大多数组件代码,并处理了响应式,生命周期钩子函数等。

简而言之,Composition API使我们能够更好地将代码组织为更多的模块化功能,而不是根据属性的类型(方法,计算的数据)进行分离。

 从Vue2转换到Vue3

这个方便的Vue2到Vue3的生命周期映射直接来自于Vue3 Composition API 文档,我认为这是一种最有用的方式来查看事情将如何变化,以及我们如何使用它们。

  • beforeCreate -> use setup()
  • created -> use setup()
  • beforeMount -> onBeforeMount
  • mounted -> onMounted
  • beforeUpdate -> onBeforeUpdate
  • updated -> onUpdated
  • beforeDestroy -> onBeforeUnmount
  • destroyed -> onUnmounted
  • errorCaptured -> onErrorCaptured

在旧的 beforeCreate 钩子函数之后和 created 的钩子函数之前立即调用 setup 方法。因此,我们不再需要这两个钩子,我们可以简单地将本应有的代码放在 setup() 方法中

添加我们的生命周期钩子

与Vue3中的大多数功能一样,生命周期钩子是我们必须导入到项目中的东西,这是为了帮助使项目尽可能轻巧。

import { onMounted, onUpdated, onUnmounted } from 'vue'

除去 beforeCreate 和 created 之外,在我们的 setup 方法中,有9个旧的生命周期钩子,我们可以在setup 方法中访问

  • onBeforeMount
  • onMounted
  • onBeforeUpdate
  • onUpdated
  • onBeforeUnmount
  • onUnmounted
  • onActivated
  • onDeactivated
  • onErrorCaptured

我们导入它们并在我们的代码中访问它们

一般Vue3里我们的axios发送请求,事件监听,setInterval等等都写在onMounted生命周期里。

<template>
  <div id="app">
    <p>{{title}}</p>
    <p>{{msg}}</p>
    <router-view/>
  </div>
</template>
import { ref,toRefs,reactive,onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted, onActivated, onDeactivated, onErrorCaptured } from 'vue'
export default {
  setup() {
    onBeforeMount(() => {
      // ... 例如返回首页 隐藏按钮
    })
    onMounted(() => {
      // ... 直接调用方法
      getHomeAllData().then(res=>{
          recommends.value = res.goods.data;
          banners.value = res.slides;
      })  
    })
    onBeforeUpdate(() => {
      // ... 
    })
    onUpdated(() => {
      // ... 
    })
    onBeforeUnmount(() => {
      // ...  例如进入列表页 显示按钮
    })
    onUnmounted(() => {
      // ... 
    })
    onActivated(() => {
      // ... 
    })
    onDeactivated(() => {
      // ... 
    })
    onErrorCaptured(() => {
      // ... 
    })
  }
}

Vue2模板

<template>
  <div>
    <Header></Header>
    <div class="article_list">
      <ul>
        <li></li>
      </ul>
    </div>
    <Footer></Footer>
  </div>
</template>
<script>
import Header from '../components/header.vue'
import Footer from '../components/footer.vue'
export default {
  components: { Header, Footer },
  data () {
    return {
      list: []
    }
  },
  created () {
    this.getData()
  },
  methods: {
    getData () {
      this.$api.get('topics', null, r => {
        console.log(r)
      })
    }
  }
}
</script>
<style>
  .article_list {margin: auto;}
</style>

Vue3

<template>
  <div>
    <p>{{id}}--{{name}}--{{num}}</p>
    <button @click="change1">点击</button>
  </div>
</template>
<script>
import { reactive ,toRefs,computed,onMounted,onUnmounted} from 'vue'
export default {
  name: "component_name",
  setup() {
    // reactive 数据双向绑定
    const data = reactive({
      id:1,
      name:'',
      num:computed(()=>state.id+=5) //计算属性
    })
    // 方法
    const methods = {
      change1(){
 
      },
      change2(){
 
      }
    }
    const test = ()=>{
        console.log('方法测试')
    }
    //页面加载完成
    onMounted(() => {
      
    })
    //销毁
    onUnmounted(() => {
      
    })
    return {
      // toRefs转换为响应式数据
      ...toRefs(data),
      ...methods,
      test
    }
  }
}
</script>
<style lang="scss" scoped>
</style>

常用Composition API  【vue3.x】vue3.x基础知识学习_vue3.x和vue3-CSDN博客
1.setup
组合API的入口,只在初始化时执行一次;函数中若返回对象,对象中的属性或方法,可在模板中直接使用

export default {
  setup(){
 
    // 非响应式数据(响应式数据:数据变化,页面跟着渲染变化)
    let count = 0;
    
    // 方法
    let updateCount = () => {
      console.log('updateCount');
      count++;
    }
    
    // 返回一个对象
    return{
      //属性
      count,
      updateCount
    }
  }
}

2.setup细节问题
2.1.setup执行时机 
在beforeCreate执行一次,此时组件并未创建 
因组件并未创建,则this为undefined;不能用this来访问data/methods/props;所以setup函数中不能使用this
其余所有compositionAPI相关回调函数中也不可以使用this
示例:

export default {
  beforeCreate(){
    console.log('beforeCreate',this);
  },
  created(){
    console.log('created',this); 
  },
  setup(){
    console.log('setup',this);
    return{
 
    }
  }
}


 执行结果:

可以看到setup中没有this;且vue3.x中的this做了处理,是一个proxy对象

                  

tips:网上还有setup执行时机是在beforeCreate和created之间这种说法?

从上图打印效果最直观的讲,setup的执行在beforeCreate和created之前

其次,beforeCreate和created内部是有this存在的,而setup中this为undefined,这也验证了setup的执行在beforeCreate和created之前

在Vue3.x中生命周期函数发生了语义化的变化,比如beforeDestroy变更为了beforeUnmount;其他生命周期均小有变化,且其他生命周期均在setup中执行;

而beforeCreate和created还维持原本,这说明Vue3.x中本身并没考虑为beforeCreate和created留有位子,而是使用setup来代替这两者,之所以Vue3.x中还有这两个钩子函数,主要是为了向下兼容

2.2.setup的返回值 
一般都返回一个对象
返回对象中的属性会与data函数返回对象合并成为组件对象的属性
返回对象中的方法会与methods中的方法合成为组件对象的方法
如有重名,setup优先
不推荐混用,methods中可以访问setup提供的属性余方法;而setup中却不能访问data/methods
setup不推荐是一个async函数:因为返回只不再是return的对象,而是promise,模板看不到return对象中的属性数据 
tips:setup可不可以是一个async函数?

可以是一个async函数,但是由于是异步,使得数据不会立即给到模板,可以使Suspense标签解决该问题,代码示例如下:

在异步组件中的setup中使用async,在未得到数据前会有一个加载中的过渡效果

<template>
    <h1>Suspense的使用</h1>
    <Suspense>
       <template #default>
           <!--异步组件-->
           <HelloWorld />
       </template>
       <template v-slot:fallback>
           <h2>加载中...</h2>  
       </template>
    </Suspense>  
</template>

参考:https://zhuanlan.zhihu.com/p/137364605

2.3.setup中的参数
setup(props,context) / setup(props,{attrs,slots,emit}) 
props:包含props配置中声明的属性的对象,可用于父传子传值
attrs:包含没有在props配置中声明的属性的对象,相当于this.$attrs
slots:包含所有传入的插槽内容的对象,相当于this.$slots
emit:用来分发自定义事件的函数,相当于this.$emit,可用于子传父传值
tips:setup中接收的props是响应式,当传入新的props时,会及时更新,由于是响应式的,所以不可以使用ES6解构,解构会消除响应式 

同理,setup中声明的响应式对象也不可解构,而是返回的时候使用toRefs来进行转换 
示例:

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  setup(props,context){
    console.log('props:',props);
    console.log('props.msg:',props.msg);
    console.log('context:',context);
    return {
 
    }
  }
}

执行结果:

新的调试钩子函数

们还可以在Vue3中使用两个全新的钩子函数来进行调试。他们是:

  • onRenderTracked
  • onRenderTriggered

这两个事件都带有一个DebuggerEvent,它使我们能够知道是什么导致了Vue实例中的重新渲染。

export default {
  onRenderTriggered(e) {
    debugger
    // 检查哪个依赖项导致组件重新呈现
  }
}

就是这样!

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐