当前位置: 首页 > news >正文

组件通信的方法

目录

组件通信共有12个方式 三大种类

1.父子组件通信

2.兄弟组件通信

3.跨层级组件通信

总结

父子:

兄弟 

跨组件


组件通信共有12个方式 三大种类

1.props

2.$emit/v-on

3..sync

4.v-model

5.ref

6.children/parent

7.attrs/listeners

8.provide/inject

9.EventBus

10.Vuex

11.$root

12.slot

这十二种可以分为三类

1.父子组件通信

  1. props
  2. $emit/v-on
  3. attrs/listeners
  4. ref
  5. .sync
  6. v-model
  7. children/parent

父组件    通过属性传值  ,  子 props 接收

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>父组件向子组件传值--props</title>
    <script src="./js/vue.min.js"></script>
</head>
<body>
    <div id="app">   
        <menu-item title="来自父组件的值"></menu-item>
  <!--   在子组件身上绑定自定义属性来接收父组件data中的数据 -->
        <menu-item :tit="title"></menu-item>
    </div>
    <script>
Vue.component('menu-item',{
    props:['tit'],  //props用来接收父组件传过来的值
    //在props中使用驼峰形式,模版中要改为使用短横线拼接  props里面的值只读,不能修改
    //props是单向数据流
    data(){
        return{
        }
    },
    template:'<div>{{tit}}</div>'
})
        var vm=new Vue({
           el:'#app',
           data:{
              title:'我是父组件中的数据'
           },
           methods:{
           }
        });
    </script>
</body>
</html>

子向父传值    

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>
<body>
  <div id="app">
    <!--   父组件 -->
    <div :style='{fontSize:fontSize+"px"}'>{{pmsg}}</div>
   <!--  子组件 -->
    <menu-item :parr="parr" @aas="blune"></menu-item>
  </div>
  <script type="text/javascript" src="js/vue.js"></script>
  <script type="text/javascript">
    /*
      子组件向父组件传值-基本用法
      props传递数据原则:单向数据流
    */
    Vue.component('menu-item', {
     props:['parr'],
     data(){
           return {
               msg1:'这是子组件传递过来的值'
           }
        },
      template: `
        <div>
          <ul>
            <li v-for="(item,index) in parr" :key="index">{{item}}</li>
          </ul>
          <button @click='dd'>扩大父组件中字体大小</button> 
        </div>
      `,
      methods:{
          dd(){
           this.$emit("aas",this.msg1)
          } 
      }
    });
 //$emit
    var vm = new Vue({
      el: '#app',
      data: {
        pmsg: '父组件中内容',
        parr: ['apple','orange','banana'],
        fontSize: 10
      },
      methods: {
        blune(message){
            this.fontSize+=5;
            console.log(message);   
        }
      }
    });
  </script>
</body>
</html>

2.兄弟组件通信

  1. EventBus
  2. Vuex
  3. $parent

兄弟组件传值 事件总线

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./js/vue.min.js"></script>
</head>
<body>
    <div id="app">
        <brother></brother>
        <sister></sister>
    </div>
    <script>
        var enveBus = new Vue();
        Vue.component('brother', {
            data() {
                return {
                    kk: ''
                }
            },
            methods: {
                dd() {
                    enveBus.$emit("bTs", '这是哥哥给妹妹的爱')
                }
            },
            template: `
        <div>
          <button @click='dd'>这是一个哥哥组件---{{kk}}</button>
        </div>
      `,
            mounted() {
                enveBus.$on('asd', (result) => {
                    this.kk = result;
                })
            }
        });
        Vue.component('sister', {
            data() {
                return {
                    sis: ''
                }
            },
            template: `
   <div>
     <button @click="cc">这是一个妹妹组件---{{sis}}</button> 
   </div>
 `,
            mounted() {
                enveBus.$on('bTs', (message) => {
                    this.sis = message
                })
            },
            methods: {
                cc() {
                    enveBus.$emit('asd', '这是妹妹对哥哥的爱');
                }
            }
        });
        var vm = new Vue({
            el: '#app',
            data: {
            },
            methods: {
            }
        });
    </script>
</body>
</html>

跨层级组件通信

  1. provide/inject
  2. EventBus
  3. Vuex
  4. attrs/listeners
  5. $root

跨组件 provide

<script lang="ts" setup>
// provide, inject

import { provide } from 'vue';

// provide(名字,值)
const { separtor = '' } = defineProps<{
  separtor?: string
}>()

// 向后代传递值
provide('separtor', separtor)
</script>
<template>
<div class="xtx-bread">
  <slot></slot>
</div>
</template>

