VUE项目中,组件嵌套使用的时候,常常须要用到互相传值,用到的方法不怪乎如下两种:vue
<template> <div> <Child :myProp="data"></Child> </div> </template> <script> import Child from "@/Child"; export default { components: { Child }, data() { return { data: "123321" } } }; </script>
子组件:vuex
<template> <div> <h1>{{myProp}}</h1> </div> </template> <script> export default { data() { return {}; }, props:{ myProp:{ type:String, default:"" } }, }; </script>
2.子组件经过 $emit方法发送子组件内部的数据给父组件,将须要传的值做为$emit的第二个参数,该值将做为实参传给响应自定义事件的方法api
父组件:this
<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>
子组件:spa
<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)传值。code
4.以及.sync
也只是上面几种方法的语法糖。component
可是我在实际开发过程当中,遇到一个比较特殊的场景需求,父组件请求接口,拿到的初始数据发给子组件,在子组件内修改表单后,在父组件执行提交操做,并且,子组件是经过Tab的切换的,还使用keep-live包裹, component 是使用v-bind:is
切换orm
通过屡次尝试,和探索,发现一种不错的解决方案,接口
父组件:事件
<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>