Vue中组件的通信方式-以及nextTick分析(一)

简介: vue也是组件化开发框架,对于这种组件化开发来说,组件之间的通信方式通常都是非常重要的所以单独开一个篇章来总结下有哪些通信方式

1. 前言


vue也是组件化开发框架,对于这种组件化开发来说,组件之间的通信方式通常都是非常重要的

所以单独开一个篇章来总结下有哪些通信方式


2. 首先列出常用的组件通信方式


1.props

2.$emit/$on

3.$children/$parent

4.$attrs / $listeners

5.ref

6.$root

7.eventBus

8.vuex

列出来后,可以自己先考虑下应用场景

下面不饶弯子了,以组件的关系来解说通信方式


3. 父子组件通信


3.1  props                父传子

1.父组件以属性的方式传值给子组件

2.子组件通过props方式接收数据

3.1.1父组件核心代码

在父组件中引入子组件并绑定parentData自定义属性


<Child:parentData="parentData"></Child >
<script>
import Child  from '@/components/child'
  export default{
    name:'Parent',
    components:{Child},
    data(){
      return{
        parentData:'我是父组件向子组件传递的值-props方式'
      }
    }
  }
</script>


3.1.2 子组件核心代码

1.在子组件中使用 props 接收父组件传递的数据,

2.props 里的名字跟父组件定义的属性名一致


<template>
  <div>我是父组件的数据:{{parentData}}</div>
  <div>我是父组件传递修改后的数据:{{mydata}}</div>
</template>
<script>
  export default{
    name:'Child',
    props:{
      parentData:{
        type:String,
        default:''
      }
    }
    data(){
      mydata:'俺的小破站 '+ this.parentData
    },
    watch:{
      parentData(newVal){
        this.mydata='俺的小破站 '+ newVal
      }
    },
  }
</script>

Vue的单向数据流机制,子组件不能够直接去修改父组件传递的修改的,否则能改的话那父组件的值就被污染了。

但是子组件内想要修改父组件传过来的值却不“污染”父组件的话,

可以在子组件内定义一个变量mydata去接收parentData数据,并使用 watch 监听parentData数据的变更

3.2  $emit/$on      子传父

1.子组件绑定自定义事件

2.使用 $emit() 触发更改数据

3.2.1 子组件核心代码


<el-button @click="handleEmit">告诉父组件我要更改数据啦</el-button>
<script>
 export default{
   name:'Child',
   methods:{
     handleEmit(){
       this.$emit('triggerEmit','我是来自子组件的数据')
     }
   }
 }
</script>


3.2.2父组件核心代码

1.父组件定义并绑定子组件传递的triggerEmit事件

2.triggerEmit事件名需跟子组件 $emit() 的事件名


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


3.3 $parent/$children

1.子组件通过 $parent 获得父组件实例

2.父组件通过 $children 获得子组件实例数组

3.3.1 子组件


<template>
  <div>我是子组件</div>
</template>
<script>
export default{
  name:"Child",
  data(){
    return{
      childTitle: '我是子组件的数据'
    }
  },
  methods:{
    childHandle(){
      console.log('我是子组件的方法')
    }
  },
  created(){
    console.log(this.$parent)
    console.log(this.$parent.parentTitle) // => 我是父组件的数据
    this.$parent.parentHandle() // => 我是父组件的方法
  }
}
</script>

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

3.3.2 父组件


<template>
  <div>
    <Child>我是父组件</Child>
  </div>
</template>
<script>
import Child from './child.vue'
export default{
  name: 'parent',
  components:{
    Child
  },
  data(){
    return{
      parentTitle: '我是父组件的数据'
    }
  },
  methods:{
    parentHandle(){
      console.log('我是父组件的方法')
    }
  },
  mounted(){
    console.log(this.$children)
    console.log(this.$children[0].childTitle) // => 我是子组件的数据
    this.$children[0].childHandle() // => 我是子组件的方法
  }
}
</script>


3.3.3 注意钩子的使用

父组件是在 mounted()生命周期中获取子组件实例的,并且获取的实例是一个数组形式

3.3.4 问题     层级发生变化的时候咋办呢 ???

