面试官: 简单说说你知道的vue2生命周期和组件通信

2,724 阅读2分钟

浅解Vue2生命周期

Vue2生命周期.png

  • 首页加载会触发哪几个生命周期
    • beforeCreate
      • 实例初始化前 此时dom不存在 只有vnode
    • created
      • 实例初始化 dom处于未挂载 数据方法计算属性等配置已完成
    • beforeMount
      • dom挂载之前 render函数将被首次调用
    • mounted 此时$el 是根节点
      • dom挂载后触发 此时$el根节点可以获取使用 一般在此处请求数据
  • 怎么触发更新生命周期
    • 在mounted中修改data里的数据 触发更新生命周期
  • vue 全部的生命周期

Vue2全部生命周期.png

  • 其他生命周期了解
    • beforeUpdate
      • data数据更新前调用
    • updated
      • 数据更新完毕后调用
    • activated
      • keep-alive缓存组件激活时调用
    • deactivated
      • keep-alive缓存组件失活时调用
    • beforeDestroy
      • 实例销毁前
    • destroyed
      • 实例销毁后
    • errorCaptured
      • 后代组件出现错误时触发
  • 生命周期小知识 ~
       // 不会保证所有子组件都挂载完毕
        mounted() {
            console.log('实例挂载后')
            // 使用nextTick可以实现整个视图都被挂载之后才会运行的代码
            this.$nextTick(function () {
                console.log('所有渲染结束')
            })
        },
        // 不会保证所有子组件都渲染完毕
        updated() {
            console.log('数据更新后')
            this.$nextTick(function () {
                //  使用nextTick可以实现整个视图都被重新渲染之后才会运行的代码
                console.log('重新渲染结束')
            })
        },

Vue2组件通信方式

props emit

props.png

  • 父组件通过v-bind指令向子级传递参数
  • 子组件通过$emit触发父组件修改方法 接收两个参数 父组件修改方法名 修改后的值
// 父组件 
<template name="component-name">
    <div>
        <p>我是父组件</p>
        // 通过v-bind:names 向child组件传递参数 
        // 通过v-on:自定义事件传递修改方法
        <child :names="message" @change="handleChange"></child>
    </div>
</template>

<script>
import Child from './children.vue'
export default {
    name:'Parent',
    components: {
        Child
    },
    data () {
        return {
            message:'这是父级传过来的'
        }
    },
    methods: {
        handleChange (e) {
        // e 参数为子组件传递的第二个参数
            this.message = e
        }
    }
}
</script>
// 子组件
<template name="component-name">
    <div>
        <p>我是子组件 {{names}}</p>
        // 点击按钮 触发修改事件
        <button @click="handleChange">按钮</button>
    </div>
</template>

<script>
export default {
    name:'Child',
    // props接收父级传来的数据
    props: {
        names:{
            // 指定数据的类型 如果不是指定数据类型 vue报错提示
            type: String,
            // 指定数据默认值
            default:''
        }
    },
    methods: {
        handleChange () {
            // $emit触发父级自定义修改事件
            this.$emit('change','修改后的names')
        }
    }
}
</script>

event bus

event bus.png

  • 使用event bus前 全局绑定
// main.js
Vue.prototype.$bus = new Vue()
// 兄弟组件
<template name="component-name">
    <div>
        <p>我是父组件 {{msg}}</p>
    </div>
</template>

<script>
export default {
    name:'Parent',
    data () {
        return {
            msg: ''
        }
    },
    mounted() {
        // 监听实例上的标识参数
        this.$bus.$on('msg', (msg)=> {
            this.msg = msg
        })
    }
}
</script>
<template name="component-name">
    <div>
        <p>这是第二个组件</p>
        <button @click="handleClick">点击发送信息</button>
    </div>
</template>

<script>
export default {
    name:'childs',
    methods: {
        handleClick () {
            // 提交事件 第一个参数为自定义标识 第二个为参数
            this.$bus.$emit('msg','来自childs的消息')
        }
    }
}
</script>

$root

$root.png

  • $root传递数据本质上是在实例上挂载自定义的数据
<template name="component-name">
    <div>
        <button @click="handleChange">按钮</button>
    </div>
</template>

<script>
export default {
    name:'Child',
    methods: {
        handleChange () {
            // 获取根组件 挂载自定义数据
            this.$root._cb = '根组件上的数据'
        }
    }
}
</script>
<template name="component-name">
    <div>
        <p>我是父组件 {{msg}}</p>
    </div>
</template>

<script>
export default {
    name:'Parent',
    mounted() {
        // 获取挂载在根组件的实例数据
        console.log(this._cd)
    },
}
</script>

$parent

$parent.png

// 子组件
<template name="component-name">
    <div>
        <p>我是子组件 {{names}}</p>
        <button @click="handleChange">按钮</button>
    </div>
</template>

<script>
export default {
    name:'Child',
    methods: {
        handleChange () {
            // 获取父组件实例 直接新增货修改属性
            this.$parent.$data.msg = 1323232
        }
    }
}
</script>
// 父组件
<template name="component-name">
    <div>
        <p>我是父组件 {{msg}}</p>
        <child :names="message" @change="handleCHnage"></child>
    </div>
</template>

<script>
import Child from './children.vue'
// import EventBus  from '../utils/bus'
export default {
    name:'Parent',
    components: {
        Child
    },
    data () {
        return {
            msg: ''
        }
    }
}
</script>


$children

$children.png

// 父组件
<template name="component-name">
    <div>
        <p>我是父组件</p>
        <child></child>
    </div>
</template>

<script>
import Child from './children.vue'
export default {
    name:'Parent',
    components: {
        Child
    },
    mounted() {
        // 由于父组件只有一个子组件 所以获取列表的第0项
        this.$children[0].arg = 233232
    }
}
</script>
// 子组件
<template name="component-name">
    <div>
        <p>我是子组件 {{arg}}</p>
        <button @click="handleChange">按钮</button>
    </div>
</template>

<script>
export default {
    name:'Child',
    data () {
        return {
            // 值被父组件修改
            arg: ''
        }
    }
}
</script>

<style scoped>
</style>

porvide / inject

provide_ inject.png

  • provide依赖在父组件定义 传向后代组件
  • 后代组件通过inject注入获取
  • 父组件参数不可更改 如需更改可以向后代传递修改参数的函数
// 父组件
<template name="component-name">
    <div>
        <p>我是父组件 {{msg}}</p>
        <child></child>
    </div>
</template>

<script>
import Child from './children.vue'
// import EventBus  from '../utils/bus'
export default {
    name:'Parent',
    components: {
        Child
    },
    // 向后代组件传递参数
    provide: {
        query: 'provide 参数'
    }
}
</script>
<template name="component-name">
    <div>
        <p>我是子组件{{query}}</p>
        <button @click="handleChange">按钮</button>
    </div>
</template>

<script>
export default {
    name:'Child',
    // 获取最上层组件传递的参数
    inject: ['query']
</script>

结语

  • 都看到这了 不考虑留个赞吗
  • 一位小萌新的学习总结