父子组件数据传递
父组件单向传递给子组件
使用v-bind传递
父组件:
<div>
<div class="far">
<label>父组件数据: </label>
<input v-model="toChildData" type="text"/>
</div>
<ToChild class="child" :toChildData="toChildData"/>
</div>
export default {
name: 'DataTransform',
components: {
ToChild,
},
data () {
return {
toChildData: '',
}
},
}
子组件:
<div>
<label>子组件数据: </label>
<input v-model="toChildData" type="text"/>
</div>
export default {
name: 'ToChild',
props: {
toChildData: {
type: String,
default: '',
}
},
computed: {
childDate: {
get () {
return this.toChildData
},
set (value) {},
},
},
}
子组件单向传递给父组件
使用 $emit $on 实现
父组件:
<div>
<div class="far">
<label>父组件数据: </label>
<input v-model="toFatherData" type="text"/>
</div>
<ToFather class="child" @onToFather="onToFather"/>
</div>
import ToFather from './_toFather.vue'
export default {
name: 'DataTransform',
components: {
ToFather,
},
data () {
return {
toFatherData: '',
}
},
methods: {
onToFather (data) {
this.toFatherData = data
},
},
}
子组件:
<div>
<label>子组件数据: </label>
<input v-model="toFatherData" type="text"/>
</div>
export default {
name: 'ToFather',
data () {
return {
toFatherData: '',
}
},
watch: {
toFatherData (newValue, oldValue) {
this.$emit('onToFather', newValue)
},
},
};
父子组件间数据双向传递
使用自定组件v-model
适用于只有一个参数需要实现双向绑定
父组件:
<div>
<div class="far">
<label>父组件数据: </label>
<input v-model="data" type="text"/>
</div>
<Bidirectional1 class="child" v-model="data"/>
</div>
<script>
export default {
name: 'DataTransform',
components: {
Bidirectional1,
},
data () {
return {
data: '',
}
},
}
</script>
子组件:
<template>
<div>
<label>子组件数据: </label>
<input v-model="childValue" type="text"/>
</div>
</template>
export default {
name: 'Bidirectional1',
model: {
prop: 'singleData',
event: 'change',
},
props: {
singleData: String,
},
computed: {
childValue: {
get () {
return this.singleData
},
set (value) {
this.$emit('change', value)
},
},
},
}
使用.sync修饰符实现
- 注意带有 .sync 修饰符的 v-bind 不能和表达式一起使用
- 也可以将这个 .sync 修饰符和 v-bind 配合使用: <text-document v-bind.sync="doc"></text-document> 这样会把 doc 对象中的每一个属性都作为一个独立的 prop 传进去
父组件:
<div>
<div class="far">
<label>单参数父组件数据: </label>
<input v-model="multipleData" type="text"/>
</div>
<Bidirectional2 class="child" :multipleData.sync="multipleData"/>
<div class="far">
<label>多参数父组件数据: </label>
<input v-model="multipleDataObj.dataOne" type="text"/>
<input v-model="multipleDataObj.dataTwo" type="text"/>
</div>
<Bidirectional3 class="child" v-bind.sync="multipleDataObj"/>
</div>
export default {
data () {
return {
multipleDataObj: {
dataOne: '',
dataTwo: '',
},
multipleData: '',
}
}
}
子组件:
// 单参数子组件
<div>
<label>单参数子组件数据: </label>
<input v-model="childValue" type="text"/>
</div>
export default {
name: 'Bidirectional2',
props: {
multipleData: String,
},
computed: {
childValue: {
get () {
return this.multipleData
},
set (value) {
this.$emit('update:multipleData', value)
},
},
},
}
// 多参数子组件
<template>
<div>
<label>多参数子组件数据: </label>
<input v-model="childValueOne" type="text"/>
<input v-model="childValueTwo" style="margin-left: 10px" type="text"/>
</div>
</template>
<script>
export default {
name: 'Bidirectional3',
props: {
dataOne: String,
dataTwo: String,
},
computed: {
childValueOne: {
get () {
return this.dataOne
},
set (value) {
this.$emit('update:dataOne', value)
},
},
childValueTwo: {
get () {
return this.dataTwo
},
set (value) {
this.$emit('update:dataTwo', value)
},
},
},
}
</script>
通过$on, $emit实现
父组件:
<template>
<div class="far">
<label>父组件数据: </label>
<input v-model="multipleData3" type="text"/>
</div>
<Bidirectional4 class="child" :multipleData="multipleData3" @changeDate="changeMultipleData"/>
</template>
<script>
export default {
data () {
return {
multipleData3: '',
}
},
methods: {
changeMultipleData (value) {
this.multipleData3 = value
},
},
}
</script>
子组件:
<template>
<div>
<label>子组件数据: </label>
<input v-model="childValue" type="text"/>
</div>
</template>
<script>
export default {
name: 'Bidirectional4',
props: {
multipleData: String,
},
computed: {
childValue: {
get () {
return this.multipleData
},
set (value) {
this.$emit('changeDate', value)
},
},
},
}
</script>
兄弟组件数据传递
子组件A向子组件B传递数据
使用父组件做中转
子组件A可以先使用$emit将数据传递给父组件,再使用props由父组件将数据传递给子组件B,具体代码不做展示,参考上文父子组件的传递。
使用Bus中央事件总线(不推荐)
新建一个bug.js文件,导出一个新的Vue,并在子组件中引入,在A中使用$emit发出事件,在B中使用$on监听事件。
使用bus需要注意两点
- $on应该在 created钩子内使用,如果在mounted使用,它可能接受不到其他组件来自created钩子发出的事件
- 使用$on后,在 beforeDestroy 钩子里应该使用$off解除。因为组件销毁后,就没必要把监听的句柄储存在bus里。
bus.js
import Vue from "vue";
export const Bus = new Vue()
父组件:
<template>
<div class="item">
<h4>兄弟组件数据传递,Bus中央事件总线</h4>
<div class="far">
<label>父组件数据: </label>
</div>
<BrotherA2 class="child"></BrotherA2>
<BrotherB2 class="child"></BrotherB2>
</div>
</template>
子组件A:
<template>
<div>
<label>子组件A数据: </label>
<input v-model="childValue" type="text"/>
</div>
</template>
<script>
import { Bus } from '../../common/bus'
export default {
name: 'BrotherA2',
data () {
return {
childValue: '',
}
},
watch: {
childValue (newV, oldV) {
Bus.$emit('changeBrotherData2', newV)
},
},
}
</script>
子组件B:
<template>
<div>
<label>子组件B数据: </label>
<input v-model="childValue" type="text"/>
</div>
</template>
<script>
import { Bus } from '../../common/bus'
export default {
name: 'BrotherB2',
data () {
return {
childValue: ''
}
},
created () {
Bus.$on('changeBrotherData2', init)
},
beforeDestroy () {
Bus.$off('changeBrotherData2', init)
},
methods: {
init (value) {
this.childValue = value
}
},
}
</script>
祖孙组件数据传递
通过父子组件一层一层传递
可以通过祖父组件将数据传递给父组件,再让父组件传递给子组件。具体代码不做展示,参考上文父子组件的传递。
使用provide inject
除了层层传递外,祖孙组件数据传递还可以provide和inject实现。
祖组件中provide返回要传给下级的数据,在需要获取数据的孙组件中使用inject注入数据。
祖组件
<div class="item">
<h4>祖孙组件数据传递</h4>
<div class="far">
<label>祖组件数据:</label>
<input v-model="grandchildData" type="text"/>
</div>
<ChildFather class="child"></ChildFather>
</div>
孙组件
<template>
<div>
<label>孙组件数据: </label>
<span>{{grandchildData()}}</span>
</div>
</template>
<script>
export default {
name: 'GroudSon',
inject: ['grandchildData'],
}
</script>