1.源码其实有更高层次的封装,在引用parent到时候抽象一个更高级的方法类似 dispatch,

2.直接指定比较重要的父组件的类型或者名称,在循环查找的时候避免程序的脆弱性

3.4 ref

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


<template>
  <div>
    <Child ref="child"></Child >
  </div>
</template>
<script>
import Child from './child.vue'
export default{
  name: 'parent',
  components:{
    Child 
  },
  mounted(){
    console.log(this.$refs.child ) /*组件实例*/
  }
}
</script>


1.注意 钩子 mounted

  1. 父组件就可以直接使用this.$refs.xx获取子组件的实例

3.5 $attrs/$listeners


4. 兄弟组件


核心就是找共同点, 搭建桥梁,中间人,话事人的感觉

4.1 $parent

既然是兄弟往上找 总能找到共同的祖先

不常用,可以参考文章上面 的 写法

4.2 $root

其实 根也是共享的

4.3 eventBus 也是都可以访问的

4.3.1 创建一个Vue实例

作为调度中心 eventBus


import Vue from "vue"
export default new Vue()


4.3.2 需要进行通信的组件中 引入


<template>
  <div>
    <div>我是通信组件A</div>
    <el-button @click="changeName">修改</el-button>
  </div>
</template
<script>
import { EventBus } from "../bus.js"
export default{
  data(){
    return{}
  },
  methods:{
    changeName(){
      EventBus.$emit("editName", '俺的小破站')
    }
  }
}
</script>


4.3.3 监听事件


<template>
  <div>我是通信组件B</div>
</template
<script>
import { EventBus } from "../bus.js"
export default{
  data(){
    return{}
  },
  mounted:{
    EventBus.$on('editName',(name)=>{
      console.log(name) // 俺的小破站!
    })
  }
}
</script>


4.4 vuex

具体可以看我之前写的vuex-0系列


5. 跨级组件


5.1eventBus

5.2 vuex

1.相当于一个公共数据的仓库

2.提供一些方法管理仓库数据

3.具体可以看我之前写的vuex-0系列

5.3.provide/inject

5.3.1 简介

父组件使用 provide 注入数据

子组件使用 inject 使用数据

5.3.2 父组件


export default{
 provide: {
   return{
     provideName: '俺的小破站'
   }
 }
}


5.3.3 分析

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

5.3.4 子组件


export default{
  inject: ['provideName'],
  created () {
    console.log(this.provideName) // 俺的小破站
  }
}


5.3.5 优缺点

1.父组件不需要知道哪个组件使用它提供出去的数据

2.子组件不需要知道这个数据从哪里来

3.更加的原生,不会对第三方库产生依赖

缺点:单向的;只能祖辈向子辈传值



相关文章
|
2天前
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的法律咨询系统的分析与设计附带文章和源代码设计说明文档ppt
基于ssm+vue.js+uniapp小程序的法律咨询系统的分析与设计附带文章和源代码设计说明文档ppt
6 1
|
2天前
|
JavaScript
vue知识点
vue知识点
9 2
|
3天前
|
JavaScript 程序员 网络架构
vue路由从入门到进阶 --- 声明式导航详细教程
vue路由从入门到进阶 --- 声明式导航详细教程
vue路由从入门到进阶 --- 声明式导航详细教程
|
3天前
|
资源调度 JavaScript UED
vue路由的基础知识总结,vueRouter插件的安装与使用
vue路由的基础知识总结,vueRouter插件的安装与使用
|
JavaScript 前端开发 缓存
|
3天前
|
JavaScript 前端开发 安全
Vue响应式设计
【5月更文挑战第30天】Vue响应式设计
23 1
|
3天前
|
JavaScript
|
3天前
|
编解码 JavaScript API
Vue在移动端的表现如何?
【5月更文挑战第30天】Vue在移动端的表现如何?
10 2
|
3天前
|
JavaScript 前端开发 API
Vue与其他框架的对比优势
【5月更文挑战第30天】Vue与其他框架的对比优势
11 1
|
4天前
|
JavaScript
Vue常用知识点总结
Vue常用知识点总结
12 0