父子组件通信: props、 $parent / $children、 provide / inject 、 ref 、 $attrs / $listeners兄弟组件通信:EventBus 、 Vuex跨级组件通信: EventBus 、 Vuex 、 provide / inject 、 $attrs / $listeners父传子 子组件用 props 接收,父组件用 v-bind:prop 发送父组件<template> <div class="section"> <com-article :articles="articleList"></com-article> </div></template><script>import comArticle from "./comArticle";export default { data() { return { articleList: ["红楼梦", "西游记", "三国演义", "水浒传"] } }, components: { comArticle },}</script>子组件<template> <ul> <li v-for="(item, index) in articles" :key="index">{{item}}</li> </ul></template><script>export default { props: ["articles"]}</script>子传父 子组件用 v-on:click="" this.$emit('name', this.msg)(【有的版本名称只能小写】)发送,父组件自定义事件 v-on:name="getChildValue" 然后在 getChildValue(data){} 方法中接收父组件<template> <div class="section"> <com-article @onEmitIndex="onEmitIndex"></com-article> 【不能加括号】 <ul> <li v-for="(item, index) in articles" :key="index">{{item}}</li> </ul> </div></template><script>import comArticle from "./com2";export default { data() { return { articles:[] }; }, components: { comArticle }, methods: { onEmitIndex(data) { this.articles = data; } }}</script>子组件<template> <div> <button @click="emitIndex()">点击把articleList传给父组件</button> 【可以传参】 </div></template><script>export default { data() { return { articleList: ["红楼梦", "西游记", "三国演义", "水浒传"] }; }, methods: { emitIndex() { this.$emit("onEmitIndex", this.articleList); // } }}</script>父子传参还可以用 $parent(对象)和 $children(数组)provide / reject (上传下)父辈组件中通过 provide 来提供变量,子孙组件中通过 reject 来注入变量。父组件<template> <div> com1 是父组件 <com2></com2> </div></template><script> import com2 from './com2.vue' export default { provide: { msg: "这是父辈组件 com1 传出去的数据" }, components:{ com2 } }</script>子组件<template> <div> com2 是 com1 的子组件 {{demo}} <com3></com3> </div></template><script> import com3 from './com3.vue' export default { inject: ['msg'], data() { return { demo: this.msg } }, components: { com3 } }</script>孙组件<template> <div> com3 是 com1 的孙组件 {{msg}} </div></template><script> export default { inject: ['msg'] }</script>ref如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据 ref="xx" this.$refs.xxeventBus(事件总线,项目较大难以维护,组件都可以传) $emit(name, data)发送 $on(name, data=>{})接收 【名称小写】event-bus.jsimport Vue from 'vue'export const EventBus = new Vue()com1.vue 发送事件<button @click="additionHandle">加法器</button>import {EventBus} from './event-bus.js'data(){ return {num: 1}},additionHandle(){ EventBus.$emit('addition', {num: this.num++})com2.vue 接收事件<div>计算和: {{count}}</div>data() { return {count: 0}},mounted() { EventBus.$on('addition', param => { this.count = this.count + param.num; })}localStorage / sessionStorage因为 window.loacalStorage.setItem(key, value)、window.loacalStorage.getItem(key) 储存的是字符串,需要用 JSON.parse() / stringify() 转换可结合 vuex,实现数据持久保存和解决数据及状态混乱问题$attrs $listeners(仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用)test.vue<template> <div> test.vue <child-com1 :name="name" :age="age" :gender="gender" :height="height" title="test.vue 传出的值"></child-com1> </div></template><script>const childCom1 = () => import("./com1.vue");export default { components: { childCom1 }, data() { return { name: "zhangsan", age: "18", gender: "女", height: "158" }; }};</script><style scoped>div{ background-color: #ddd;}</style>com1.vue<template> <div class="com1"> com1 <p>name: {{name}}</p> <p>childCom1的$attrs: {{$attrs}}</p> <child-com2 v-bind="$attrs"></child-com2> </div></template><script>const childCom2 = () => import("./com2.vue");export default { components: { childCom2 }, inheritAttrs: false, // 关闭自动挂载到组件根元素上的没有在 props 声明的属性 props: { name: String }, created() { console.log(this.$attrs); // {age: "18", gender: "女", height: "158", title: "test.vue 传 com1.vue"} }};</script><style scoped>.com1{ margin: 20px; background-color: #f00;}</style>com2.vue<template> <div>com2 <p>age: {{age}}</p> <p>childCom2: {{ $attrs }}</p> </div></template><script>export default { inheritAttrs: false, props: { age: String }, created() { console.log('com2', this.$attrs); // { "name": "zhang", "gender": "女", "height": "158", "title": "程序员成长指北" } }};</script><style scoped>div{ background: #0f0; margin: 20px}</style>