Vue组件间通信的7种方法(全)

简介: Vue组件间通信的7种方法(全)

大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

组件之前的通信方法

1. props/$emit

父传子 props 这个只能够接收父组件传来的数据 不能进行修改 可以静态传递 也可以动态传递(一个表达式,一个对象或者布尔值等)父组件属性绑定 子组件用props接收

子改父 子组件的内部通过emit子组件的内部通过emit去触发这个事件 同时也可以传参过去 v-on去传递事件是写在子组件的标签身边的,然后回调函数是写在父组件的methods身上的

//父组件
<template>
  <div>
    <child :msg="msg"  @changeMsg="changeMsg"></child>
    <p>{{msg}}</p>
  </div>
</template>
<script>
import child from "../components/Child";
export default {
  data() {
    return {
      msg: "hello"
    };
  },
  components: { child },
  methods:{
   changeMsg(value){
      this.msg=value
   }
  }
};
</script>
// 这是子组件
<template>
  <div>
      <div @click="change">改变父组件的{{msg}}</div>
  </div>
</template>
<script>
export default {
  props: ["msg"],
  methods:{
   change(){
     this.$emit("changeMsg",123)
   }
  }
};
</script>
复制代码

2.parent/children

$parent 子组件可以获取到父组件身上的属性以及方法,但是一定要注意,如果说这个组件的父组件不止一个的话 那么容易发生报错

ℎ父组件拿到自己身上的子组件的属性已经方法,如果身上的子组件不止一个的话打印ℎ.children父组件拿到自己身上的子组件的属性已经方法,如果身上的子组件不止一个的话打印this.children的时候会以数组的形式展示出来

3.ref

父组件想要拿到子组件身上的数据 还可以给子组件写上ref="名字" 然后在父组件身上 this.$ref.名字就可以拿到子组件 身上的方法已经数据都可以获取到

4.v-model

v-model:将数据传递下去的同时 子组件可以修改父组件提供过来的数据(emit方法)

// 这是父组件
<template>
  <div>
    <child v-model="msg"></child>
    <p>{{msg}}</p>
  </div>
</template>
<script>
import child from "../components/Child";
export default {
  data() {
    return {
      msg: "hello"
    };
  },
  components: { child }
};
</script>
// 这是子组件
<template>
  <div>
      <input :value="value" @input="$emit('input',$event.target.value)">
  </div>
</template>
<script>
export default {
  props: ["value"]
};
</script>
复制代码

5.sync

sync:将数据传递下去的同时 允许子组件可以修改数据

// 父组件
<template>
  <div>
    {{num}}
   <child-a :count.sync="num" />
  </div>
</template>
<script>
import childA from "../components/ChildA";
export default {
  data() {
    return {
      num: 0
    };
  },
  components: { childA }
};
</script>
// 子组件
<template>
  <div>
     <div @click="handleAdd">ADD</div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      counter: this.count
    };
  },
  props: ["count"],
  methods: {
    handleAdd() {
      this.$emit("update:count", ++this.counter);
    }
  }
};
</script>
复制代码

6.,attrs,listeners

attrs包含的是父组件不被prop所识别的特性(📢:inheritAttrs为true属性才会渲染false时属性不会被渲染)可以通过v−bind="attrs"传给内部的组件 包含父组件啊种−事件监听器通过−="listeners包含父组件啊种v−on事件监听器通过v−on="listeners" 传给内部的足迹爱

<template>
  <div>
    <!-- 父组件 -->
    <h1>{{ count }}</h1>
    <son
      :msg="msg"
      :foo="foo"
      :boo="boo"
      :coo="coo"
      :doo="doo"
      title="前端工匠"
      @click.native="handleClick"
      v-on:focus="handleFocus"
    />
  </div>
</template>
<script>
import son from "./son.vue";
export default {
  name: "FatherVue",
  components: { son },
  data() {
    return {
      msg: "父组件的msg",
      foo: "Javascript",
      boo: "Html",
      coo: "CSS",
      doo: "Vue",
    };
  },
  computed: {
    count() {
      return this.$children[0] && this.$children[0].count;
    },
  },
  mounted() {
    console.log(this.$children); // [子组件1, 子组件2,......]
  },
  methods: {
    handleClick() {
      console.log("handleClick");
    },
    handleFocus() {
      console.log("handleFocus");
    },
  },
};
</script>
<!-- 子组件 son.vue -->
<template>
  <div>
    {{ msg }}
    <p>father 父组件的$attrs: {{ $attrs }}</p>
    <button @click="handleClick">click</button>
    <smallson v-bind="$attrs"></smallson>
  </div>
