vue 父組件傳值給子組件,子組件中修改數據,父組件獲取最新的值

VUE項目中,組件嵌套使用的時候,常常須要用到互相傳值,用到的方法不怪乎如下兩種:vue

  1. 父組件經過屬性的方式給子組件傳值,子組件用props進行數據的接收,父組件:
<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>
相關文章
相關標籤/搜索