vue 组件通信

1、父组件给孙组件传递消息

// 父组件
<template>
	<aaa
      name="蔡蔡"
      age="18"
      @test1="onTest1"
    />
</template>
<script>
import aaa from '@/views/supplementary/baseSetting/sizeRatio/aaa'
export default {
     
  name: 'parent',
  components: {
     
    aaa
  },
  methods: {
     
    onTest1(val) {
     
      console.log(val)
       // child2-$emit:我是孙子发的消息
	  // child2-$listeners:我是孙子发的消息
	  // child1-$emit:我是儿子发的消息
	 // child1-$listeners:我是儿子发的消息
    },
  }
}
</script>
// 儿子组件
<template>
  <div>
    <p>儿子组件得到:$attrs:{
     {
      $attrs }}</p>
    <bbb v-bind="$attrs" v-on="$listeners" />
  </div>
</template>

<script>
import bbb from '@/views/supplementary/baseSetting/sizeRatio/bbb'

export default {
     
  name: 'Aaa',
  components: {
     
    bbb
  },
  inheritAttrs: false, // 父组件传递动态数据后,子组件的默认行为
  data() {
     
    return {
     
      name: 'jamie'
    }
  },
  mounted() {
     
    this.$emit('test1', 'child1-$emit:我是儿子发的消息') // 触发父组件方法的一种方式
    this.$listeners.test1('child1-$listeners:我是儿子发的消息') // 触发父组件方法的另一种方式
  }
}
</script>
// 孙子组件
<template>
  <div>
    <!--<p>孙子组件得到:age:{
     {
      age }}</p>-->
    <!--<p>孙子组件得到:name:{
     {
      name }}</p>-->
    <p>孙子组件得到:$attrs:{
     {
      $attrs }}</p>
  </div>
</template>
<script>
export default {
     
  name: 'Bbb',
  inheritAttrs: false, // 默认行为需要取消
   // props 和 $attrs 只能用一个,用了props,$attrs就拿不到了。
  // props: {
     
  //   age: {
     
  //     type: String,
  //     default: ''
  //   },
  //   name: {
     
  //     type: String,
  //     default: ''
  //   }
  // },
  mounted() {
     
    this.$emit('test1', 'child2-$emit:我是孙子发的消息') // 触发父组件方法的一种方式
    this.$listeners.test1('child2-$listeners:我是孙子发的消息')// 触发父组件方法的另一种方式
  }
}
</script>


2、组件通信 — 父组件给子组件传递数据 Download

// 子组件 - List.vue
<script>
export default {
     
  name: 'List',
  props: ['comments'] // 声明组件名
}
</script>

// 父组件 - App.vue
 <Add :comments="comments" ></Add>

3、组件通信 — 子组件给父组件传递数据

// 子组件 - List.vue
this.$emit('func',this.msg)

// 父组件 - App.vue
 <mall-select  @func="getMsgFormSon"></mall-select>
 
 getMsgFormSon (data) {
     
  console.log(data)
 },

4、组件通信 — 父组件调用子组件方法

// 子组件 - List.vue
 methods: {
     
	resetFilter () {
     
		this.mallCode = null
	},
 }


// 父组件 - App.vue

import mallSelect from '../common/mallSelect.vue'
export default {
     
	components: {
     
		mallSelect
	},
	methods: {
     
		resetFilter () {
     
			this.$refs.mallSelect.resetFilter() // 调用子组件方法
		}
	}
}

// HTML
<button @click="resetFilter()">重置</button>
<mall-select ref='mallSelect'></mall-select>

5、子组件调用父组件的方法

1、第一种方法是直接在子组件中通过this.$parent.event来调用父组件的方法

// 父组件
<template>
  <div>
    <child></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
     
    components: {
     
      child
    },
    methods: {
     
      fatherMethod() {
     
        console.log('测试');
      }
    }
  };
</script>

// 子组件
<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
     
    methods: {
     
      childMethod() {
     
        this.$parent.fatherMethod();
      }
    }
  };
</script>

2、第二种方法是在子组件里用$emit向父组件触发一个事件,父组件监听这个事件就行了。

// 父组件
<template>
  <div>
    <child @fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
     
    components: {
     
      child
    },
    methods: {
     
      fatherMethod() {
     
        console.log('测试');
      }
    }
  };
</script>

// 子组件
<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
     
    methods: {
     
      childMethod() {
     
        this.$emit('fatherMethod');
      }
    }
  };
</script>

3、第三种是父组件把方法传入子组件中,在子组件里直接调用这个方法

// 父组件
<template>
  <div>
    <child :fatherMethod="fatherMethod"></child>
  </div>
</template>
<script>
  import child from '~/components/dam/child';
  export default {
     
    components: {
     
      child
    },
    methods: {
     
      fatherMethod() {
     
        console.log('测试');
      }
    }
  };
</script>

// 子组件
<template>
  <div>
    <button @click="childMethod()">点击</button>
  </div>
</template>
<script>
  export default {
     
    props: {
     
      fatherMethod: {
     
        type: Function,
        default: null
      }
    },
    methods: {
     
      childMethod() {
     
        if (this.fatherMethod) {
     
          this.fatherMethod();
        }
      }
    }
  };
</script>

6、vue 父组件监听子组件触发事件($on 和 $emit)

父组件:
// html
<todoList ref='todoList'>
//js - 监听子组件触发事件
this.$refs.todoList.$on('deleteTodo', 回调函数) // 这种方法跟在标签上写自定义事件一样的效果(@deleteTodo='回调函数')

子组件:
this.$emit('deleteTodo')

7、vue 父组件监听子组件事件(dispatch),子组件可以调用父组件 this

// 子组件

import emitterfrom 'element-ui/src/mixins/emitter'
name: 'MultipleSelect',
componentName: 'MultipleSelect',
mixins: [emitter],
inject: ['commonForm'],

this.dispatch(this.commonForm.$options.componentName, 'baseProductColumnPagination') // 告诉父组件事件发生了

mounted() {
     
console.log(this.commonForm) // 可以看到父组件得this对象
},

// 父组件:

import emitter from 'element-ui/src/mixins/emitter'
name: 'SingleSizeRatioAdd',
componentName: 'SingleSizeRatioAdd',
mixins: [emitter],
provide() {
     
return {
     
commonForm: this
}
},


mounted() {
     
this.$on('baseProductColumnPagination', this.baseProductColumnPagination) // 父组件收到了子组件得事件发生了得通知
},

8、pubsub.js 消息的发布订阅 (消息的发布订阅,当嵌套层数比较多,可以用此工具库)

下载:npm install pubsub-js --save

import PubSub from "pubsub-js"
// 在有数据的地方进行发布
PubSub.publish("频道","频道发布的消息")

// 组件将要被渲染的时候进行订阅
PubSub.subscribe("频道", (msg,data)=> {
     
	console.log(msg,data)
})

9、slot 插槽

问:什么时候用到插槽?

答:使用场景1:手机端头部导航栏,有的页面头部只有返回按钮,有的只有标题… (父组件可以传标签到子组件去展示,子组件起到了占位的作用。)
vue 组件通信_第1张图片

vue 组件通信_第2张图片

你可能感兴趣的:(vue)