目录
前言
Vue的两大核心特性:
1、组件系统
2、数据驱动
因此组件(Component)是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。重点是可复用。
那么组件间传值有哪些呢?
常见就三类情况,父传子,子传父,非父子组件传值三种
1、父组件向子组件传值
1.1、props
即父组件通过属性的方式向子组件传值,子组件通过 props 来接收。
// 父组件
<son-component :toNumber="Number" />
export default {
components: {
SonComponent
}
......
}
在子组件中使用props(可以是数组也可以是对象)接收即可。可以传多个属性。
// 子组件
export default {
props: ['toNumber']
}
props有多种写法
//1、指定传入的类型,如果类型不对会警告
props: {
toNumber: Number}
//2、多个可能的类型
props: {
toNumber: [String, Number] }
//3、必填的数字
prosp: {
toNumber: {
type: Number, requires: true } }
//4、带有默认值
prosp: {
toNumber: {
type: Number, value: 1} }
//5、default指定默认值
props: {
toNumber: {
type: Number,
default: () => []
}
}
子组件接收的父组件的值分为引用类型和普通类型两种
普通类型:字符串(String)、数字(Number)、布尔值(Boolean)、空(Null)
引用类型:数组(Array)、对象(Object)
1.2、provide / inject
适用于祖孙,父子通信
// 父组件
<div>
<button @click="changeName">修改姓名</button>
<child-b />
</div>
<script>
......
data() {
return {
name: "Jack"
};
},
provide() {
return {
parentObj: this //提供祖先组件的实例
};
},
methods: {
changeName() {
this.name = 'Lily'
}
}
</script>
//后代组件
<template>
<div class="border2">
<P>姓名:{
{
parentObj.name}}</P>
</div>
</template>
<script>
export default {
inject: {
parentObj: {
default: () => ({
})
}
} // 或者inject: ['parentObj']
};
</script>
2、子组件向父组件传值
2.1、 this.$emit()
子组件绑定一个事件,通过 this.$emit() 来触发
// 子组件
<button @click="changeParentName">改变父组件的name</button>
export default {
methods: {
//子组件的事件
changeParentName: function() {
this.$emit('handleChange', 'ShuFeng') // 触发父组件中handleChange事件并传参ShuFeng
// 注:此处事件名称与父组件中绑定的事件名称要一致
}
}
}
// 父组件
<child @handleChange="changeName"></child>
methods: {
changeName(name) {
// name形参是子组件中传入的值ShuFeng
this.name = name
}
}
2.2、 通过 callback 函数
// 父组件
<child :callback="callback"></child>
methods: {
callback: function(name) {
this.name = name
}
}
// 子组件
<button @click="callback('shuFeng')">改变父组件的name</button>
props: {
callback: Function,
}
2.3、通过 $parent / $children 或 $refs 访问组件实例
// 子组件
export default {
data () {
return {
title: '子组件'
}
},
methods: {
sayHello () {
console.log('Hello');
}
}
}
// 父组件
<template>
<child ref="childRef" />
</template>
<script>
export default {
created () {
// 通过 $ref 来访问子组件
console.log(this.$refs.childRef.title); // 子组件
this.$refs.childRef.sayHello(); // Hello
// 通过 $children 来调用子组件的方法
this.$children.sayHello(); // Hello
}
}
</script>
2.4、 $attrs / $listeners
$attrs / $listeners ,通常配合 inheritAttrs 一起使用。
//父组件
<template>
<child :name="name" :age="age" :infoObj="infoObj" @updateInfo="updateInfo" @delInfo="delInfo" />
</template>
<script>
import Child from '../components/child.vue'
export default {
name: 'father',
components: {
Child },
data () {
return {
name: 'Lily',
age: 22,
infoObj: {
from: '上海',
job: 'policeman',
hobby: ['reading', 'writing', 'skating']
}
}
},
methods: {
updateInfo() {
console.log('update info');
},
delInfo() {
console.log('delete info');
}
}
}
</script>
//子组件
<template>
<grand-son :height="height" :weight="weight" @addInfo="addInfo" v-bind="$attrs" v-on="$listeners" />
// 通过 $listeners 将父作用域中的事件,传入 grandSon 组件,使其可以获取到 father 中的事件
</template>
<script>
import GrandSon from '../components/grandSon.vue'
export default {
name: 'child',
components: {
GrandSon },
props: ['name'],
data() {
return {
height: '180cm',
weight: '70kg'
};
},
created() {
console.log(this.$attrs);
// 结果:age, infoObj, 因为父组件共传来name, age, infoObj三个值,由于name被 props接收了,所以只有age, infoObj属性
console.log(this.$listeners); // updateInfo: f, delInfo: f
},
methods: {
addInfo () {
console.log('add info')
}
}
}
</script>
//grandSon.vue 组件:
<template>
<div>
{
{
$attrs }} --- {
{
$listeners }}
<div>
</template>
<script>
export default {
... ...
props: ['weight'],
created() {
console.log(this.$attrs); // age, infoObj, height
console.log(this.$listeners) // updateInfo: f, delInfo: f, addInfo: f
this.$emit('updateInfo') // 可以触发 father 组件中的updateInfo函数
}
}
</script>
3、非父子组件之间传值
3.1、$emit 和 props
适用于兄弟组件
在A兄使用$emit传值给到父组件,父组件在通过props传值给B兄
3.2、Bus总线程通信
通过建立一个第三方bus来做中转站,然后借用$emit 发送参数和 $on 来接受参数
建立一个bus.js
import Vue from 'vue'
export default Vue.prototype.bus = new Vue()
在main.js引入
import bus from './util/bus'
//发送信息组件
<template>
<button @click="changeBus()">bus</button>
</template>
...
methods: {
changeBus(){
this.bus.$emit("change",'yjw');
}
}
//接受信息组件
mounted(){
let self = this;
this.bus.$on('change',function(msg){
console.log(msg);
self.msg = msg;
})
}
3.3、Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,他适用于所有组件的传值,统一管理数据
3.4、provide / inject
同1.2一样
3.5、 $attrs / $listeners
同2.4一样