2017-09-25 95 views
1

我有一個設置選項,它將從父組件更新。我將這些設置數據保存在localStorage上,這三個子組件正在使用設置數據。如何在Vue JS的父組件上按下按鈕時刷新子組件?

<P> 
    <c1> </c1> 
    <c2> </c2> 
    <c3> </c3> 
</P> 

我想要一種方式,當我將更新我的設置數據時,三個組件將刷新或更新以獲取新值。 像,我會按下父組件上的一個按鈕,三個孩子將被更新。

------------------------ UPDATED --------------------- ---------

模板部件:

<template> 
 
    <div class="main-content"> 
 
    <div class="main"> 
 

 
<!-- COMPONENT --> 
 
<div class="row"> 
 
    <div class="padpad"> 
 
     <div class="col-md-6"> 
 
     <app-colma></app-colma> 
 
     </div> 
 
     <div class="col-md-3"> 
 
     <app-colmb></app-colmb> 
 
     </div> 
 
    
 
    </div> 
 
</div> 
 

 
<!-- SAVE BUTTON --> 
 

 
      <button type="submit" class="btn btn-success" data-dismiss="modal" aria-label="Close" v-on:click="onSubmit()"><span>Save</span></button> 
 
      
 
      
 
       
 
<!-- DATA FORM (SELECT, OPTION) --> 
 
       <div class="container modal-body"> 
 

 
        <div class="col-xs-12 col-md-3"> 
 
        <h4>Sortierung</h4> 
 

 
        <div class="radio"> 
 
         <label><input value="theropeut" type="radio" name="filterop">Theropeut</label> 
 
        </div> 
 
        <div class="radio"> 
 
         <label><input value="ausl_perf" type="radio" name="filterop">Ausl Perf</label> 
 
        </div> 
 
        <div class="radio"> 
 
         <label><input value="ausl_bud" type="radio" name="filterop">Ausl Bud</label> 
 
        </div> 
 
        <div class="radio"> 
 
         <label><input value="umsatz" type="radio" name="filterop">Umsatz</label> 
 
        </div> 
 

 
        <div class="order-select"> 
 
         <select id="orderid" class="form-control"> 
 
          <option value="ascending">Ascending</option> 
 
          <option value="descending">Descending</option> 
 
         </select> 
 
        </div> 
 
        </div> 
 
    </div> 
 
</div> 
 
</template>

腳本代碼:

<script> 
 
import ColmA from './ColmA.vue'; 
 
import ColmB from './ColmB.vue'; 
 
import ColmTotal from './ColmTotal.vue'; 
 
export default { 
 
    components: { 
 
    'app-colma': ColmA, 
 
    'app-colmb': ColmB, 
 
    'app-colmtotal': ColmTotal 
 
    }, 
 
\t name: 'main-content', 
 
\t data() { 
 
\t \t return { 
 
\t \t \t users: [], 
 
     filtr:'', 
 
\t \t \t order:'' 
 
\t \t } 
 
\t }, 
 
\t methods: { 
 
    onSubmit: function(){ 
 
     // console.log("onsubmit"); 
 

 
     //filter 
 
     var filterop = document.getElementsByName('filterop'); 
 

 
     for (var i = 0, length = filterop.length; i < length; i++) { 
 
      if (filterop[i].checked) { 
 
       // do whatever you want with the checked radio 
 
       // alert(filterop[i].value); 
 
       this.filtr = filterop[i].value; 
 
       // only one radio can be logically checked, don't check the rest 
 
       break; 
 
      } 
 
     } 
 
     //order 
 
     var e = document.getElementById("orderid"); 
 
     this.order = e.options[e.selectedIndex].value; 
 

 
     var homesetting = { 
 
      filter: this.filtr, 
 
      order:this.order, 
 
     }; 
 

 

 

 
     if (localStorage.getItem('homesetting') === null) { 
 
     var homesettings = []; 
 

 
     // homesettings.push(homesetting); 
 
     localStorage.setItem('homesetting', JSON.stringify(homesetting)); 
 
     } else { 
 
     localStorage.removeItem('homesetting'); 
 
     localStorage.setItem('homesetting', JSON.stringify(homesetting)); 
 

 
     }; 
 
    } 
 

 
\t }, 
 

 
\t created: function() { 
 
\t \t this.fetchData(); 
 
\t } 
 

 
} 
 

 
</script>

組件代碼:

<script> 
 
export default { 
 
    name: 'colma', 
 
    data() { 
 
    return { 
 
     title: 'A Area', 
 
     colmAdata:[] 
 
    } 
 
    }, 
 
    methods: { 
 
    fetchData: function() { 
 
     var self = this; 
 
     var homeObject = JSON.parse(localStorage.getItem('homesetting')); 
 

 
     // console.log('retrievedObject: ', retrievedObject.filter); 
 
     var filter= homeObject.filter; 
 
     var order= homeObject.order; 
 

 
     // HERE I NEED MY TWO UPDATED VARIABLES 
 
     var a = 'http://localhost:3000/'+'_'+filter+'_'+order; 
 
     console.log('A',a); 
 

 

 
     $.get(apiURL, function (data) { 
 
     self.colmAdata = data; 
 
     // self.$store.state.storeGdata = ' store data from content'; 
 
     // console.log(data.people[0].name); 
 

 
     }); 
 

 
    } 
 

 
    }, 
 
\t created: function() { 
 
\t \t this.fetchData(); 
 
\t } 
 
} 
 
