八种vue实现组建通信的方式

目录
  • 一、组件通信
    • 1、props 父组件--->子组件通信
    • 2、$emit 子组件--->父组件传递
    • 3、bus(事件总线) 兄弟组件通信
    • 4、$parent、$children 直接访问组件实例
    • 5、$refs
    • 6、provide/inject(提供/注入) 多组件或深层次组件通信
    • 7、slot(slot-scope作用域插槽) 子元素-->父元素(类似于通信)
    • 8、vuex状态管理

一、组件通信

1、props 父组件--->子组件通信

  • 父组件---属性的方式传值给子组件
  • 子组件---props方式接收数据
<Son :datas="fData"></Son>

<script>
import Son from '@/components/son'
  export default{
    name:'Father',
    components:{Son},
    data(){
      return{
        fData:'我是父组件向子组件传递的值-props方式'
      }
    }
  }
</script>

子组件props接受的参数名称,要与父组件传递时定义的属性名一致

<template>
  <div>我是父组件的数据:{{fData}}</div>
  <div @click=changeData>我是父组件传递修改后的数据:{{mydata}}</div>
</template>
<script>
  export default{
    name:'Son',
    props:{
      fData:{
        type:String,
        default:''
      }
    }
    data(){
      mydata:this.fatherData
    },
    methods:{
     changeData(){
        this.mydata += '改变数据'
      }
    },
  }
</script>

注意:

  • 子组件不能够直接去修改父组件传递的值修改的:因为Vue的单向数据流机制,如果直接修改那父组件的值就被“污染”了。(props是单向绑定的(只读属性):当父组件的属性变化时,将传导给子组件,但是反过来不会)

报错信息大概是:vue使用prop通信出错:Avoid mutating a prop directly since the value will be overwritten whenever the parent

  • 解决方案:可以在子组件内定义一个变量mydata去接收fData数据
  • 参数传递类型不确定是可以这么写
props:{
    fData:{
        type:[String,Number],
        default:''
    }
}

2、$emit 子组件--->父组件传递

  • 子组件绑定自定义事件
  • $emit()第一个参数为:自定义的事件名称,第二个参数为:需要传递的数据
  • 使用 $emit() 触发更改数据子组件
<el-button @click="handleEmit">改变父组件</el-button>

<script>
 export default{
   name:'Son',
   methods:{
     handleEmit(){
       this.$emit('triggerEmit','子组件的数据')
     }
   }
 }
</script>

父组件(子组件发送的事件名称,要和父组件接受的事件名称一致)

<Son @triggerEmit="changeData"></Son>

<script>
 import Son from '@/components/son'
 export default{
   name:'Father',
   components:{Son},
   methods:{
     changeData(name){
       console.log(name) // => 我是来自子组件的数据
     }
   }
 }
</script>

$emit与props结合 兄弟组件传值

  • 父组件引入两个子组件
  • 父组件充当一个桥梁作用父组件
<childA :myName="name"></ChildA>
<ChildB :myName="name" @changeName="editName"></ChildB>  

export default{
  data() {
    return {
      name: '数据你好'
    }
  },
  methods: {
    editName(name){
      this.name = name
    }
  }
}

子组件B改变,接收数据

<p>姓名:{{ myName }}</p>
<button @click="changeName">修改姓名</button>

<script>
export default{
  props: {
    myName:String
  },
  methods: {
    changeName() {
      this.$emit('changeName', '新数据名称')
    }
}
}
</script>

子组件A接收数据

<p>姓名:{{ newName }}</p>

<script>
export default{
  props: {
    myName:String
  }
}
</script>

3、bus(事件总线) 兄弟组件通信

非父子组件或更多层级间组件间传值,在Vue中通过单独的事件中心来管理组件间的传值

  • 创建一个公共的bus.js文件
  • 暴露出Vue实例
  • 传递数据方,通过一个事件触发bus.$emit(方法名,传递的数据)
  • 接收数据方,在生命周期函数中,通过bus.$on(方法名,[params])来监听
  • 销毁事件,在接受数据方,通过bus.$off(方法名)销毁之后无法监听数据
import Vue from "vue"
const bus=new Vue()
export default bus

需要改变数据的组件中定义调用

<template>
  <div>
    <div>我是通信组件A</div>
    <button @click="changeName">修改姓名</button>
  </div>
</template>

