Vue 组件通信的8种方式

更新日期: 2021-06-22阅读: 965标签: 组件


前言

做了半年的公司系统,终于就在前天上线了。后期改BUG时间拖得太长了,出现的大部分BUG 是 前端 与后端 信息不对称导致的,逻辑性错误很不多,用户体验上稍微差点,毕竟第一次做这么大的系统(100w+),通过这次系统的开发,总结了不少经验,如何更好的跟后端人员协作开发以及如何设计来提高用户体验上,之前自己做开发没关注这方面,只注重功能实现,后期的这块多补补。

项目上线后,接下来就是后期的维护更新了,最近时间终于不是之前那么忙碌了,简单的对系统做了下复盘。 由于项目采用的技术栈是vue, 平常开发只注重功能实现了,接下来陆续会对 Vue 深入分析,来封装常用业务组件,以及Vue源码解析<br/><br/>    本章将是对Vue 组件通信的8方法总结,日常开发组件通信密切,熟悉组件通信可以更好的开发业务。

Vue 组件之间传值

1. 父组件 向 子组件 传递值

在父组件中引入子组件
注册子组件
在页面中使用,子组件标签上 动态绑定传入动态值 / 静态值
在子组件中,使用 props 来接受 父组件 传递过了的值

子组件接收的父组件的值分为引用类型和普通类型两种:

  • 普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
  • 引用类型:数组(Array)、对象(Object)
#父组件

<template>
  <div>
    <!-- 传递值 -->
    <Test
     :obj="obj" 
     info="测试"/>
  </div>
</template>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      obj: {
        code: 200,
        title: "前端自学社区",
      },
    };
  },
};
</script>
<template>
    <div>
        <h1>{{obj.code}}</h1><br>
        <h2>{{obj.title}}</h2>
        <h3>{{info}}</h3>
    </div>
</template>

<script>
    export default {
        name:'test',
        props:{
            obj:Object,
            info: [String,Number]  //info值为其中一种类型即可,其他类型报警告
        }
    }
</script>
由于 Vue 是 单向数据流, 子组件 是不能直接 修改 父组件 的 值。

2. 子组件 向父组件传递值

子组件通过绑定事件,通过 this.$emit('函数名',传递参数)
#父组件

<Test
     :obj="obj" 
     info="测试"
     @modify="modifyFatherValue"/>

<script>
// 引入子组件
import Test from "../components/Test.vue";
export default {
  name: "about",
  // 注册子组件
  components: {
    Test,
  },
  data() {
    return {
      msg:'我是父组件'
    };
  },
  methods:{
    // 接受子组件传递来的值,赋值给data中的属性
    modifyFatherValue(e){
      this.msg = e
    }
  }
};
</script>
# 子组件

<button @click="modifyValue">修改父组件的值</button>


<script>
    export default {
        name:'test',
        methods:{
            modifyValue(){
                this.$emit('modify','子组件传递过来的值')
            }
        }
    }
</script>

3. 父组件 通过 $refs / $children 来获取子组件值

$refs :

  • 获取dom 元素 和 组件实例来获取组件的属性和方法。
  • 通过在 子组件 上绑定 ref ,使用 this.$refs.refName.子组件属性 / 子组件方法

$children :

  • 当前实例的子组件,它返回的是一个子组件的集合。如果想获取哪个组件属性和方法,可以通过 this.$children[index].子组件属性/f方法

示例 Text 组件

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是子组件值"
            }
        },
        props:{
            obj:Object,
            info: [String,Number]
        },
        methods:{
            getValue(){
                console.log('我是Test1')
            }
        }
    }
</script>

示例 Text2组件

<template>
    <div>
        <h1>我是Test2</h1>
    </div>
</template>

<script>
    export default {
        name:'test',
        data() {
            return {
                datas:"我是Test2"
            }
        },
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        methods:{
            getTest2(){
                console.log(this.datas)
            }
            
        }
    }
</script>

refs

<template>
  <div>
   // 给子组件上绑定 ref  
    <Test
      ref="son"
    />
   <Test2/>
  </div>
</template>

// 通过 $refs 示例来获取 子组件的属性和方法

 console.log( this.$refs.son.datas) 

 this.$refs.son.getValue()

