VueJS从根Vue实例中的组件访问数据

时间:2017-04-19 16:04:12

标签: javascript vue.js local-storage

我试图在我的根Vue实例中访问组件的数据。我想要完成的是,你点击一个按钮,就会出现一组输入。每组输入都是localStorage中自己的对象,包含密钥id,包和金额。当我更新一组输入时,它们的值应该在localStorage中更新。我无法弄清楚如何访问我的组件的数据包和金额。我认为我应该使用的是道具,因为这是我在React中使用的。但是,我在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;
    }
  }
});

Root 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

2 个答案:

答案 0 :(得分:2)

通常,您不希望进入组件以获取其数据。您希望组件Guid g = Guid.NewGuid(); Images.SaveAs(Server.MapPath("~/Uploads/" + g + ".jpg")); fileNames = g.ToString() + ".jpg"; 。 Vue通常是props down, events up

我修改了您的订单组件以支持$emit。这允许对组件的更改自动反映在父组件中。

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 }); } } }); bags,只需传递订单即可。然后,当订单发生变化时,会发出修改后的订单。

一个工作示例是here

此外,我将amount属性添加到您的value对象中。如果您不保存,则无法正确计算行李和音量的变化。

答案 1 :(得分:1)

如果道具让您感到困惑,请务必阅读Composing Components,其中介绍了&#34;支持&#34;支持事件&#34;约定。

道具是从组件外部控制的数据。该组件不应对其道具进行修改(正如您在watch中所做的那样,并且正如您在v-model中使用它们所隐含的那样)。

您可能希望从道具中创建初始化的组件data项(给它们命名与道具名称不同!)然后您可以操作这些值。

由于您希望父级知道值的更改,因此您应该在发生更改时emit events。父级可以捕获这些事件并采取适当的操作,例如将它们保存到订单对象和localStorage。

相关问题