<script>
import bus from "@/utils/Bus.js";
export default {
  components: {},
  data() {
    return {};
  },
  mounted() {
    console.log(bus);
  },
  methods: {
    changeName() {
      bus.$emit("editName", "数据集!");
    },
  },
};
</script>

<style lang='scss' scoped>
</style>

另外一个组件中同样引入bus.js文件,通过$on监听事件回调

<template>
  <div>
  <span>名称:{{name}}</span>
    <div>我是通信组件B</div>
  </div>
</template>

<script>
import  bus  from "@/utils/Bus.js";
export default {
  components: {},
  data() {
    return {name};
  },
  mounted() {
    bus.$on("editName", (name) => {
        this.name=name
      console.log(name); //
    });
  },
  methods: {},
};
</script>

<style lang='scss' scoped>
</style>

4、$parent、$children 直接访问组件实例

  • 子组件通过---> $parent 获得父组件实例
  • 父组件通过---> $children 获得子组件实例数组

子组件---this.$parent可以获取到父组件的方法、data的数据等,并可以直接使用和执行

<template>
  <div>我是子组件</div>
</template>

<script>
export default{
  name:"Son",
  data(){
    return{
      sonTitle: '我是子组件的数据'
    }
  },
  methods:{
    sonHandle(){
      console.log('我是子组件的方法')
    }
  },
  created(){
    console.log(this.$parent)
    console.log(this.$parent.fatherTitle) // => 我是父组件的数据
    this.$parent.fantherHandle() // => 我是父组件的方法
  }
}
</script>

父组件 --- 获取子组件实例的,并且获取的实例是一个数组形式,this.$children[0]才可以获取某个组件实例,并调用组件方法和数据

<template>
  <div>
    <Son>我是父组件</Son>
  </div>
</template>

<script>
import Son from './son.vue'

export default{
  name: 'father',
  components:{
    Son
  },
  data(){
    return{
      fatherTitle: '我是父组件的数据'
    }
  },
  methods:{
    fantherHandle(){
      console.log('我是父组件的方法')
    }
  },
  mounted(){
    console.log(this.$children)
    console.log(this.$children[0].sonTitle) // => 我是子组件的数据
    this.$children[0].sonHandle() // => 我是子组件的方法
  }
}
</script>

5、$refs

ref被用来给元素或子组件注册引用信息。引用信息将会注册在父组件的 $refs 对象上。

父组件使用 $refs 获得组件实例

<template>
  <div>
    <Son ref="son"></Son>
  </div>
</template>

<script>
import Son from './son.vue'

export default{
  name: 'father',
  components:{
    Son
  },
  mounted(){
    console.log(this.$refs.son) /*组件实例*/
  }
}
</script>

6、provide/inject(提供/注入) 多组件或深层次组件通信

provide/inject详解

  • 父组件使用 provide 注入数据
  • 子组件使用 inject 使用数据
/*父组件*/
export default{
 provide: {
   return{
     provideName: '贩卖前端仔'
   }
 }
}

至此provideName这个变量可以提供给它其下的所有子组件,包括曾孙、孙子组件等,只需要使用 inject 就能获取数据

/*子组件*/
export default{
  inject: ['provideName'],
  created () {
    console.log(this.provideName) // => "贩卖前端仔"
  }
}
  • 父组件不需要知道哪个组件使用它提供出去的数据
  • 子附件不需要知道这个数据从哪里来

7、slot(slot-scope作用域插槽) 子元素-->父元素(类似于通信)

  • 用作一个 (能被传递数据的)可重用模板,来代替已经渲染好的元素
  • 在子组件中,只需将数据传递到插槽,就像你将 prop 传递给组件一样
  • 注意:父级插槽接收内容是最外侧元素 ,必须要有属性slot-scope子元素
<template>
  <div>
    <div class="isSon">
        <slot :info='arrList'></slot>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  data() {
    return {arrList:[1,'aa','张三']};
  },
  mounted() {
  },
  methods: {

  },
};
</script>

父元素

<template>
<div>
    <SonG>
        <span slot-scope="props">
            <ul>
                aa
                <li v-for="item in props.info" :key="item">
                    {{item}}
                </li>
            </ul>
        </span>
    </SonG>
</div>
</template>

<script>

import SonG from '../components/SonG.vue'
export default {
   components:{
       SonG
   },
   data () {
       return {
       }
   }
}
</script>