$children

//  通过 $children  来获取 子组件的属性和方法
      this.$children[0].getValue(); // 我是 Test1
      this.$children[1].getTest2();  //我是 Test2
      console.log(`---------${this.$children[1].datas}`); //我是Test2

4. 子组件 通过 $parent 来获取父组件实例的属性和方法

<script>
    export default {
        name:'test',
        created(){
         console.log( this.$parent.obj ) 
         this.$parent.getQuery()
        },
        
    }
</script>

5. $attrs 和 $listeners 获取父组件实例属性和方法(组件嵌套情况下使用)

$attrs:包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind=” $attrs” 传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。

$listeners:包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。

使用场景: 多层嵌套组件的情况下使用,可以避免使用Vuex来做数据处理, 使用 v-bind="$attrs" v-on="$listeners" 很方便达到业务数据传递。

父组件

<template>
    <div>
        <Test3  
        :status="status" 
        :title="title"
        @getData="getData" />
    </div>
</template>

<script>
import Test3 from "../components/Test3.vue";
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          getData(){
              console.log(this.title)
          }  
        },
        components:{
            Test3
        }
    }
</script>

子组件1

<template>
  <div>
    <h1>Test3 组件</h1>
    <br /><br />
    // 通过 $attrs(属性,除了【props中定义的属性】)  和 $listeners(方法)  来给嵌套子组件传递父组件的属性和方法
    <Test4   v-bind="$attrs" v-on="$listeners"/>
  </div>
</template>

<script>
// 引入子子组件   
import Test4 from "../components/Test4";
export default {
  name: "test3",
  props: ["title"],
  components: {
    Test4,
  },
  created() {
    console.log(this.$attrs);  //{status: false}
    console.log("-----------");
    console.log(this.$listeners); // {getData: ƒ}
  },
};
</script>

嵌套子组件

<template>
    <div>
        <h1>Test4 组件</h1>
    </div>
</template>

<script>
    export default {
        name:'test4',
        created(){
            console.log('-----Test4------')
            console.log(this.$attrs) //{status: false}
            console.log(this.$listeners) // {getData: ƒ}
        }
    }
</script>

6. 跨组件之间传值

通过新建一个 js 文件,导入 vue , 导出 vue 实例; 然后通过 给导出的实例 上绑定事件 $emit 事件 , 然后再通过 $on 监听触发的事件,这样就可以达到全局组件数据共享。

使用场景:

它可以满足任意场景传递数据, 父子组件传值 , 子父传值 , 兄弟组件之间传值 , 跨级组件之间传值 .

通信数据比较简单时,可以采用这种 方案,项目比较庞大,可以采用 Vuex .

vue .js

/*
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:48:56
 * @LastEditTime: 2021-01-22 15:51:24
 * @LastEditors: ZhangXin
 */

 import Vue from 'vue'

 export default new Vue()

组件A

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 14:44:17
 * @LastEditTime: 2021-01-22 16:25:33
 * @LastEditors: ZhangXin
-->

<template>
    <div>  
        <button @click="changeValue">改变</button>
    </div>
</template>

<script>
import zxVue from '../util/newVue.js';
    export default {
        name:'person',
        data(){
            return {
                title:'personal 组件',
                status: false
            }
        },
        methods:{
          changeValue(){
             // 通过给 vue实例绑定事件
             zxVue.$emit("getTitle", this.title)   
          }  
        }
    }
</script>


组件C

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 15:07:30
 * @LastEditTime: 2021-01-22 16:26:38
 * @LastEditors: ZhangXin
-->
<template>
  <div>
    <h1>Test4 组件</h1>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
import zxVue from "../util/newVue";
export default {
  name: "test4",
  data() {
    return {
      title: "test4",
    };
  },
  mounted(){
    // 通过 vue 实例.$on  监听事件名,来接收跨级组件传递过来的值
    zxVue.$on("getTitle", (item) => {
      this.title = item;
      console.log(item)
    });

  }
};
</script>

7. Vuex

这里就不介绍了,完了单独写一篇文章精讲 Vuex

8. provide 和 inject 实现父组件向子孙孙组件传值。(层级不限)

provide 和 inject 这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。