<style scoped lang="less">
.xtx-bread {
  display: flex;
  // padding: 25px 10px;
  &-item {
    a {
      color: #666;
      transition: all 0.4s;
      &:hover {
        color: @xtxColor;
      }
    }
  }
  i {
    font-size: 12px;
    margin-left: 5px;
    margin-right: 5px;
    line-height: 22px;
  }
}
</style>

inject

<script lang="ts" setup>
import { inject } from 'vue';

// inject(名字)
// 获取分隔符
const separtor = inject('separtor')

defineProps<{
  to?: string // 要跳转的位置
}>()
</script>
<template>
<slot> </slot>
<div class="xtx-bread-item">
  <!-- 是否需要跳转 -->
  <router-link v-if="to" :to="to"><slot> </slot></router-link>
  <slot v-else> </slot>

  <!-- 分隔符从祖先来的 -->
  <i v-if="separtor">{{ separtor }}</i>
  <!-- 默认分隔符 -->
  <i v-else class="iconfont icon-angle-right"></i>
</div>

</template>
<style lang="less" scoped>
.xtx-bread-item {
  i {
    margin: 0 6px;
    font-size: 10px;
  }
  // 最后一个i隐藏
  &:nth-last-of-type(1) {
    i {
      display: none;
    }
  }
}
</style>

总结

父子:

1.props 通过属性传值,子props接收

2.$emit/v-on 父组件使用子组件声明的自定义事件,传值时触发

3.v-model 原理即props与$emit;父:v-model="值"、子:this.$emit('input',值)

4..sync 原理即:属性名& this.$emit('update:属性名', 值)

5.refs 操作dom,通过this.$refs

6.$children/$parent this.$children获取所有子组件的数组对象,包括子组件的属性和监听事件; this.$parent获取父组件的对象,包括子组件的属性和监听事件;

7.$attrs / $listeners 读取到的只读(不可改): this.$attrs获取所有当前元素的属性(不包括:class、style、props传递给子的) this.$listeners获取所有当前元素的监听事件(不包括:.native声明的)

兄弟 

1.vuex state中为动态分享的数据; mutations为方法,修改state中的数据; actions(c,v)异步函数(也可为同步)异步操作后c.commit()调用components中的函数间接修改state的数据; getters类似于computed动态属性 modules:用于模块化时的声明

2.EventBus 通过自定义事件:this.$emit与this.$on配合使用 ...

跨组件

1.provide/inject provide('键','值') const a = inject('键')

2.$root 通过this.$root获取到根,从而逐级查找到具体项(标签元素)的属性与值

3.vuex

4.EventBus

5.$attrs/$listeners

相关文章:

  • 【Pytorch】torch. matmul()
  • 【JVM笔记】类型转换字节码指令
  • 聚观早报 | 东方甄选与顺丰、京东合作;拼多多跨境电商平台上线
  • 如何创建并运行java线程呢?
  • dubbo安装跟部署
  • ESP8266-Arduino编程实例-QRE1113红外反射传感器
  • 【Django】REST_Framework框架——Mixin类和GenericAPIView中的视图子类源码解析
  • Springboot、Tomcat启动加载外部指定文件夹下的jar文件
  • MySQL教程 - 索引(Index)
  • 神经网络做预测的原理,神经网络预测空气质量
  • java代码审计的点
  • alsa-lib和alsa-utils移植
  • SAP 电商云 Spartacus 服务器端渲染的单步调试详细步骤
  • 尚硅谷Vue系列教程学习笔记(12)
  • Flutter 高级教程之如何开发iOS Widget小组件展示SQLite本地数据库数据(教程含完整源码)
  • JavaScript 如何正确处理 Unicode 编码问题!
  • android百种动画侧滑库、步骤视图、TextView效果、社交、搜房、K线图等源码
  • C# 免费离线人脸识别 2.0 Demo
  • CSS 专业技巧
  • ES6系列(二)变量的解构赋值
  • Flex布局到底解决了什么问题
  • JS函数式编程 数组部分风格 ES6版
  • JS实现简单的MVC模式开发小游戏
  • Linux链接文件
  • Redis中的lru算法实现
  • Vue全家桶实现一个Web App
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 多线程 start 和 run 方法到底有什么区别?
  • 记录:CentOS7.2配置LNMP环境记录
  • 漂亮刷新控件-iOS
  • 你学不懂C语言,是因为不懂编写C程序的7个步骤 ...
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • #1014 : Trie树
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • (1)(1.9) MSP (version 4.2)
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)甲方乙方——赵民谈找工作
  • (转)用.Net的File控件上传文件的解决方案
  • .bashrc在哪里,alias妙用
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net 8 发布了,试下微软最近强推的MAUI
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .NET的微型Web框架 Nancy
  • .NET面试题(二)
  • .project文件
  • @Builder用法
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [ 蓝桥杯Web真题 ]-布局切换
  • [20150904]exp slow.txt