</template>
<script>
import smallson from "./smallson.vue";
export default {
  name: "FuSon",
  components: { smallson },
  inheritAttrs: true, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
  computed: {
    msg() {
      return this.$parent.msg;
    },
  },
  data() {
    return {
      count: "我是子组件的count",
    };
  },
  methods: {
    handleClick() {
      console.log(this.$listeners);
    },
  },
};
</script>
<!-- smallson 组件 -->
<template>
  <div>
    <h1>smallson</h1>
    {{ $attrs }}
  </div>
</template>
<script>
export default {
  name: "SmallSon",
  inheritAttrs: false,
};
</script>
复制代码

7.provide/inject

provide 提供变量 inject 注入变量

📢:

  1. 不论层级多深 只要调用了inject那么久可以注入provide的变量
  2. provide提供的数据在父组件中假设发生了变化 默认后辈的组件是不会响应式变化的 但是如果给的数据是this的数据的话 那么就是响应式的书
<template>
  <div id="app">
    <myInject></myInject>
  </div>
</template>
<script>
import myInject from "./components/zujiantongxin/inject.vue";
export default {
  name: "App",
  provide: {
    for: "provide", 
  },
  // provide() {
  //   return {
  //     baba: this,
  //     msg: this.msg,
  //   };
  // }, 这个时候的数据就可以做到响应式的了 给的就是this的数据 给的就是响应式的数据 就可以做到响应式
  components: {
    myInject,
  },
};
</script>
<template>
  <div>
    <h2>inject 组件</h2>
    <h1>{{ for1 }}</h1>
  </div>
</template>
<script>
export default {
  name: "myInject",
  data() {
    return {
      for1: this.for,//这一步可以省略的
    };
  },
  inject: ["for"],
  mounted() {
    console.log(this.for);
  },
};
</script>
复制代码

7.eventBus

EventBus 本质上就是一个vue实例对象,它可以实现兄弟组件之前的通信,首先在A组件中设置EventBus.��自定义事件名称以及回调函数,然后�组件就是通过��������.on自定义事件名称以及回调函数,然后B组件就是通过eventbus.emit去触发那个自定义事件,将数据传递给A组件

Eventbus的原理实际上就是发布订阅的模式

发布订阅模式 :其实就是一种对象间一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于它的对象都将得到状态改变的通知

vue中常见的发布订阅就是����emiton

redux中常见的就是subscribe

// eventBus.js
import Vue from "vue";
export default new Vue();
<template>
  <!-- comA子组件 -->
  <div>
    <h1>{{ msg }}</h1>
  </div>
</template>
<script>
import eventBus from "./eventBus";
export default {
  name: "面试ComA",
  data() {
    return {
      msg: "",
    };
  },
  mounted() {
    eventBus.$on("message", (val) => {
      this.msg = val;
    });
  },
};
</script>
<template>
  <div>
    <button @click="sendMsg">click 点击 想 COMA 发消息</button>
  </div>
</template>
<script>
import eventBus from "./eventBus";
export default {
  name: "面试ComB",
  data() {
    return {};
  },
  methods: {
    sendMsg() {
      eventBus.$emit("message", "我是来自comB的数据");
    },
  },
};
</script>
<template>
  <div id="app">
    <comA></comA>
    <comB></comB>
  </div>
</template>
<script>
import comA from "@/components/zujiantongxin/comA.vue";
import comB from "@/components/zujiantongxin/comB.vue";
export default {
  name: "App",
  components: {
    comA,
    comB,
  },
};
</script>

 

大厂面试题分享 面试题库

前后端面试题库 (面试必备) 推荐:★★★★★

地址:前端面试题库  web前端面试题库 VS java后端面试题库大全

相关文章
|
24天前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
26天前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
21天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
125 64
|
27天前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
32 1
vue学习第一章
|
21天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
28 8
|
21天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
24天前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
21 1
|
24天前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
27 1
|
24天前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
24天前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能