2017-09-25 79 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>

相关问题