Vue 多组件数据传递

针对不同的使用场景,如何选择行之有效的通信方式?这是我们所要探讨的主题。本文总结了 vue 组件间通信的几种方式,如 props$emit/$onvuex$parent / $children$attrs/$listenersprovide/inject,以通俗易懂的实例讲述这其中的差别及使用场景。

1、props/$emit

父组件向子组件传值. 父组件 A 通过 props 的方式向子组件 B 传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。

<template>
    <div id="app">
        <users :users="users" @getMsg="showMsg"></users>
    </div>
</template>
<script>
import Users from "./components/Users"
export default {
    name: 'App',
    data() {
        return {
            users: ["Henry", "Bucky", "Emily"]
        }
    },
    components: {
        "users": Users
    },
    methods: {
        showMsg(val) {
            console.log(val)
        }
    }
}

子组件

<template>
    <div class="hello">
        <ul>
            <li v-for="user in users" @click="sendMsg">{{user}}</li>
        </ul>
    </div>
</template>
<script>
export default {
    name: 'HelloWorld',
    props: {
        users: {
            type: Array,
            required: true
        }
    },
    methods: {
        sendMsg() {
            this.$emit('getMsg', 'get data from child') //自定义事件  传递值“子向父组件传值”
        }
    }
}
</script>

$emit/$on

这种方法通过一个空的 Vue 实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案 vuex。

var Event=new Vue();
    Event.$emit(eventName,data);
    Event.$on(eventName,data => {});

Vuex

1.dispatch 异步操作 this.store.dispatch('actions.example()', arg), 调用actions里的方法。
2.commit 同步操作 this.store.commit('mutations.example()', arg),调用mutations里的方法。

const user = {
  state: {
    token: ''
  },

  mutations: {
    SET_TOKEN: (state, token) => {
      state.token ="test " +token 
    },
  },
  actions: {
    // 登录
    Login({commit}, userInfo) {
      return new Promise((resolve, reject) => {
        login(userInfo.account, userInfo.password).then(aa => {
          if(aa.status==200){
            const tokenSuccess = aa.data.token.tokenValue
            commit('SET_TOKEN', tokenSuccess )
            token="test"+tokenSuccess ;
            //setToken("test" +token)
            resolve();
          }
          
        }).catch(error => {
          console.log("登录失败")
          reject(error)
        })
      })
    },
  }
}
toLogin() {
     this.$store.dispatch('Login',arg).then((res) => { 
        console.log(res)       
     })
}

$attrs/$listeners

$attrs:当前组件的属性,通俗的讲也就是在组件标签定义的一系列属性,如input的value,placeholder等,但是不包括在当前组件里面定义的props属性
$listeners:当前组件监听的事件,通俗的讲也就是在使用组件的时候在标签中定义的事件,如@input,以及一些自定义事件@tempFn等
$props:当前组件从父组件那里接收的参数,通俗的讲和$attr差不多,但是只包括在当前组件中定义了的props属性

<childComponent v-bind="$attrs" v-bind="$listeners"></childComponent>

provide/inject

主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
父组件

export default {
  provide: (){
    return {
      name: 'demo'
    }
  }
}

子组件

export default {
  inject: ['name'],
  mounted () {
    console.log(this.name); 
  }
}
posted @ 2021-05-24 14:55  boygdm  阅读(195)  评论(0编辑  收藏  举报