vue 组件通讯

组件之间的通讯简述:
父子组件的关系可以总结为 props 向下传递,事件event向上传递
祖先组件和后代组件(跨多代)的数据传递,可以使用provide和inject来实现
跨组件或者兄弟组件之间的通信,可以通过eventBus或者vuex等方式来实现

  1. 页面级组件传值
    • 通过路由带参数进行传值
    • 通过设置 sessionStorage缓存的形式进行传递
  2. 父子组件传值
    • 父传子props,子传父$emit
      • .sync
      • v-model
    • $parent$children
  3. 后代组件传值
    • provide / inject
    • $attrs$listeners
  4. 跨组件或者兄弟组件之间传值
    • 小项目少页面用eventBus
    • 大项目多页面使用 vuex

页面级组件传值

1. 通过路由带参数进行传值

//两个组件 A和B,A组件通过query把orderId传递给B组件(触发事件可以是点击事件、钩子函数等)
this.$router.push({ path: '/f4', query: { orderId: 123 } }) //跳转到f4
//在B组件中获取A组件传递过来的参数
this.$route.query.orderId
router-link 进入Father4

2. 通过设置 Session Storage缓存的形式进行传递

//两个组件A和B,在A组件中设置缓存orderData
const orderData = { 'orderId': 123, 'price': 88 }
sessionStorage.setItem('orderInfo', JSON.stringify(orderData))

//B组件就可以获取在A中设置的缓存了
const orderInfo = JSON.parse(sessionStorage.getItem('orderInfo'))

父子组件传值

1. 父传子props,子传父$emit

  • .sync
//父组件



//子组件



  • v-model
//父组件



//子组件



2. $parent$children

在组件内部可以直接通过子组件$parent对父组件进行操作,父组件通过$children对子组件进行操作.

//父组件



//子组件1



//子组件2



后代组件传值(父组件与子、孙子、曾孙子组件传值)

1. provide / inject

provide / inject 可以以一个祖先组件向所有子孙后代注入依赖。
简单的来说就是在父组件中通过provide来提供变量,然后在后代组件中通过inject来注入变量,不仅限于prop的父子组件数据交互,只要在上一层级的声明的provide,那么下一层级无论多深都能够通过inject来访问到provide的数据

//父组件



//子组件



//孙子组件



vue 组件通讯_第1张图片
通过 provide / inject 后代组件都可以访问父组件的数据

2. $attrs$listeners

通过$attrs属性将父组件的数据(不作为 prop 被识别的数据)传递给子组件、孙子组件、曾孙子组件等后代组件

$listeners属性是一个对象,里面包含了作用在这个组件上的所有监听器,我们在子组件上绑定v-on=”$listeners”, 就可以在父组件中监听孙子组件、曾孙子组件触发的事件,就能把孙子组件、曾孙子组件等后代组件发出的数据,传递给父组件。

//父组件


//子组件


//孙子组件


跨组件或者兄弟组件之间传值

小项目少页面用eventBus

总结:
EventBus 又称为事件总线,在Vue中可以使用 EventBus 来作为沟通桥梁,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所有组件都可以上下平行地通知其他组件
在需要传值的组件中用eventBus.$emit触发一个自定义事件,并传递参数
在需要接收数据的组件中用eventBus.$on监听自定义事件,并在回调函数中处理传递过来的参数
EventBus原理是发布订阅
eventBus容易导致命名冲突,所以大项目要用vuex




//eventBus.js
import Vue from 'vue';
export const eventBus = new Vue();

大项目多页面使用 vuex

vuex主要借鉴了flux redux,vuex只能在vue中使用(单独为vue开发的)
vuex为大型项目而生,主要是(状态)管理,状态指的是数据,将数据统一管理
每一个vuex应用的核心是store,store是一个容器
不能直接改变store中的状态,通过commit一个mutation来更改状态

vue 组件通讯_第2张图片
vuex计数器项目架构图
//main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store'

//计数器
new Vue({
    el:'#app',
    ...App,
    store, //store被注册到了实例上 所有组件都会有this.$store这个属性
})
//store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import logger from 'vuex/dist/logger'; //logger是一个日志插件
Vue.use(Vuex);
//容器是唯一的 不可以更改 所以用const比较好 
const state={count:0}; 
const getters={ //相当于computed
    val:(state)=>state.count%2 ? '奇数' : '偶数'
};
import mutations from './mutations';
export default new Vuex.Store({
    state,
    mutations,
    getters, 
    plugins:[logger()],
    strict:true //严格模式 只能通过mutation(管理员)来更改状态,mutation不支持异步
})
//App.vue



//Counter.vue
 
 
 
// store/mutations.js
import * as Types from './mutations-types';
const mutations={
    [Types.INCREMENT](state,count){ //state是自动放入的,默认指的就是当前的state
        state.count+=count;
    },
    [Types.DECREMENT](state,count){
        state.count-=count;
    }
};
export default mutations;
// store/mutations-types.js
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';

你可能感兴趣的:(vue 组件通讯)