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

Javascript VueJS从根Vue实例中的组件访问数据,javascript,vue.js,local-storage,Javascript,Vue.js,Local Storage,我正在尝试访问根Vue实例中的组件数据。我想完成的是,你点击一个按钮,就会出现一组输入。每一组输入在localStorage中都是它自己的对象,具有密钥id、bags和amount。当我更新一组输入时,它们的值应该在localStorage中更新。我很难弄清楚如何访问我的组件的行李和数量数据。我想我应该用的是道具,因为这就是我在《反应》中使用的道具。但是,我还不太习惯在Vue中使用它们 以下是我到目前为止的情况: var STORAGE_KEY = "orders"; var orderSto

我正在尝试访问根Vue实例中的组件数据。我想完成的是,你点击一个按钮,就会出现一组输入。每一组输入在localStorage中都是它自己的对象,具有密钥id、bags和amount。当我更新一组输入时,它们的值应该在localStorage中更新。我很难弄清楚如何访问我的组件的行李和数量数据。我想我应该用的是道具,因为这就是我在《反应》中使用的道具。但是,我还不太习惯在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;
    }
  }
});
HTML


添加

示例:

如果道具让您感到困惑,请务必阅读关于“道具下降,事件上升”约定的内容

道具是从组件外部控制的数据。组件不应修改其道具(正如您在
手表中所做的,以及您在
v-model
中使用道具时所做的)

您可能希望使组件
数据
项从道具中初始化(使它们的名称与道具名称不同!),然后可以操作这些值


因为您希望父级知道值的更改,所以应该在发生更改时进行更改。父级可以捕获这些事件并采取适当的操作,例如将它们保存到order对象和localStorage。

通常,您不希望接触组件以获取其数据。您想让组件发射它。Vue通常是

我已修改您的订单组件以支持
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
      });
    }
  }
});
Vue.component('order'){
道具:[“价值”],
模板:`
{{option.text}
去除
`,
数据(){
返回{
选项:[{
正文:“产品(25公斤)”,
价值:25
}, {
正文:“产品(50kg)”,
价值:50
}, {
正文:“产品(75公斤)”,
价值:75
}],
顺序:这个值
}
},
方法:{
onBags(){
this.order.volume=this.order.bags*this.order.value;
this.$emit(“输入”,this.order)
},
onVolume(){
this.order.bags=this.order.volume/this.order.value;
this.$emit(“输入”,this.order)
}
}
})
新Vue({
el:“#应用程序”,
数据:{
订单:orderStorage.fetch(),
},
观察:{
订单:{
处理程序:orders=>orderStorage.save(订单),
深:是的
}
},
方法:{
addProduct:功能(订单){
这个,命令,推({
id:orderStorage.uid++,
行李:0,
卷:0,
价值:25
});
}
}
});
这样做,您不必传递
行李
金额
,只需传递订单即可。然后,当顺序更改时,将发出修改后的顺序

一个有效的例子是

此外,我将
属性添加到
订单
对象中。如果不保存,则无法正确计算行李和体积的变化

<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>
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
      });
    }
  }
});