vue 组件间的通讯及生命周期

本文详细介绍了Vue中组件间的四种通信方式:props和$emit实现父子组件通信,Vuex解决非父子组件通信,以及使用provide/inject进行隔代组件通信。同时,文章通过代码示例展示了组件的生命周期,包括beforeCreate、created、beforeMount等各个阶段的执行顺序。此外,还提到了全局事件总线$bus用于跨组件通信的方法。
摘要由CSDN通过智能技术生成

vue 组件间的通讯

通常组件传参是有两种情况

1.父子组件进行传参,这时候通常利用props

        1)props  ,$emit父子组件通讯

        2)自定义事件

        父组件rights, 子组件inp和item,自定义事件引入的event.js

2.非父子组件传参,这时候一般利用vuex

3.隔代组件传参,这时候可以利用props一层一层传递下去,但是代码就比较乱了,最好使用provide/inject 进行隔代组件传递

        对于使用场景,基础组件应该使用props,我个人觉得一般用于比较复杂业务,提供基础数据,比如最近的基金详情页。可以直接在最顶层提供基金的基本信息,然后子组件都可以访问的到,不用每个单独提供detail的props 属性

4.跨组件的全局通信 $bus

生命周期

生命周期有父子组件的情况,是如何执行的,看下面效果图

<template>
  <div class="header">
    <!-- rights组件 -->
    <!-- 子组件触发的this.emit事件必须与父组件的自定义事件name一致!!! -->
    <Inp @add='addHandler'></Inp>
    <Item :list='list' @delete= 'deleteHandler'></Item>
    
  </div>
</template>

<script type="text/ecmascript-6">

import Inp from './inp'
import Item from './item'
export default {
  data() {
    return {
      list:[
        {id:1, title:'标题一'},
        {id:2, title:'标题二'},
      ]
    }
  },
  components:{
    Inp,
    Item
  },
  beforeCreate() {
    console.log('rights beforeCreate');
  },
  created() {
    console.log('rights created');
  },
  beforeMount() {
    console.log('rights beforeMount');
  },
  mounted() {
    console.log('rights mounted');
  },
  beforeUpdate() {
    console.log('rights beforeUpdate');
  },
  updated() {
    console.log('rights updated');
  },
  beforeDestroy() {
    console.log('rights beforeDestroy');
  },
  destroyed() {
    console.log('rights destroyed');
  },
  methods: {
    // 父组件接收到触发add的事件,并执行addHandler函数,title(可自定义)为携带过来的数据
    addHandler(title) {
      console.log(title);
      // 解构
      const {list} = this
      // 对象简写 key 与value一样时可直接写 key
      list.push({id:list.length+1, title})
    },
    deleteHandler(id) {
      console.log(id);
      // filter是返回满足条件的数据,假如点击的是id=2的元素,这里就是返回list中id不等于2的数据
      this.list = this.list.filter((item)=>item.id !== id)
    }  
  },
}
</script>
<template>
  <div>
    <!-- inp组件 -->
    <input type="text" name="" id="" v-model="title">
    <button @click="addTitle">添加</button>
  </div>
</template>

<script>
//  event是vue 自带的能力
import event from './event'
export default {
  data() {
    return {
      title: ''
    }
  },
  methods: {
    addTitle() {
      // 向父组件触发add 事件,并携带参数this.title
      this.$emit('add', this.title)

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

      // 清空输入框
      this.title = ''
    }
  },
}
</script>
<template>
  <div>
    <!-- item组件 -->
    <ul>
      <li v-for="item in list" :key="item.id">
        {{item.title}}
        <button @click="del(item.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

<script>
//  event是vue 自带的能力
import event from './event'
export default {
  // 或者写成props: ['list']
  props:{
    list:{
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      
    }
  },

  beforeCreate() {
    console.log('item beforeCreate');
  },
  created() {
    console.log('item created');
  },
  beforeMount() {
    console.log('item beforeMount');
  },
  mounted() {
    // 监听自定义事件onAddTitle
    event.$on('onAddTitle',this.addTitleHandler)
    console.log('item mounted');
  },
  beforeUpdate() {
    console.log('item beforeUpdate');
  },
  updated() {
    console.log('item updated');
  },
  beforeDestroy() {
    // 自定义事件或addEventListener的事件需及时销毁,否则可能会造成内存泄漏
    console.log(121414124);
    event.$off('onAddTitle',this.addTitleHandler)
    console.log('item beforeDestroy');
  },
  destroyed() {
    console.log('item destroyed');
  },
   methods: {
    del(id) {
      // 子组件触发delete事件,并携带参数id
      this.$emit('delete',id)
    },
    // 自定义事件onAddTitle后,马上执行addTitleHandler函数
    addTitleHandler() {
      console.log(`emit自定义触发的事件,再由on监听的事件,
      自定义事件不管隔多少层,都能监听到
    
      `);
    }
  },
}
</script>
import Vue from 'vue'

// 直接new了一个  vue的实例
export default new Vue()

生命周期有父子组件的情况

挂载阶段:先是父组件(rights)vue 实例化完成也就是先js 建模完成,在子组件(item) js建模完成至整个页面渲染完成,后才是父组件页面渲染

更新阶段:也同上

3.依赖注入 隔代组件,即多层嵌套组件

父组件:

  provide() {
    return {
      name: "Garrett",
    };
  },

子组件:

export default {
  inject: ["name"],
  data() {
    return {};
  },
  components: {
    RCScene,
  },
  mounted() {
    console.log("this.name", this.name);
  },
}

传对象:

export default {
  data() {
    return {
      showIndex: 0,
      obj: {
        name: "obj",
      },
    };
  },
  provide() {
    return {
      map_nodeObj: { map_node: this.obj },
      // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
    };
  },
}

 

export default {
  inject: {
    map_nodeObj: {
      default: () => {
        return { map_node: "99" };
      },
    },
  },
  data() {
    return {};
  },
  components: {
    RCScene,
  },
  mounted() {
    console.log(
      " this.map_nodeObj.map_node",
      this.map_nodeObj.map_node 
    )// {name:'obj'}
  },
};

4.跨组件的全局通讯

main.js

let that = new Vue({
  el: '#app',
  router,
  components: { App },
  template: '<App/>',
  beforeCreate() { //注册bus
    Vue.prototype.$bus = this;
  }
})
this.$bus.$emit("changchunHome_dateYM", this.value1);  // 触发事件

this.$bus.$on("changchunHome_dateYM", data => {  // 全局监听事件
      this.changchunHome_dateYM = data;
    });

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值