Vue2组件通信的基础方式

自己的理解:组件化通信,无非就是数据你传我,我传你,两个组件的相互交流,方法很多,下方有图示(此篇建议小白阅读,大神的话也不会看,哈哈哈哈!仅供参考,有不同的意见可以一起交流!)

  1. 父传子(父组件传给子组件数据)
  2. 子传父(子组件传给父组件数据)
  3. 任意组件间通讯

父组件给子组件传数据

​ 我的理解是:如果建议使用props的方式,那我们就来了解一下props

props传数据:
解释:一个组件需要显式声明它所接受的 props,这样 Vue 才能知道外部传入的哪些是 props
(你要是想用父组件的传下来的数据,你肯定得先传呀,父组件传完之后,就是子组件接收了,这之后就要用到props来接收了,接收的类型很多,字符串呀,对象呀,数组呀,布尔值呀,其中props中的属性,最终都会出现在VueComponent的实例对象上,也就是说,会暴露在当前this上)
1.props声明:
1.1 为什么要声明?你不声明怎么知道外部传来的是哪个props
1.2 声明定义的类型有很多
1.2.1 最简单的字符串数组的声明方式(只接收): props:['foo']
1.2.2 稍微微微的有点小变化(限制类型):props:{name:'String'}
1.2.3 稍微有点多的对象方式来声明(可以指定传递的类型进行校验,限制必要性):
props:{
name:{
type:String, //类型
required:true, //必要性
default:'xxx' //默认值
}
备注:props是只读的,Vue底层会监测你对props的修改,如果进行了修改,就会发出警告,若业务需求确实需要修改,那么请复制props的内容到data中一份,然后去修改data中的数据。
2. 细节
2.1很多小伙伴困扰,该怎么起名字,要有什么规范吗?
我平常起名字的话也是有点小随意,但是正在改进,主要还是英语限制了,跑题了!!!
如果一个 prop 的名字很长,强烈建议使用 camelCase 形式或者 kebab-case ,建议Vue官方的推荐,这种方式不管从美观度还是可读性都是极好的,也是JavaScript合法的标识符,不比我们自己起的好?如果英语基础不是很好,可以去有道之类的一些查词软件上查,不断提升自己的命名能力!
那我们在多说一点吧,可以大说是小伙伴都知道,对于组件名我们推荐使用 PascalCase 写法,使用组件单闭合的形式,这样能更好的区分原生的标签
2.2 props 动态和静态的理解
分为动态和静态,但是在我们实际开发中,用的动态还是比较多的,很少传静态,
动态: 我们可以通过 v-bind 来动态绑定 props
<!-- 根据一个变量的值动态传入 -->
<BlogPost :title="post.title" />
<!-- 根据一个更复杂表达式的值动态传入 -->
<BlogPost :title="可以传递一个方法,表达式等" />
2.3 实际上任何类型的值都可以作为 props 的值被传递。String,Number,Boolean,Array,Object
2.4 有时候我们传递的不只是一个属性,把对象传递过去,使用一个对象传递多个props,
如果你想要将一个对象的所有属性都当作 props 传入,你可以使用没有参数的 v-bind,即只使用 v-bind 而非 :prop-name
<BlogPost v-bind="post" />
等价于:<BlogPost :id="post.id" :title="post.title" />

嵌入代码更易于理解

子组件给父组件传数据

1.最笨重的方法,但是有效

​ 就是利用props传递,有人会说,props不是父给子传吗?其实有一种方法是可以实现子给父传递数据的

我们需要利用props给子组件传递有参方法,子组件接收并调用传递参数,数据以参数的形式传递给父组件,此时父组件拿到的参数就是子组件中的数据来实现,以此子传父.

嵌入代码

2.相对于方法1稍微好点

​ 2.1 一种组件间通信的方式,适用于:子组件 ===> 父组件

​ 2.2 使用场景:A是父组件,B是子组件,B想给A传数据,那么就要在A中给B绑定自定义事件(事件的回调在A中)。

​ 2.3 绑定自定义事件:第一种方式,在父组件中:<Demo @taoTao="test"/><Demo v-on:taoTao="test"/>

​ 第二种方式,在父组件中:

<Demo ref="demo"/>
......
mounted(){
this.$refs.xxx.$on('taoTao',this.test)
}
  1. 若想让自定义事件只能触发一次,可以使用once修饰符,或$once方法。

  2. 触发自定义事件:this.$emit('taoTao',数据)

  3. 解绑自定义事件this.$off('taoTao')

  4. 组件上也可以绑定原生DOM事件,需要使用native修饰符。

  5. 注意:通过this.$refs.xxx.$on('taoTao',回调)绑定自定义事件时,回调要么配置在methods中,要么用箭头函数,否则this指向会出问题!

任意组件间通信(全局事件总线(GlobalEventBus))

任意组件间通信的方法:全局事件总线

​ 前面两种父传子,子传父,也只能解决比较简单的问题,如果跨级传递,或者是兄弟之间传递,操作起来就很繁琐,所以我们就定义出来了一种 全局事件总线的方法来解决任意组件间通讯,说白了就是:

​ 1.全局事件总线的介绍:A组件和B组件是兄弟组件,现在我想把A组件的数据传递给B组件进行使用,我们就需要把一个东西作为傀儡(中间人),然后A组件把数据传给傀儡,B组件从傀儡中获得A组件传递的值,这样就可以实现任意组件间的通讯,你可能会有疑问,那么多组件都给傀儡的话,如何区分是哪个组件传递的,这是就需要传递过来的数据携带一个标识,方便使用,使用完要销毁,不然压力会很大,这就是全局事件总线的工作流程。那我们应该如何书写呢?

​ 2.安装全局事件总线

那我就要给你们细讲了:全局事件总线有两个特点:首先我们得叫所有的组件都能访问到这个事件,其次是能有$emit,$on,$off等这些属性,我们就会想到Vue或者是VueComponent,其中我们会用

一个重要的内置关系:VueComponent.prototype.__proto__ === Vue.prototype

我们可以这样定义全局事件总线:

new Vue({
......
beforeCreate() {
Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
},
......
})

3.使用全局事件总线

​ 3.1 接收数据:A组件想接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身。

methods(){
demo(data){......}
}
......
mounted() {
this.$bus.$on('xxxx',this.demo)
}

​ 3.2 提供数据:this.$bus.$emit('xxxx',数据)

  1. 最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

消息订阅与发布(pubsub)

  1. 一种组件间通信的方式,适用于任意组件间通信。

  2. 使用步骤:

    1. 安装pubsub:npm i pubsub-js

    2. 引入: import pubsub from 'pubsub-js'

    3. 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。

      methods(){
      demo(data){......}
      }
      ......
      mounted() {
      this.pid = pubsub.subscribe('xxx',this.demo) //订阅消息
      }
    4. 提供数据:pubsub.publish('xxx',数据)

    5. 最好在beforeDestroy钩子中,用PubSub.unsubscribe(pid)去取消订阅。

插槽

  1. 作用:让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件

  2. 分类:默认插槽、具名插槽、作用域插槽

  3. 使用方式:

    1. 默认插槽:

      父组件中:
      <Category>
      <div>html结构1</div>
      </Category>
      子组件中:
      <template>
      <div>
      <!-- 定义插槽 -->
      <slot>插槽默认内容...</slot>
      </div>
      </template>
    2. 具名插槽:

      父组件中:
      <Category>
      <template slot="center">
      <div>html结构1</div>
      </template> <template v-slot:footer>
      <div>html结构2</div>
      </template>
      </Category>
      子组件中:
      <template>
      <div>
      <!-- 定义插槽 -->
      <slot name="center">插槽默认内容...</slot>
      <slot name="footer">插槽默认内容...</slot>
      </div>
      </template>
    3. 作用域插槽:

      1. 理解:数据在组件的自身,但根据数据生成的结构需要组件的使用者来决定。(games数据在Category组件中,但使用数据所遍历出来的结构由App组件决定)

      2. 具体编码:

        父组件中:
        <Category>
        <template scope="scopeData">
        <!-- 生成的是ul列表 - ->
        <ul>
        <li v-for="g in scopeData.games" :key="g">{{g}}</li>
        </ul>
        </template>
        </Category> <Category>
        <template slot-scope="scopeData">
        <!-- 生成的是h4标题 -->
        <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4>
        </template>
        </Category>
        子组件中:
        <template>
        <div>
        <slot :games="games"></slot>
        </div>
        </template> <script>
        export default {
        name:'Category',
        props:['title'],
        //数据在子组件自身
        data() {
        return {
        games:['红色警戒','穿越火线','劲舞团','超级玛丽']
        }
        },
        }
        </script>

最后一种就是Vuex

之后再更新..........

最新文章

  1. logstash实战
  2. STSdb,最强纯C#开源NoSQL和虚拟文件系统 4.0 RC2 支持C/S架构
  3. Java Socket Server的演进 (一)
  4. Xcode7免证书真机调试实践
  5. Java:Comparator接口
  6. JSON操作技巧
  7. NAND闪存颗粒结构及工作原理
  8. 分布式文件系统之MogileFS工作原理及实现过程
  9. mysql7笔记----存储过程实例
  10. java.nio.file.NoSuchFileException
  11. Faiss安装
  12. 20135327郭皓--Linux内核分析第七周 可执行程序的装载
  13. BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划
  14. P1337 [JSOI2004]平衡点 / 吊打XXX 模拟退火
  15. H5做的商城客户端,效果很不错
  16. jvm 基础
  17. 【转】C#模拟http 发送post或get请求
  18. web.xml关于spring的讲解
  19. SpringBoot静态资源目录
  20. 实现工资的按天统计(X:日期 Y:姓名)

热门文章

  1. bat查找文件
  2. [开源福利] FreeRedis 历时两年正式发布 v1.0 [C#.NET Redis Client]
  3. Python数据科学手册-机器学习:线性回归
  4. Grafana Loki 学习之踩坑记
  5. ProxySQL(8):SQL语句的重写规则
  6. 使用logstash同步Mysql数据表到ES的一点感悟
  7. vue2.x引入threejs
  8. IC入门课第五课作业:完善 Microblog 前端(1、显示发布者的名字;2、增加新UI、3、关注其他学员的 canister)
  9. PAT甲级英语单词整理
  10. liunx之expect简介