vue中父子组件之间的传值、非父子组件之间的传值
在Vue实例中每个组件之间都是相互独立的,都有自己的作用域,所以组件之间是不能直接获取数据。在项目开发中一个组件可能需要获取另一个组件的值,我们可以通过其他方法间接的获取。所以,获取的方法有以下几种:
1、父子组件之间通信:
1.1 父组件 → 子组件
父组件传值给子组件:通过自定义属性传值。
父组件:
<template> <div class="home"> <p>这是Home页面</p> <p>组件A页面:</p> <button @click="commitVal">父组件传值给子组件</button> <br /><br /> <!-- :commitVal是定义的属性--> <com-a :commitVal='fatherVal'></com-a> </div> </template> <script> import comA from '../components/comA.vue' import comB from '../components/comB.vue' export default{ components:{ 'com-a':comA, 'com-b':comB, }, data(){ return{ fatherVal:'aaa' } }, methods:{ commitVal(){ //这里点击 “父组件传值给子组件”按钮将值传递给子组件A this.fatherVal='这是父组件传过来的值'; } } } </script> <style> </style>
子组件:
<template> <div class="box-1"> 这是组件一:{{data}} {{requestData}} </div> </template> <script> export default{ data(){ return{ data:10, requestData:'' } }, props:['commitVal'], watch:{ //props中的 commitVal 就是来自父组件自定义的属性,这里通过监听将值转化为子组件A的值。 commitVal(newVal,oldVal){ this.requestData=this.commitVal; } } } </script> <style> .box-1{ border: 1px solid lightsteelblue; height: 100px; } </style>
结果:点击按钮后子组件页面获取到了父组件的值。
1.2 子组件 → 父组件:通过自定义方法。
父组件页面:
<template> <div class="home"> <p>这是Home页面</p> <p>组件A页面:</p> <button @click="commitVal">父组件传值给子组件</button> <br /><br /> <p>来自子组件的值:{{sonVal}}</p> <!-- :commitVal是定义的属性--> <!--requestSonData是自定义的方法,在requestMethod中获取子组件传过来的值--> <com-a :commitVal='fatherVal' @requestSonData='requestMethod'></com-a> </div> </template> <script> import comA from '../components/comA.vue' import comB from '../components/comB.vue' export default{ components:{ 'com-a':comA, 'com-b':comB, }, data(){ return{ fatherVal:'aaa', sonVal:null } }, methods:{ commitVal(){ //这里点击 “父组件传值给子组件”按钮将值传递给子组件A this.fatherVal='这是父组件传过来的值'; }, requestMethod(val){ console.log(val); //将传过来的值转换成自己的值 this.sonVal=val.value; } } } </script> <style> </style>
子组件页面:
<template> <div class="box-1"> 这是组件一:{{data}} {{requestData}} <button @click="commitToFather">子组件传值给父组件</button> </div> </template> <script> export default{ data(){ return{ data:10, requestData:'' } }, props:['commitVal'], methods:{ commitToFather(){ //点击按钮时,通过$emit(val1,val2)去触发父组件自定义的方法requestSonData,顺便传一个obj过去,参数val1是方法名称,参数val2是需要传的值。 let obj={ title:'子组件的内容', value:1111 } this.$emit('requestSonData',obj) } }, watch:{ //props中的 commitVal 就是来自父组件自定义的属性,这里通过监听将值转化为子组件A的值。 commitVal(newVal,oldVal){ this.requestData=this.commitVal; } } } </script> <style> .box-1{ border: 1px solid lightsteelblue; height: 100px; } </style>
结果:点击按钮时父组件页面获取到了子组件的值。
1.3在父组件页面调用子组件页面的方法和获取其值:
1.3.1在父组件页面调用子组件页面的方法:通过refs属性调用
父组件页面:
<template> <div class="home"> <p>这是Home页面</p> <p>组件A页面:</p> <button @click="commitVal">父组件传值给子组件</button> <button @click="getComaData">父组件页面调用子组件页面的方法</button> <br /><br /> <p>来自子组件的值:{{sonVal}}</p> <!-- :commitVal是定义的属性--> <!--requestSonData是自定义的方法,在requestMethod中获取子组件传过来的值--> <com-a :commitVal='fatherVal' @requestSonData='requestMethod' ref='coma'></com-a> </div> </template> <script> import comA from '../components/comA.vue' import comB from '../components/comB.vue' export default{ components:{ 'com-a':comA, 'com-b':comB, }, data(){ return{ fatherVal:'aaa', sonVal:null } }, methods:{ commitVal(){ //这里点击 “父组件传值给子组件”按钮将值传递给子组件A this.fatherVal='这是父组件传过来的值'; }, requestMethod(val){ console.log(val); //将传过来的值转换成自己的值 this.sonVal=val.value; }, getComaData(){ //给子组件加上ref属性,可以通过 this.$refs.coma.getData()调用了,coma是自定义的属性名称。 console.log(this.$refs.coma.getData()); } } } </script> <style> </style>
子组件页面:
<template>
<div class="box-1">
这是组件一:{{data}}
{{requestData}}
<button @click="commitToFather">子组件传值给父组件</button>
</div>
</template>
<script>
export default{
data(){
return{
data:10,
requestData:''
}
},
props:['commitVal'],
methods:{
commitToFather(){
//点击按钮时,通过$emit(val1,val2)去触发父组件自定义的方法requestSonData,顺便传一个obj过去,参数val1是方法名称,参数val2是需要传的值。
let obj={
title:'子组件的内容',
value:1111
}
this.$emit('requestSonData',obj)
},
//这里将值返回给调用的对象
getData(){
return '这是通过父组件页面调用的';
}
},
watch:{
//props中的 commitVal 就是来自父组件自定义的属性,这里通过监听将值转化为子组件A的值。
commitVal(newVal,oldVal){
this.requestData=this.commitVal;
}
}
}
</script>
结果:
1.3.2在父组件页面获取子组件页面的值得另一种方法:通过refs属性获取
此方法类似于1.3.2的方法这里只展示部分代码:
this.$refs.coma.data; //10 获取到了子组件的值。
1.4在子组件页面如何获取父组件的中的值:通过$parent调用
父组件:只展示部分代码
getData(){ return '这是父组件的值'+this.fatherVal; }
子组件:
<button @click="getFather">调用父组件的方法</button>
getFather(){
console.log(this.$parent.getData());
}
结果:
2、非父子组件的传值:可以通过子组件A将值传给父组件,父组件再将值传给子组件B,这样做很麻烦,我们可以借助中央事件总线($bus)来进行传值,$bus就像一个中间键。
main.js页面:新建一个vue空实例作为$bus挂载到原型链上。
Vue.prototype.$bus=new Vue();
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store/index.js'
//将一个$bus挂载到vue实例的原型链上,在其它任何页面就可以直接使用了。
Vue.prototype.$bus=new Vue();
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
组件A:
通过this.$bus.$emit()去触发 commitDataTo,同时自定义一个obj传过去。
<template>
<div class="box-1">
这是组件一:{{data}}
{{requestData}}
<!--<button @click="commitToFather">子组件传值给父组件</button>-->
<!--<button @click="getFather">调用父组件的方法</button>-->
<button @click="commitToB">传值给组件B</button>
</div>
</template>
<script>
export default{
data(){
return{
data:10,
requestData:''
}
},
methods:{
commitToB(){
//通过this.$bus.$emit()去触发 commitDataTo,同时自定义一个obj传过去。
let obj={
title:'这是组件A传过来的值',
value:1111
}
this.$bus.$emit('commitDataTo',obj)
}
},
}
</script>
组件B:
通过this.$bus.$on()监听。
<template> <div class="box-2"> 这是组件二:{{data}} 这是组件一:{{valueOne}} </div> </template> <script> export default{ data(){ return{ data:20, valueOne:'' } }, mounted(){ //通过this.$bus.$on监听commitDataTo,同时获取传过来的值。 this.$bus.$on('commitDataTo',(val)=>{
console.log(val); this.valueOne=val.title; }); }, methods:{ getDataTwo(){ console.log('组件二的值:'+this.data); }, }, } </script>
结果:
3、非父子组件之间方法的调用:
也是通过$bus.$emit和$bus.$on,将要调用的方法写在$bus.$on的回调方法里。
以上就是父子组件、非父子组件之间的传值和方法的调用。