Vue 组件通信

1 父=>子 父:msg='msg' 子props

单向数据流,子组件不允许改变props的值,如msg

2 子=>父 子事件里触发事件this.$emit(名 , 参) 父@名='fn' fn(参)

在组件上写event,都是自定义事件
即便: <Son @click='fn'/> 点击不会触发click
要想使用原生click: 
父 <Son @click.native='fn'/>
子 (不用写this.$emit) 
.native原理: 
将@click="$emit('click')"绑定在了子组件的根div上,点击子组件的哪里都会触发(事件委派)

3 非父子

1.全局定义,在main.js文件将bus挂载到vue.prototype上
	import Vue from 'vue';
	Vue.prototype.bus = new Vue();
2.新建一个bus.js文件,作为*总线,然后再组件引用时调用这个bus.js文件
	import Vue from 'vue';
	const EventBus = new Vue();
	export default EventBus;	

一个触发事件 bus.$emit('名' , 参)
一个监听事件 bus.$on( '名' , fn(参) )

4 $attrs 与 $listeners 得到父组件的属性与事件

父组件: <Son type="" titil="" :msg="msg" @click='fn' >
子组件props:['type'] 用this.$attrs {titil="" msg="msg"}
子组件

<p :title="this.$attrs.title" :msg="this.$attrs.msg"></p>
可简写为:<p v-bind="this.$attrs"></p>

$lieteners值为父组件的 自定义事件&&非.native

5 $parent / $children与 ref

ref:用在子组件上,访问组件实例
$parent / $children:访问父 / 子实例

ref
父:  <Son ref="comA" />   const a=this.$ref.comA.title
子:  data () {    return {      title: 'Vue.js'    }  }

$parent / $children
父:  <Son />   const a=this.$children.title
子:  data () {    return {      title: 'Vue.js'    }  }

6 provide/inject

祖先组件=>子孙组件
祖先组件provider来提供变量,子孙组件inject来注入变量。

//provide 是一个对象, inject 是:一个字符串数组
// A.vue
export default {
  provide: {
    name: '浪里行舟'
  }
}

// B.vue
export default {
  inject: ['name'],
  mounted () {
    console.log(this.name);  // 浪里行舟
  }
}

provide 和 inject 绑定并不是可响应的,A.vue 的 name 如果改变了,B.vue 的 this.name 是不会改变的

实现数据响应式:
provide 是一个函数(返回值为一个对象), inject 是:一个对象,对象的 key 是本地的绑定名

//方法一:提供祖先组件的实例
data () {    return {      color: 'red'    }  },
provide() {
    return {
      theme: this
    };
},
//方法二:使用2.6最新API Vue.observable 优化响应式 provide
provide() {
	this.theme = Vue.observable({  //向实例this上添加theme对象
     color: "blue"
   });
   return {
     theme: this.theme
   };
/************
	return {
     theme: Vue.observable({     color: "blue"   });
   };
************/
},
methods: {
  changeColor(color) {
       this.theme.color = color;
  } 
}

//子孙组件写法一样
<template functional>
  <div class="border2">
    <h3 :style="{ color: theme.color }">F 组件</h3>
  </div>
</template>
<script> export default {
  inject: {
    theme: {
      //函数式组件取值不一样
      default: () => ({})
    }
  }
};
</script>

7 作用域插槽

插槽: 父组件提供代码(html模板) => 子组件的slot => 再显示在父组件上

默认插槽

父: 
<div> 
	<Son></Son> 
</div>
子: 
<div> 
	<slot>没插</slot> 
</div>
//结果:  没插

父: 
<div> 
	<Son>插了</Son> 
</div>
子: 
<div> 
	<slot>没插</slot>    
</div>
//结果:  插了

具名插槽 ( 子组件有多个slot )

父: 
<Son>
    <template v-slot:header>
      <h1>Here might be a page title</h1>
    </template>
</Son>
子:
<div> 
	<slot name="header"></slot>
	...
	<slot name="footer"></slot>
</div>

作用域插槽

父组件提供代码(html模板)带有子组件的数据 => 子组件的slot => 再显示在父组件上

父:
<Son>
  <template v-slot:todo="slotProps" > {{slotProps.user.firstName}} </template> 
</Son> 
//slotProps 可以随意命名
//slotProps 接取的是子组件标签slot上属性数据的集合所有v-bind:user="user"
//:todo是插槽名(具名插槽), :default是默认插槽

子:
<slot name="todo" :user="user" :test="test"> </slot>
data() {
        return {
            user:{
                lastName:"Zhang",
                firstName:"yue"
            },
            test:[1,2,3,4]
        }
    },

混入 mixin

重复的js 写在一个单独的js里, 如myMixin
export default{
...
}

引入 import myMixin from './myMixin'
使用 mixins: [ ' myMixin ' ]

上一篇:.Net 5 在函数中使用Lambda


下一篇:工具类系列---【适用场景:有一数字000122,进行加法运算+1后,返回000123】