VUE项目中,组件嵌套使用的时候,经常需要用到互相传值,用到的方法不怪乎以下两种:
- 父组件通过属性的方式给子组件传值,子组件用props进行数据的接收,父组件:
<template>
<div>
<Child :myProp="data"></Child>
</div>
</template>
<script>
import Child from "@/Child";
export default {
components: {
Child
},
data() {
return {
data: "123321"
}
}
};
</script>
子组件:
<template>
<div>
<h1>{{myProp}}</h1>
</div>
</template>
<script>
export default {
data() {
return {};
},
props:{
myProp:{
type:String,
default:""
}
},
};
</script>
2.子组件通过 $emit方法发送子组件内部的数据给父组件,将需要传的值作为$emit的第二个参数,该值将作为实参传给响应自定义事件的方法
父组件:
<template>
<div>
<Child @handle="myHandle"></Child>
</div>
</template>
<script>
import Child from "@/Child";
export default {
components: {
Child
},
data() {
return { }
},
method:{
myHandle(str){
console.log(str);// => 123321
}
}
};
</script>
子组件:
<template>
<div>
<h1>1112222</h1>
<button @click='onclick'></button>
</div>
</template>
<script>
export default {
data() {
return {};
},
method:{
onclick(){
this.$emit('handle','123321')
}
}
};
</script>
3.另外,兄弟组件直接传值则是通过bus,说白了就是new Vue(),由于Vue 没有直接子对子传参的方法,建议将需要传递数据的子组件,都合并为一个组件。如果一定需要子对子传参,可以先从传到父组件,再传到子组件。或者通过eventBus或vuex(小项目少页面用eventBus,大项目多页面使用 vuex)传值。
4.以及.sync
也只是上面几种方法的语法糖。
但是我在实际开发过程中,遇到一个比较特殊的场景需求,父组件请求接口,拿到的初始数据发给子组件,在子组件内修改表单后,在父组件执行提交操作,而且,子组件是通过Tab的切换的,还使用keep-live包裹, component 是使用v-bind:is
切换
经过多次尝试,和探索,发现一种不错的解决方案,
父组件:
<template>
<el-tabs v-model="currentTab" :before-leave="tabBeforeLeave">
<el-tab-pane v-for="(tab, $index) in tabs" :key="$index" :name="tab.alias">
<span slot="label">
{{tab.name}}
</span>
<transition>
<keep-alive >
<component
v-bind:is="tab.relationComponent"
:ref="tab.relationComponent"
:data="data"
></component>
</keep-alive>
</transition>
</el-tab-pane>
</el-tabs>
</template>
<script>
import aComponent from "@/aComponent";
import bComponent from "@/bComponent";
import cComponent from "@/cComponent";
export default {
components: {
aComponent,
bComponent,
cComponent
},
data() {
return {
tabs:[ {
name: 'AAA',
alias: 'aaa',
relationComponent: 'aComponent',
},{
name: 'BBB',
alias: 'bbb',
relationComponent: 'bComponent',
},{
name: 'CCC',
alias: 'ccc',
relationComponent: 'cComponent',
},],
data:{
aChildData:{},
bChildData:{},
cChildData:{}
}
}
},
created() {
this.getData()
},
method:{
getData(){
//接口请求之前保存的数据
this.$api.funy({ id: '123457' },
response => {
if(response){
this.data.aChildData=response;
this.currentTab = 'aaa';
this.$refs['aComponent'][0].localAssign();
}
},
fal => {
}
);
},
submit(){
//组件内修改的数据,可以通过下面这个方法获取到,并且在父组件提交
let achild = this.$refs['aComponent'][0].sogalocal
}
}
};
</script>
子组件aComponent:
<template>
<div>
<el-form v-model="sogalocal" label-width="120px">
<el-input
type="textarea"
:autosize="{ minRows: 4, maxRows: 6}"
placeholder="placeholder"
maxlength="42"
show-word-limit
v-model="sogalocal.desc">
</el-input>
<el-radio-group v-model="sogalocal.bingAuth">
<el-radio label="jia">宋兵甲</el-radio>
<el-radio label="yi">宋兵乙</el-radio>
<el-radio label="bing">宋兵丙</el-radio>
</el-radio-group>
</el-form>
</div>
</template>
<script>
export default {
name: 'child'
props: {
data:{
type: Object,
default: () => {},
}
},
data() {
return {
sogalocal: null
};
},
created() {},
mounted(){},
methods: {
localAssign(){
//等到父组件拿到数据,然后调用this.$refs['aComponent'][0].localAssign();实现数据本地化,
//或者通过这个接口把数据传过来localAssign(aChildData)
this.sogalocal = Object.assign({},this.data.aChildData)
},
}
};
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。