</script>

+0

你嘗試過什麼?你在哪裏研究? – Script47

回答

2

解決此問題的辦法是發射從子組件自定義事件(如果改變從孩子起源),然後捕獲/聽這個事件在父類中調用一個方法。然後可以使用此方法調用將更新值的子方法。

真正的問題是,爲什麼你需要這樣做?假設父組件是真實的來源(即將數據作爲道具傳遞給子組件),那麼您只需要監視這些道具中的變化,或者使用計算的道具來獲取更新的值。根本不需要使用事件來調用方法。

基本上,你的手法可以是:

  1. 傳遞父值(存儲在父數據)作爲道具子組件。子組件將被動地更新它們的繼承屬性。

  2. 家長的設置也可以同時存儲到localStorage。這可以通過簡單地使用watch來監視父數據的變化來完成。在這種情況下,您可以簡單地從localStorage中讀取父級重新裝入時的狀態(例如重新裝入頁面時)—使用mounted lifecycle hook。根據第1點,這些更改將再次傳播到子組件。

證明一個概念例子(爲localStorage的功能起作用,please check this fiddle因爲代碼片段沙盒):

Vue.component('child-component-a', { 
 
    template: '<div><h2>Child component A</h2><p>I multiply inherited parent value by 2: <strong>{{ computedNumber }}</strong></p></div>', 
 
    props: { 
 
    number: { 
 
     type: Number 
 
    } 
 
    }, 
 
    computed: { 
 
    computedNumber() { 
 
     return this.number * 2; 
 
    } 
 
    } 
 
}); 
 

 
Vue.component('child-component-b', { 
 
    template: '<div><h2>Child component B</h2><p>I divide inherited parent value by 16: <strong>{{ computedNumber }}</strong></p></div>', 
 
    props: { 
 
    number: { 
 
     type: Number 
 
    } 
 
    }, 
 
    computed: { 
 
    computedNumber() { 
 
     return this.number/16; 
 
    } 
 
    } 
 
}); 
 

 
var app = new Vue({ 
 
    el: '#app', 
 
    data: { 
 
    parentNumber: 1024 
 
    }, 
 
    watch: { 
 
    parentNumber() { 
 
     // Store parent number in localStorage when updated 
 
     // *NOTE: Disabled in this code snippet since it is sandboxed 
 
     // localStorage.setItem('parentNumber', this.parentNumber); 
 
    } 
 
    }, 
 
    mounted() { 
 
    // Overwrite parent data if localStorage is found 
 
    // *NOTE: Disabled in this code snippet since it is sandboxed 
 
    // if (localStorage.getItem('parentNumber') !== null) { 
 
    // this.parentNumber = localStorage.getItem('parentNumber'); 
 
    // } 
 
    } 
 
});
html { 
 
    font-family: Arial, sans-serif; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script> 
 
<div id="app"> 
 
    <div> 
 
    <h1>Parent component</h1> 
 
    <p>I have a value of <strong>{{ parentNumber }}</strong>.</p> 
 
    <p>But wait, you can change my number!</p> 
 
    <input v-model="parentNumber" type="number" /> 
 
    </div> 
 
    <child-component-a v-bind:number="parentNumber"></child-component-a> 
 
    <child-component-b v-bind:number="parentNumber"></child-component-b> 
 
</div>

+0

我同意。存儲在本地存儲中並從本地存儲讀取不是傳播更改的方式。 – Strernd

+0

我需要將這些設置數據保存在localstorage上。所以我認爲這個程序是行不通的。 – Sharat

+0

@CodeName閱讀我更新的答案:) – Terry

1

如果你使用Vue公司。JS你應該真的只是使用 Vue.JS - 父母應該有一個模型,其中包含您的設置作爲反應數據。然後,您將此屬性傳遞給您的組件,如屬性,並且該組件僅在該屬性上定義了一個觀察者

var localStore = { reason: 'Fake, because no localStorage in Sandbox' }; 
 

 
Vue.component('rows', { 
 
    props: ["order"], 
 
    data: function(){ return { values: [] } }, 
 
    template: `<ul><li v-for="v in values">{{v}}</li></ul>`, 
 
    created: function() { this.fetchValues() }, 
 
    watch: { order: function() { this.fetchValues() } }, 
 
    methods: { fetchValues: function() { 
 
    /* Placeholder for an ajax-call with order as a parameter */ 
 
    this.values = (this.order == 'ascending') ? [1,2,3] : [3,2,1] 
 
    } } 
 
}) 
 

 
new Vue({ 
 
    el: '#main', 
 
    data: { order: 'ascending' }, 
 
    created: function() { 
 
    if (localStore.order) { 
 
     this.order = localStore.order; 
 
    } 
 
    }, 
 
    watch: { order: function() { 
 
    /* Save any change on order in the local storage */ 
 
    localStore.order = this.order; 
 
    } } 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.js"></script> 
 

 
<div id="main"> 
 
    <select v-model="order"> 
 
    <option value="ascending">Sort Ascending</option> 
 
    <option value="descending">Sort Descending</option> 
 
    </select> 
 

 
    <rows :order="order"></rows> 
 
</div>

相關問題