provide :

  • 是一个对象或返回一个对象的函数
  • 该对象包含可注入其子孙的属性。

inject :

  • 是一个字符串数组 或者是一个对象
  • 用来在子组件或者子孙组件中注入 provide 提供的父组件属性。

使用场景:

provide/inject可以轻松实现跨级访问父组件的数据

# provide
//对象
provide:{
    name:'测试'
}
//返回对象的函数
provide(){
    return {
        name: '测试'
    }
}

#inject
inject:['name']

父组件

<!--
 * @Description: 
 * @Author: ZhangXin
 * @Date: 2021-01-22 23:24:16
 * @LastEditTime: 2021-01-22 23:49:50
 * @LastEditors: ZhangXin
-->
<template>
    <div>
        <h1>我是父组件</h1>
        <Son />
    </div>
</template>

<script>
import Son from '../components/son/SonOne'
    export default {
        name:'father',
        provide(){
            return {
                titleFather: '父组件的值'
            }
        },
        components:{
            Son
        },
        data(){
            return{
                title:'我是父组件 '
            }
        },
        
    }
</script>

子组件

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

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>

子孙组件

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

<script>
import SonTwo from '../son/SonTwo'
    export default {
        name:'sonone',
        components:{
           SonTwo
        },
        inject:['titleFather'],
        created(){
             console.log(`${this.titleFather}-----------SonTwo`)
        },
        data(){
            return{
                title:'我是子组件 '
            }
        },
        
    }
</script>


链接: https://www.fly63.com/article/detial/10560

Vuetify基于vue2.0,为移动而生的组件框架

Vuetify 支持SSR(服务端渲染),SPA(单页应用程序),PWA(渐进式Web应用程序)和标准HTML页面。 Vuetify是一个渐进式的框架,试图推动前端开发发展到一个新的水平。

Vue中插槽的作用_Vue组件插槽的使用以及调用组件内的方法

通过给组件传递参数, 可以让组件变得更加可扩展, 组件内使用props接收参数,slot的使用就像它的名字一样, 在组件内定义一块空间。在组件外, 我们可以往插槽里填入任何元素。slot-scope的作用就是把组件内的数据带出来

react 函数子组件(Function ad Child Component)

函数子组件(FaCC )与高阶组件做的事情很相似, 都是对原来的组件进行了加强,类似装饰者。FaCC,利用了react中children可以是任何元素,包括函数的特性,那么到底是如何进行增强呢?

Vue和React组件之间的传值方式

在现代的三大框架中,其中两个Vue和React框架,组件间传值方式有哪些?组件间的传值是灵活的,可以有多种途径,父子组件同样可以使用EventBus,Vuex或者Redux

vue.js自定义组件directives

自定义指令:以v开头,如:v-mybind。bind的作用是定义一个在绑定时执行一次的初始化动作,观察bind函数,它将指令绑定的DOM作为一个参数,在函数体中,直接操作DOM节点为input赋值。

vue中prop属性传值解析

prop的定义:在没有状态管理机制的时候,prop属性是组件之间主要的通信方式,prop属性其实是一个对象,在这个对象里可以定义一些数据,而这些数据可以通过父组件传递给子组件。 prop属性中可以定义属性的类型,也可以定义属性的初始值。

Web组件简介

Web组件由三个独立的技术组成:自定义元素。很简单,这些是完全有效的HTML元素,包含使用一组JavaScript API制作的自定义模板,行为和标记名称(例如,<one-dialog>)。

web组件调用其他web资源

web组件可以直接或间接的调用其他web资源。一个web组件通过内嵌返回客户端内容的另一个web资源的url来间接调用其他web资源。在执行时,一个web资源通过包含另一个资源的内容或者转发请求到另一个资源直接调用。

vue中如何实现的自定义按钮

在实际开发项目中,有时我们会用到自定义按钮;因为一个项目中,众多的页面,为了统一风格,我们会重复用到很多相同或相似的按钮,这时候,自定义按钮组件就派上了大用场,我们把定义好的按钮组件导出,在全局引用,就可以在其他组件随意使用啦,这样可以大幅度的提高我们的工作效率。

Vue子组件调用父组件的方法

Vue中子组件调用父组件的方法,这里有三种方法提供参考,第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法,第二种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!