Vue 之 组件传值,一文给你弄懂

目录

一、父子组件传值 

1. 最常用的

01 - 父组件传递数据

02 - 子组件接受数据

03 - 子组件发射事件 

04 - 父组件中感知

2. 使用$Refs|$parent | $root

子组件

父组件

二、非直接父子传值 ( 有嵌套关系 )

使用provide 与 inject 

父组件 ( 祖先组件 ) 

子组件

 三、非父子传值 ( 无嵌套关系 )

1. vuex的存取值 

2. 全局事件总线 (vue2)

01 - 在 main.js 中注册

02 - 在某组件发射事件

03 - 在某组件监听事件         

04 - 移除事件 

3. 全局事件总线Mitt(vue3)

01 - 安装

02 - 封装一下

03 - 发射事件 

04 - 监听事件

05 - 取消事件 


一、父子组件传值 

1. 最常用的

01 - 父组件传递数据

02 - 子组件接受数据

03 - 子组件发射事件 

04 - 父组件中感知

2. 使用$Refs|$parent | $root

$parent | $root 很少使用,会使代码变得混乱,不推荐使用

tip : 在vue3中,$children,已经被移除了!!!

子组件

<template>
  <div class="son-layout">
    <h3>{{ name }}</h3>
  </div>
</template>
<script>
export default {
  name: 'son',
  data() {
    return {
      name: 'son'
    };
  },
  mounted(){
    //使用$parent拿到父组件的name数据 (不推荐)
    this.$parent.name
    //使用$root拿到根组件( 一般是app.vue ) (不推荐)
    this.$root
  },
  methods: {
    getName() {
      console.log('son :>> ', this.name);
    }
  }
};
</script>
<style></style>

父组件

<template>
  <!-- 设定ref -->
  <son ref="sonRef" />
  <button @click="getSonInfo">getSonInfo</button>
</template>
<script>
import Son from './son.vue';
export default {
  components: { Son },
  data() {
    return {
      name:'我是父组件'
    };
  },
  methods: {
    getSonInfo() {
      // this.$refs.sonRef 获取到子组件
      // 获取子组件中数据
      console.log(this.$refs.sonRef.name);
      // 更改子组件中数据 tip : 强烈不建议更改,不易于维护
      this.$refs.sonRef.name = '我更改了'
      // 使用子组件中方法
      this.$refs.sonRef.getName();

      // 注意:这样使用 this.$refs.sonRef 拿到的是组件实例
      // 如果需要拿到dom根元素,需要这样
      const domEl = this.$refs.sonRef.$el
    }
  }
};
</script>
<style scoped></style>

二、非直接父子传值 ( 有嵌套关系 )

使用provide 与 inject 

比如一些深度嵌套的子组件,想要获取父组件的部分内容

父组件 ( 祖先组件 ) :provide 提供数据

子组件 :inject 使用这个数据

父组件 ( 祖先组件 ) 

  • 静态数据
export default {
  name: 'ancestor',
  // 提供数据
  provide:{
    name:'我是祖先',
    age:345
  }
};
  •  使用data中的数据 

export default {
  name: 'ancestor',
  // 注意,如果需要拿data中的数据,需要这么来写,provide写成一个方法
  provide() {
    return {
      name: '我是祖先',
      // 这样才能拿到数据,vue内部做了个绑定
      age: this.ageArr
    };
  },
  data() {
    return {
      ageArr: [18, 19, 20, 21]
    };
  }
}
  • 使用data中的数据

tip : 在vue3中,如果没有响应式,可以这样写 , 现在不使用应该也是响应式的

// 从vue中导入computed函数
import { computed } from 'vue'

export default {
  name: 'ancestor',
  provide() {
    return {
      name: '我是祖先',
      // 使用computed包裹一下
      age: computed(() => this.ageArr)
    };
  },
  data() {
    return {
      ageArr: [18, 19, 20, 21]
    };
  }
}

子组件

<template>
  <div class="Home-layout">
    <!-- 使用数据 -->
    {{name}} - {{age}}
  </div>
</template>
<script>
export default {
  name: 'son',
  // 拿到需要的祖先数据
  inject: ['name', 'age']
};
</script>

 三、非父子传值 ( 无嵌套关系 )

1. vuex的存取值 

可以看我之前写的vuex的文章哦~

Vue 之 封装Vuex

2. 全局事件总线 (vue2)

 Vue2默认是带有事件总线的功能,因为vue实例自带了以下方法

01 - 在 main.js 中注册

// 在入口 main.js 中,创建一个 bus 总线,这样全局都可以使用
Vue.prototype.$bus = new Vue()

02 - 在某组件发射事件

<template>
  <button @click="btnClick">发射</button>
</template>
 
<script> 
export default {
  methods: {
    btnClick() {
      this.$bus.$emit("emitFn", '我来啦!!!');
    }
  }
}; 

03 - 在某组件监听事件         

<template>
  <div>test</div>
</template>
 
<script> 
export default {
  mounted() {
    // 监听 emitFn 事件
    this.$bus.$on("emitFn", (res) => {
      console.log(res) // 我来啦!!!
    });

    // 只会促发一次的监听
    this.$bus.$once("gulugulu", (res) => {
      console.log('once') // once
    });
  }
};

04 - 移除事件 

<template>
  <div>test</div>
</template>
 
<script> 
export default {
  mounted() {
    // 监听 emitFn 事件
    this.$bus.$on("emitFn", this.sayHello);
  },
  methods: {
    sayHello(res) {
        console.log(res) // 我来啦!!!
    }
  },
  // 移除事件
  beforeDestroy() {
    this.$bus.$off("emitFn")
    // this.$bus.$off("emitFn", this.sayHello)
  }
};

3. 全局事件总线Mitt(vue3)

vue3中移除了$on、$off、$once方法,所以想要继续使用,要通过第三方库,使用mitt

01 - 安装

npm install mitt

02 - 封装一下

新建eventbus.js

// 导入
import mitt from 'mitt';
// 创建
const emitter = mitt();
// 导出
export default emitter;

03 - 发射事件 

<template>
  <div class="son-layout">
    <button @click="emitSon">son</button>
  </div>
</template>
<script>
// 导入封装的
import emitter from '../assets/eventBus';
export default {
  name: 'son',
  methods: {
    emitSon() {
      console.log('我发射啦');
      // 使用
      emitter.emit('sonEmit', { name: '我是son' });
    }
  }
};
</script>
<style></style>

04 - 监听事件

<template>
  <div class="zhong-layout">zhong</div>
</template>
<script>
// 导入
import emitter from '../assets/eventBus';
export default {
  name: 'zhong',
  mounted() {
    // 监听sonEmit事件
    emitter.on('sonEmit', (value) => {
      console.log(value.name, '收到啦');
    });

    // 监听所有事件  type : 事件的名字  info:对应的数据
    // 如果有两个事件,会执行两次,不会有冲突哒~
    emitter.on('*', (type, info) => {
      console.log(info);
      console.log('* listener', type, info);
    });
  },
};
</script>
<style>
</style>

05 - 取消事件 

// 取消所有的事件监听
emitter.all.clear()

// 取消指定事件监听,方法要使用同一个 如 : sonEmit. 
function onFoo(){}
emitter.on('sonEmit', onFoo)
emitter.off('sonEmit', onFoo)
  • 33
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值