8、vuex状态管理

  • 相当于一个公共数据的仓库
  • 提供一些方法管理仓库数据
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
  },
  mutations: {
  },
  actions: {
  },
  modules: {
  }
})

到此这篇关于八种vue实现组建通信的方式的文章就介绍到这了,更多相关vue实现组建通信的方式内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue3 与 vue2 优点对比汇总

    目录 优点1:diff算法的优化 优点2:hoistStatic 静态提升 优点3:cacheHandlers 事件侦听器缓存 优点4:ssr渲染 优点5:更好的Ts支持 优点6:Compostion API: 组合API/注入API 优点7:更先进的组件 优点8:自定义渲染API 优点9:按需编译,体积比vue2.x更小 优点10:支持多根节点组件 ​​​​​​摘要: Vue3新版本的理念成型于 2018 年末,当时的 Vue 2 已经有两岁半了.比起通用软件的生命周期来这好像也没那么久,Vu

  • Vue实现可拖拽组件的方法

    本文为大家分享了Vue实现可拖拽.拖拽组件,供大家参考,具体内容如下 描述: 组件仅封装拖拽功能,内容通过#header.#default.#footer插槽 自定义 效果: 代码: <template> <div ref="wrapper" class="drag-bar-wrapper" > <div ref="header" class="drag-bar-header" > <

  • 关于怎么在vue项目里写react详情

    我们可以直接创建jsx/tsx文件 这次的项目结构是这样的: 在vue文件里这么使用 // index.vue <template> <div class="wrapper"> <Common :opt="list" /> </div> </template> <script lang="ts"> import { Component, Vue } from "vu

  • Vue实现动态圆环百分比进度条

    最近在开发小程序的时候,碰到一个实现圆环百分比进度条的需求,类似如下设计图: 小白的我感觉实现起来有难度,于是上百度看看别人是怎么做的,结果没找到一个满意的,要不是静态的实现,就是需要用到比较多的DOM操作,小程序还是尽量避免直接操作DOM. 下面是我以Vue组件形式做的一个动态的实现,先上效果图: 效果 实现步骤 画一个饼图 .pie { display: inline-block; position: relative; width: 150px; height: 150px; margin

  • vue+element实现下拉菜单并带本地搜索功能示例详解

    需求: 后台返回数组对像,前端组合成数组,根据name组合成一个个数组并把后台返回的值当成一个children推入数组,在数组中自定义属性备份数据防止搜索的时候改变原数组使得数组无法回退 这里是用的vuex存储,因为多个页面使用同一个接口;所以没必要重复请请求 src\store\module\metadata.js /* * @Author: your name * @Date: 2021-09-02 15:46:45 * @LastEditTime: 2021-09-16 17:39:53

  • vue实现百分比占比条效果

    本文实例为大家分享了vue实现百分比占比条的具体代码,供大家参考,具体内容如下 效果图 1.各自占比 /p> 2.左百分百 3.右百分百 代码实现 <template> <div class="about"> <!-- <h1>This is an about page</h1> --> <div class="step"> <!-- 左边100%的时候不显示斜边三角形,并且增加右边

  • vue中wangEditor的使用及回显数据获取焦点的方法

    在做后台管理项目时常常会用到富文本编辑器,在这里推荐大家使用wangEditor,非常好用 第一步安装 npm i wangeditor --save 第二步在项目中使用 html 页面中的编辑.添加布局在最下面 <div id="div1"> <p>欢迎使用 <b>wangEditor</b> 富文本编辑器</p> </div> <el-button type="primary" @cl

  • vue实现动态进度条效果

    本文实例为大家分享了vue实现动态进度条效果的具体代码,供大家参考,具体内容如下 演示效果: 结构 progress/index.js const controller = { init: require('./controllers/html'), speed: require('./controllers/speed') } exports.init = controller.init exports.speed = controller.speed progress/controllers

  • 八种vue实现组建通信的方式

    目录 一.组件通信 1.props 父组件--->子组件通信 2.$emit 子组件--->父组件传递 3.bus(事件总线) 兄弟组件通信 4.$parent.$children 直接访问组件实例 5.$refs 6.provide/inject(提供/注入) 多组件或深层次组件通信 7.slot(slot-scope作用域插槽) 子元素-->父元素(类似于通信) 8.vuex状态管理 一.组件通信 1.props 父组件--->子组件通信 父组件---属性的方式传值给子组件 子

  • 八种Vue组件间通讯方式合集(推荐)

    前言 Vue 提供了各种各样的通讯,其中包括 兄弟间 的通讯和 非兄弟间 的通讯,借此机会做个总结,查阅起来方便.如果喜欢的话可以帮忙点个赞 :+1: 或者关注一下 :yum: 1.props 目录结构 components ├── Parent.vue // 父亲 ├── Son1.vue // 儿子1 代码结构 在父亲组件中使用儿子组件,给儿子通过 :date="xxx" 单向传值 <template> <div> <div>爸爸:{{date}

  • vue组件间通信六种方式(总结篇)

    前言 组件是 vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用.一般来说,组件可以有以下几种关系: 如上图所示,A 和 B.B 和 C.B 和 D 都是父子关系,C 和 D 是兄弟关系,A 和 C 是隔代关系(可能隔多代). 针对不同的使用场景,如何选择行之有效的通信方式?这是我们所要探讨的主题.本文总结了vue组件间通信的几种方式,如props. $emit / $on .vuex. $parent / $children . $attrs

  • vue中各种通信传值方式总结

    1.路由通信传值 路由通信是通过路由跳转用query把参数带过去,也是vue常用的通信手段. 例子:创建并在路由注册一个组件Head <template> <div id="head"> <button @click="handleChange">clickMe</button> //给按钮绑定点击事件 </div> </template> <script> export defau

  • vue实现组件通信的八种方法实例

    目录 1.props 父组件--->子组件通信 2.$emit 子组件--->父组件传递 3.bus(事件总线) 兄弟组件通信 4.$parent.$children 直接访问组件实例 5.$refs 6.provide/inject(提供/注入) 多组件或深层次组件通信 7.slot(slot-scope作用域插槽) 子元素-->父元素(类似于通信) 8.vuex状态管理 总结 对于vue来说,组件之间的消息传递是非常重要的,下面是我对组件之间消息传递的常用方式的总结 1.props

  • 详解Vue组件之间通信的七种方式

    使用Vue也有很长一段时间,但是一直以来都没对其组件之间的通信做一个总结,这次就借此总结一下. 父子组件之间的通信 1)props和$emit 父组件通过props将数据下发给props,子组件通过$emit来触发自定义事件来通知父组件进行相应的操作 具体代码如下: ``` // 父组件 <template> <div> <h3>props和$emit</h3> <Children v-on:changeMsg="changeMsg"

  • Vue.js组件通信的几种姿势

    写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出. 文章的原地址: https://github.com/answershuto/learnVue . 在学习过程中,为Vue加上了中文的注释 https://github.com/answershuto/learnVue/tree/master/vue-src ,希望可以对其他想学习Vue源码的小伙伴有所帮助. 可能会有理解存在偏差的地方,欢迎提issu

  • 详解MySQL数据库优化的八种方式(经典必看)

    引言: 关于数据库优化,网上有不少资料和方法,但是不少质量参差不齐,有些总结的不够到位,内容冗杂. 偶尔发现了这篇文章,总结得很经典,文章流量也很大,所以拿到自己的总结文集中,积累优质文章,提升个人能力,希望对大家今后开发中也有帮助 1.选取最适用的字段属性 MySQL可以很好的支持大数据量的存取,但是一般说来,数据库中的表越小,在它上面执行的查询也就会越快.因此,在创建表的时候,为了获得更好的性能,我们可以将表中字段的宽度设得尽可能小. 例如,在定义邮政编码这个字段时,如果将其设置为CHAR(

  • vue组件传值的实现方式小结【三种方式】

    本文实例讲述了vue组件传值的实现方式.分享给大家供大家参考,具体如下: 前言 vue的组件传值分为三种方式:父传子.子传父.非父子组件传值 引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递 父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示: 下面我们就开始用代码(一言不合就上代码)详细的介绍vue组件传值的三种方式 1.父传子 子组件的代码: <template> <div id="container"&

  • Selenium Webdriver元素定位的八种常用方式(小结)

    在使用selenium webdriver进行元素定位时,通常使用findElement或findElements方法结合By类返回的元素句柄来定位元素.其中By类的常用定位方式共八种,现分别介绍如下. 1. By.name() 假设我们要测试的页面源码如下: <button id="gbqfba" aria-label="Google Search" name="btnK" class="gbqfba"><

随机推荐