组件之间的通信

前言

本文从大概会包括以下几个内容

  • 常用的组件通讯方式
  • 多组件之间共享(数据)的解决方案——Vuex

组件通讯方式

  1. 父组件给子组件传值:通过props传值
<!--父组件 parentComponent.vue-->
<div>
  <child-component title="hello"></child-component>
</div>
<script>
import { childComponent } from './childComponent'
export default {
	components:{
	  childComponent
	}
}
</script>
<!--子组件 childComponent.vue-->
<div>{{  title }}</div>
<script>
export default {
  props: ['title']
}
</script>
  1. 子传父亲: $event/$on
<!--子组件中发布一个事件-->
<button v-on:click="$emit('enlargeText', 0.1)"> Enlarge text </button>
<!--父组件监听这个自定义事件-->
<blog-post v-on:enlargeText="hFontSize += $event"></blog-post>
  1. 非父子组件:Event Bus
// eventbus.js
export default new Vue()
// 用$emit发布事件
bus.$emit('自定义事件名称', 数据);
// 用$on订阅事件
bus.$on('自定义事件名称', data => {
// 执行操作 
})
  1. 父直接访问子组件:通过 ref 获取子组件
    ref 有两个作用:
  • 如果你把它作用到普通 HTML 标签上,则获取到的是 DOM
  • 如果你把它作用到组件标签上,则获取到的是组件实例

$refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这仅作为一个用于直接操作子组 件的“逃生舱”——你应该避免在模板或计算属性中访问 $refs 。

多组件之间共享(数据)的解决方案——Vuex

当我们遇到以下问题的时候,上面的通讯方式就不太适用了

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。
    建议符合这种场景的业务使用 Vuex 来进行数据管理,例如非常典型的场景:购物车。

Vuex回顾

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件 的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调 试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调 试功能。

  • Vuex是专门为Vue.js设计的状态管理库
  • 它采用集中式的方式存储需要共享的数据
  • 从使用的角度,他就是JavaScript库
  • 他的作用是进行状态管理,解决复杂组件通讯,数据共享
Vuex核心概念

vuex核心概念图
上面演示了vuex整个工作流程。

  1. state是管理的全局状态,把状态绑定到了组件,渲染到用户界面,展示给用户
  2. 用户可以跟视图交互,可以通过dispatch下发到actions
  3. actions 可以进行异步操作,异步操作结束后,通过commit 提交到mutation,记录状态的更改
  4. mutation必须是同步的,所有状态的更改都要通过mutation,我们可以通过它记录所有状态的变化

Vuex中几个核心概念

  • Store: 仓库,是使用vuex的核心,每一个应用仅有一个Store,Store是一个容器,包含应用中的大部分状态,我们不能直接改变Store中的状态,要提交mutation的方式改变状态
  • State: 状态, 保存在Store中,因为Store是唯一的,所以State也是唯一的,称为单一状态树,但是所有状态都保存在State中的话会让程序难以维护,可以通过后续的模块解决该问题,这里面的状态是响应式的
  • Getter: 计算属性,方便从一个属性派生出其他的值,内部可以对计算的结果进行缓存,只有当依赖状态重新改变,才会重新计算
  • Mutation:状态的变化必须通过mutation完成
  • Action:action可以进行异步操作
  • Mudule: 模块,可以将Store分割成模块,每个模块拥有自己的state/mutaion/action/getter
vuex 使用示例
  • store仓库
export default {
  state: {
	user: {
		name: 'xiaomao', age: 18,
		sex: '男'
	} 
  },
  mutations: {
  	SET_USER_NAME(state,name):{
		state.user.name = name
    }
  },
  actions: {
     changeUserNameAction ({commit},name) { 
	    commit('SET_USER_NAME', name)
	  }
  }
}
  • State
 /**------------1. 接收数组参数 ---------------*/
 // 该方法是 vuex 提供的,所以使用前要先导入 import { mapState } from 'vuex'
 // mapState 返回名称为 count 和 msg 的计算属性 // 在模板中直接使用 count 和 msg
  computed: {
    ...mapState(['user']) 
  }
 /**------------2. 接收对象参数 ---------------*/
  computed: {
   ...mapState({
     user: state => state.user
   }) 
  }
  • Getter
import { mapGetter } from 'vuex'
computed: { 
    ...mapGetter(['reverseMsg']),
    // 改名,在模板中使用 reverse 
    ...mapGetter({
      reverse: 'reverseMsg'
    })
}
  • Mutation
import { mapMutations } from 'vuex'
methods: { 
  ...mapMutations(['increate']), // 传对象解决重名的问题
  ...mapMutations({
      increateMut: 'increate'
  })
}
  • Action
// Action 提交的是mutation,而不是直接变更状态
// Action 可以包含任何异步操作
import { mapActions } from 'vuex'
methods: { 
 ...mapActions(['increate']), // 传对象解决重名的问题 
 ...mapActions({
      increateAction: 'increate'
    })
}
  • Module
    由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
    为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、 mutation、action、getter、甚至是嵌套子模块。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值