2017-04-19 27 views
1

我試圖訪問我的根Vue實例中的組件數據。我試圖完成的是,你點擊一個按鈕並出現一組輸入。每個輸入集都是localStorage中自己的對象,具有密鑰id,行李和金額。當我更新一組輸入時,它們的值應該在localStorage中更新。我無法弄清楚如何訪問我的組件的數據袋和金額。我認爲我應該使用的是道具,因爲這是我在React中使用的。但是,我不太願意在Vue中使用它們。VueJS從組件Vue實例中訪問數據

這是我到目前爲止有:

var STORAGE_KEY = "orders"; 

var orderStorage = { 
    fetch: function() { 
    var orders = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]"); 
    orders.forEach(function(order, index) { 
     order.id = index; 
    }); 
    orderStorage.uid = orders.length; 
    return orders; 
    }, 
    save: function(orders) { 
    localStorage.setItem(STORAGE_KEY, JSON.stringify(orders)); 
    } 
}; 

組件

Vue.component('order', { 
    template: ` 
    <div> 
     <select v-model="selected"> 
     <option v-for="option in options" v-bind:value="option.value"> 
      {{ option.text }} 
     </option> 
     </select> 
     <input class="input" id="bags" v-model="bags" type="number" placeholder="Bags"> 
     <input class="input" id="amount" v-model="amount" type="number" placeholder="Amount"> 
     <button @click="$emit('remove')">Remove</button> 
    </div> 
    `, 
    props: { 
    bags: this.bags, // I must be doing this wrong 
    amount: this.amount 
    }, 
    data() { 
    return { 
     bags: null, 
     amount: null, 
     selected: null, 
     options: [{ 
     text: "Product (25kg)", 
     value: 25 
     }, { 
     text: "Product (50kg)", 
     value: 50 
     }, { 
     text: "Product (75kg)", 
     value: 75 
     }] 
    } 
    }, 
    watch: { 
    bags(newValue) { 
     this.amount = newValue * this.selected; 
    }, 
    amount(newValue) { 
     this.bags = newValue/this.selected; 
    } 
    } 
}); 

根Vue的實例

new Vue({ 
    el: '#app', 
    data: { 
    orders: orderStorage.fetch(), 
    bags: null, 
    amount: null, 
    }, 
    watch: { 
    orders: { 
     handler: function(orders) { 
     orderStorage.save(orders); 
     }, 
     deep: true 
    } 
    }, 
    methods: { 
    addProduct: function() { 
     this.orders.push({ 
     id: orderStorage.uid++, 
     bags: this.bags, // component.bags ? 
     amount: this.amount// component.amount? 
     }); 
     console.log(localStorage); 
    } 
    } 
}); 

HTML

<div id="app"> 
    <button @click="addProduct">Add</button> 

    <div class="orders"> 
    <order v-for="(order, index) in orders" :id="index" :key="order" @remove="orders.splice(index, 1)" :bags="bags" :amount="amount"></order> 
    </div> 
</div> 

例如:https://codepen.io/anon/pen/YVwxpz?editors=1010

回答

1

通常情況下,您不希望觸及組件以獲取其數據。你想要組件$emit它。 Vue通常是props down, events up

我修改了您的訂單組件以支持v-model。這允許組件的更改自動反映到父項中。

Vue.component('order', { 
    props:["value"], 
    template: ` 
    <div> 
     <select v-model="order.value"> 
     <option v-for="option in options" v-bind:value="option.value"> 
      {{ option.text }} 
     </option> 
     </select> 
     <input class="input" id="bags" v-model="order.bags" type="number" @input="onBags" placeholder="Bags"> 
     <input class="input" id="amount" v-model="order.volume" type="number" @input="onVolume" placeholder="Amount"> 
     <button @click="$emit('remove')">Remove</button> 
    </div> 
    `, 
    data() { 
    return { 
     options: [{ 
     text: "Product (25kg)", 
     value: 25 
     }, { 
     text: "Product (50kg)", 
     value: 50 
     }, { 
     text: "Product (75kg)", 
     value: 75 
     }], 
     order: this.value 
    } 
    }, 
    methods: { 
    onBags() { 
     this.order.volume = this.order.bags * this.order.value; 
     this.$emit("input", this.order) 
    }, 
    onVolume() { 
     this.order.bags = this.order.volume/this.order.value; 
     this.$emit("input", this.order) 
    } 
    } 
}) 

new Vue({ 
    el: '#app', 
    data: { 
    orders: orderStorage.fetch(), 
    }, 
    watch: { 
    orders: { 
     handler: orders => orderStorage.save(orders), 
     deep: true 
    } 
    }, 
    methods: { 
    addProduct: function(order) { 
     this.orders.push({ 
     id: orderStorage.uid++, 
     bags: 0, 
     volume: 0, 
     value: 25 
     }); 
    } 
    } 
}); 

這樣做,你不必通過bagsamount,你只是傳遞的順序。然後,當訂單改變時,修改後的訂單就會發出。

一個工作示例是here

此外,我將value屬性添加到您的order對象。如果你沒有保存,那麼你無法正確計算行李和音量的變化。

1

如果道具讓您感到困惑,請務必閱讀關於Composing Components的文章,其中討論了「支持道具,舉辦活動」的約定。

道具是從組件外部控制的數據。組件不應修改其道具(正如您在watch中所做的那樣,因爲您通過與v-model一起使用它們而隱式地進行操作)。

你可能想使組件data項目,你從道具初始化(給他們的道具名稱differerent名!),那麼你可以操縱這些值。

由於您希望父母知道對這些值所做的更改,因此發生更改時應該使用emit events。父母可以捕獲這些事件並採取適當的措施,例如將其保存到訂單對象和localStorage中。