vue组件通讯|vue父子组件通讯demo

vue组件通讯

最近一直在写报表的页面,也碰到了非常多组件通讯的问题,最近准备重构和总结一下。因为之前是第一次上手vue-cli + echarts + mint-ui,所以前一次写的代码自己非常的不满意。第一次的报表完成图,大致如下gif所示。下面就是总结一下一些组件通讯的方式吧。温故知新。

报表页面

父子组件通讯

数据从父组件到子组件

数据从父组件到子组件是最容易理解的,因为vue是单向数据流,所以数据就像水流一样,从高处到低处,这里为理解为,从父组件流向子组件。

vue

目录如下所示

vue

Main.vue

<template>
  <div class="main">
    //需要传递到子组件的数据,并且绑定到type上
    <header-nav :type="type"></header-nav>
  </div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
export default {
  name: 'hello',
  components: {
    HeaderNav
  },
  data() {
    return {
      type: {
        summary: '汇总',
        trend: '走势',
      },
      selected: 1
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav

<template>
  <div class="header">
    <mt-navbar v-model="selected">
      <mt-tab-item id="summary">{{type.summary}}</mt-tab-item>
      <mt-tab-item id="trend">{{type.trend}}</mt-tab-item>
    </mt-navbar>

    <!-- tab-container -->
    <mt-tab-container v-model="selected">
      <mt-tab-container-item id="1">
        summary
      </mt-tab-container-item>
      <mt-tab-container-item id="2">
        trend
      </mt-tab-container-item>
    </mt-tab-container>
  </div>
</template>

<script>
export default {
  name: 'headerNav',
  //父组件传递来的数据
  props: ['type'],
  data() {
    return {
        selected:"summary"
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
  .test
    font-size 50px
</style>

数据从子组件到父组

子组件将数据传递到父组件,主要到方法是$emit()和$on方法

vue自定义事件

  • 使用 $on(eventName) 监听事件
  • 使用 $emit(eventName) 触发事件

Main.vue

<template>
  <div class="main">
    <!--通过on-v绑定transferUser自定义事件监听 transferUser为子组件中的自定义事件-->
    <header-nav :type="type" @transferUser="getUser"></header-nav>
    <span>this is name</span>
    <span>{{user}}</span>
    <br>
    <router-link to='/selectTime'>
      selectTime
    </router-link>
  </div>
</template>

<script>
import HeaderNav from './HeaderNav.vue';
import selectTime from './selectTime.vue';
export default {
  name: 'hello',
  components: {
    HeaderNav,
    selectTime
  },
  data() {
    return {
      type: {
        summary: '汇总',
        trend: '走势',
      },
      selected: 1,
      user: '',
    }
  },
  methods: {
    getUser(msg){
      this.user = msg
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->

<style lang="stylus" rel="stylesheet/stylus">

</style>

HeaderNav.vue

<template>
  <div class="header">
    <!--出发change事件调用setUser,绑定自定义事件transferUser,并传入参数-->
    <input type="text" v-model="username" @change="setUser">
  </div>
</template>

<script>
export default {
  name: 'headerNav',
  props: ['type'],
  data() {
    return {
        selected:"summary",
        username:''
    }
  },
  methods: {
    // 触发自定义事件
    setUser:function(){
      this.$emit('transferUser', this.username)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="stylus" rel="stylesheet/stylus">
  .test
    font-size 50px
</style>

分享到:

发表评论

昵称

沙发空缺中,还不快抢~