1. 父子组件传值
1.1 props
父组件可以把子级的属性和方法传给子组件, 子组件需要在props里面接收, 即可使用。props可以是数组类型, 也可以是对象类型。
:::success
//父组件
//子组件
props:{
parentData:[‘parentData’,’getData’]
},
:::
//父组件
<template>
<div class="parent" >
<h2>我是父组件</h2>
<h2>姓名:{{parentData.name}}</h2>
<h2>年龄:{{parentData.age}}</h2>
<my-child :parentData="parentData" :getData="getData"></my-child>
</div>
</template>
<script>
import MyChild from './MyChild.vue'
export default {
components: {
MyChild,
},
data() {
return {
parentData: {
name: '我是父组件',
age:'60'
},
getData(){
console.log('我是父组件的getData方法')
}
}
},
}
</script>
//子组件
<template>
<div class="child">
<h2>我是子元素</h2>
<h3>姓名:{{child.name}}</h3>
<h3>年龄:{{child.age}}</h3>
<button @click="getDataByParent">通过$parent获取父组件数据</button>
<button @click="getData">通ss</button>
<my-son v-bind="$attrs"></my-son>
</div>
</template>
<script>
import MySon from './MySon.vue'
export default {
components: {
MySon,
},
props:{
parentData:{
type:Object,
required: true,
default: function() {
return { name:'我是默认值', age:20 };
}
},
getData:{
type:Function
}
},
data() {
return {
child: {
name: '我是child组件',
age: 45,
},
}
},
methods: {
getDataByParent() {
console.log(this.parentData)
},
},
}
</script>
1.2 $emit
子组件可以通过this.$emit把子级的数据给父组件。
:::success
//父组件
//子组件
getDataByParent() {
this.$emit(‘sendMsg’,’我是子组件’)
},
:::
<template>
<div class="parent" >
<h2>我是父组件</h2>
<h2>姓名:{{parentData.name}}</h2>
<h2>年龄:{{parentData.age}}</h2>
<my-child @sendMsg = 'sendMsg'></my-child>
</div>
</template>
<script>
import MyChild from './MyChild.vue'
export default {
components: {
MyChild,
},
data() {
return {
parentData: {
name: '我是父组件',
age:'60'
},
getData(){
console.log('我是父组件的getData方法')
}
}
},
methods:{
sendMsg(val){
console.log(val)
}
}
}
</script>
//子组件
<template>
<div class="child">
<h2>我是子元素</h2>
<h3>姓名:{{child.name}}</h3>
<h3>年龄:{{child.age}}</h3>
<button @click="getDataByParent">send</button>
<my-son v-bind="$attrs"></my-son>
</div>
</template>
<script>
import MySon from './MySon.vue'
export default {
components: {
MySon,
},
data() {
return {
child: {
name: '我是child组件',
age: 45,
},
}
},
methods: {
getDataByParent() {
this.$emit('sendMsg','我是子组件')
},
},
}
</script>
1.3 $parent
子组件通过this.$parent获取父组件的属性和方法
:::success
this.$parent.parentData //获取父组件的属性
this.$parent.getData() //调用父组件的方法
:::
//parent组件
<template>
<div class="parent" ref='parentEle'>
<h2>我是父组件</h2>
<h2>姓名:{{parentData.name}}</h2>
<h2>年龄:{{parentData.age}}</h2>
<my-child></my-child>
</div>
</template>
<script>
import MyChild from './MyChild.vue'
export default {
components: {
MyChild,
},
data() {
return {
parentData: {
name: '我是父组件',
age:'60'
},
}
},
}
</script>
//child组件
<template>
<div class="child">
<h2>我是子元素</h2>
<h3>姓名:{{child.name}}</h3>
<h3>年龄:{{child.age}}</h3>
<button @click="getDataByParent">通过$parent获取父组件数据</button>
<my-son v-bind="$attrs"></my-son>
</div>
</template>
<script>
import MySon from './MySon.vue'
export default {
components: {
MySon,
},
data() {
return {
child: {
name: '我是child组件',
age: 45,
},
}
},
methods: {
getDataByParent() {
console.log(this.$parent.parentData) //获取父组件的属性
console.log(this.$parent.getData()) //调用父组件的方法
},
},
}
</script>
1.4 $refs
可以通过this.$refs获取子组件的属性和方法.
:::success
console.log(this.$refs.childEle.child) //获取子组件的属性
console.log(this.$refs.childEle.change())//获取子组件的方法
:::
<template>
<div class="parent" >
<h2>我是父组件</h2>
<h2>姓名:{{parentData.name}}</h2>
<h2>年龄:{{parentData.age}}</h2>
<button @click="getData">通过ref获取子组件的数据</button>
<my-child ref='childEle'></my-child>
</div>
</template>
<script>
import MyChild from './MyChild.vue'
export default {
components: {
MyChild,
},
data() {
return {
parentData: {
name: '我是父组件',
age:'60'
}
}
},
methods:{
getData(){
console.log(this.$refs.childEle.child) //获取子组件的属性
console.log(this.$refs.childEle.change())//获取子组件的方法
}
}
}
</script>
1.5 $attrs
首先我们有三个组件A-B-C,然后想A中的属性传入C中,基本的做法是这样的,一层一层通过 props 往下传递。
ComponentB 组件中并没有使用到父组件传递过来的属性 msg,但是这样写就是想把属性再传递给ComponentC,那么除了这种写法还可以给ComponentC绑定$attrs属性。
<component-c v-bind="$attrs"></component-c>
1.6 $children
this.$children可以获取子组件的方法和属性。
在父组件中打印this.$children。里面包含了所有子组件:
<template>
<div class="parent">
<h2>我是父组件</h2>
<h2>姓名:{{parentData.name}}</h2>
<h2>年龄:{{parentData.age}}</h2>
<button>通过ref获取子组件的数据</button>
<my-child :parentData="parentData"></my-child>
</div>
</template>
<script>
import MyChild from './MyChild.vue'
export default {
components: {
MyChild,
},
data() {
return {
parentData: {
name: '我是父组件',
age: '60',
},
}
},
mounted() {
console.log(this.$children[0].child)
console.log(this.$children[0].getData())
},
}
</script>
2. 兄弟组件传值
2.1 bus事件总线
通过this.$emit和this.$on。this.$emit触发当前实例上的事件, 并将参数传递给监听器, 通过this.$on监听当前实例上的自定义事件。 :::success 简单理解为一个托管平台, 这个平台必须独立于关联两个组件之外的vue实例, 当2个组件需要传递数据的时候, 发起方在平台上触发一个this.$emit然后传递参数, 接收方在平台设置一个监听this.$on接收参数并执行方法, 方法的参数就是发送方传递过来的参数。 :::
//main.js
import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import Directives from './directives/index'
import 'element-ui/lib/theme-chalk/index.css';
import store from './store'
Vue.use(Directives)
Vue.config.productionTip = false;
Vue.use(ElementUI);
const vm = new Vue({
render: h => h(App),
store,
beforeCreate(){
Vue.prototype.$bus = this;
}
}).$mount('#app')
console.log(vm)
//发送方
this.bus.$emit('send', this.child1)
//接收方
this.bus.$on('send', (value) => {
this.child1 = value
})
//兄弟一
<template>
<div class="child">
<h2>我是子元素</h2>
<h3>姓名:{{child1.name}}</h3>
<h3>年龄:{{child1.age}}</h3>
<button @click="sendData">给兄弟组件传值</button>
<hr>
</div>
</template>
<script>
export default {
data() {
return {
child1: {
name: '我是child1111组件',
age: 45,
},
}
},
methods:{
sendData(){
this.bus.$emit('send', this.child1)
}
}
}
</script>
<style>
.child {
padding: 20px;
background: green;
}
</style>
//兄弟2
<template>
<div class="child2">
<h2>我是子元素</h2>
<h3>姓名:{{child2.name}}</h3>
<h3>年龄:{{child2.age}}</h3>
<p>下面是兄弟组件传过来的值</p>
<h2>{{child1.name}}</h2>
<h2>{{child1.age}}</h2>
</div>
</template>
<script>
export default {
data() {
return {
child2: {
name: '我是child组件22222',
age: 45,
},
child1:{}
}
},
methods:{
},
mounted(){
console.log(1231321)
// this.bus.$on('send', this.getData)
this.bus.$on('send', (value) => {
this.child1 = value
})
}
}
</script>
<style>
.child2 {
padding: 20px;
background: rgb(32, 68, 230);
}
</style>