vue2父子组件之间生命周期的调用顺序

1,982 阅读1分钟

vue2父子组件之间生命周期的调用顺序

先导语

之前从来没有没有注意过在父子组件的情况下,vue生命周期的调用顺序。今天就来实际看一下,顺便记录一下,加深自己的印象。

代码演示

还是使用之前的todolist的代码:

beforeCreate和created以及mounted阶段

父组件代码:

<template>
    <div>
        <Input @add="addHandler"/>
        <List :list="list" @delete="deleteHandler"/>
    </div>
</template>

<script>
import Input from './Input'
import List from './List'

export default {
    components: {
        Input,
        List
    },
    data() {
        return {
            list: [
                {
                    id: 'id-1',
                    title: '标题1'
                },
                {
                    id: 'id-2',
                    title: '标题2'
                }
            ]
        }
    },
    methods: {
        addHandler(title) {
            this.list.push({
                id: `id-${Date.now()}`,
                title
            })
        },
        deleteHandler(id) {
            this.list = this.list.filter(item => item.id !== id)
        }
    },
    beforeCreate() {
      console.log("父-beforeCreate")
    },
    created() {
      console.log("父-Create")
    },
    mounted() {
        console.log('父- mounted')
    },
}
</script>

子组件代码:

<template>
    <div>
        <input type="text" v-model="title"/>
        <button @click="addTitle">add</button>
    </div>
</template>

<script>
import event from './event'

export default {
    data() {
        return {
            title: ''
        }
    },
    beforeCreate() {
      console.log("子-beforeCreate")
    },
    created() {
      console.log("子-created")
    },
    mounted() {
      console.log("子-mounted")
    },
    methods: {
          addTitle() {
              // 调用父组件的事件
              this.$emit('add', this.title)

              // 调用自定义事件
              event.$emit('onAddTitle', this.title)

              this.title = ''
          }
      }
}
</script>

输出结果:

image.png

可以得出结论:
在beforecreate,created,mounted阶段,先执行父组件的beforecreate,created钩子函数,再执行子组件的beforecreate,created,mounted钩子函数,最后执行父组件的mounted函数。

beforeUpdate和updated

父组件代码:

<template>
    <div>
        <Input @add="addHandler"/>
        <List :list="list" @delete="deleteHandler"/>
    </div>
</template>

<script>
import Input from './Input'
import List from './List'

export default {
    components: {
        Input,
        List
    },
    data() {
        return {
            list: [
                {
                    id: 'id-1',
                    title: '标题1'
                },
                {
                    id: 'id-2',
                    title: '标题2'
                }
            ]
        }
    },
    methods: {
        addHandler(title) {
            this.list.push({
                id: `id-${Date.now()}`,
                title
            })
        },
        deleteHandler(id) {
            this.list = this.list.filter(item => item.id !== id)
        }
    },
    // beforeCreate() {
    //   console.log("父-beforeCreate")
    // },
    // created() {
    //   console.log("父-Create")
    // },
    // mounted() {
    //     console.log('父- mounted')
    // },
    beforeUpdate() {
      console.log('父-beforeUpdate');
    },
    updated() {
      console.log('父-updated');
    },
}
</script>

子组件代码:

<template>
    <div>
        <input type="text" v-model="title"/>
        <button @click="addTitle">add</button>
    </div>
</template>

<script>
import event from './event'

export default {
    data() {
        return {
            title: ''
        }
    },
    // beforeCreate() {
    //   console.log("子-beforeCreate")
    // },
    // created() {
    //   console.log("子-created")
    // },
    // mounted() {
    //   console.log("子-mounted")
    // },
    beforeUpdate() {
      console.log('子-beforeUpdate');
    },
    updated() {
      console.log('子-updated');
    },
  methods: {
          addTitle() {
              // 调用父组件的事件
              this.$emit('add', this.title)

              // 调用自定义事件
              event.$emit('onAddTitle', this.title)

              this.title = ''
          }
      }
}
</script>

当添加 todolist 之后:

image.png

为什么会时这个结果呢?
原因是:当增加todolist选项时,先将title的值传给了父组件,然后再改变了title的值。

beforeDestroy和destroyed

父组件代码:

<template>
    <div>
        <Input @add="addHandler"/>
        <List :list="list" @delete="deleteHandler"/>
    </div>
</template>

<script>
import Input from './Input'
import List from './List'

export default {
    components: {
        Input,
        List
    },
    data() {
        return {
            list: [
                {
                    id: 'id-1',
                    title: '标题1'
                },
                {
                    id: 'id-2',
                    title: '标题3'
                }
            ]
        }
    },
    methods: {
        addHandler(title) {
            this.list.push({
                id: `id-${Date.now()}`,
                title
            })
        },
        deleteHandler(id) {
            this.list = this.list.filter(item => item.id !== id)
        }
    },
    // beforeCreate() {
    //   console.log("父-beforeCreate")
    // },
    // created() {
    //   console.log("父-Create")
    // },
    // mounted() {
    //     console.log('父- mounted')
    // },
    // beforeUpdate() {
    //   console.log('父-beforeUpdate');
    // },
    // updated() {
    //   console.log('父-updated');
    // },
    beforeDestroy() {
      console.log('父-beforeDestroy');
    },
    destroyed() {
      console.log('父-destroyed');
    },
}
</script>

子组件代码:

<template>
    <div>
        <input type="text" v-model="title"/>
        <button @click="addTitle">add</button>
    </div>
</template>

<script>
import event from './event'

export default {
    data() {
        return {
            title: ''
        }
    },
    // beforeCreate() {
    //   console.log("子-beforeCreate")
    // },
    // created() {
    //   console.log("子-created")
    // },
    // mounted() {
    //   console.log("子-mounted")
    // },
    // beforeUpdate() {
    //   console.log('子-beforeUpdate');
    // },
    // updated() {
    //   console.log('子-updated');
    // },
    beforeDestroy() {
      console.log('子-beforeDestroy');
    },
    destroyed() {
      console.log('子-destroyed');
    },
  methods: {
          addTitle() {
              // 调用父组件的事件
              this.$emit('add', this.title)

              // 调用自定义事件
              event.$emit('onAddTitle', this.title)

              this.title = ''
          }
      }
}
</script>

结果:

image.png

只有当子组件被销毁之后父组件才能被销毁

结束语

通过上面的demo练习,相信大家对父子组件生命周期的调用已经有比较清晰的认知了。那么下次见,好好学习,天天向上!

image.png