VueJS 从根 Vue 实例中的组件访问数据
Posted
技术标签:
【中文标题】VueJS 从根 Vue 实例中的组件访问数据【英文标题】:VueJS accessing data from component in root Vue instance 【发布时间】:2017-09-15 23:33:21 【问题描述】:我正在尝试访问我的根 Vue 实例中的组件数据。我想要完成的是,您单击一个按钮并出现一组输入。每组输入都是 localStorage 中自己的对象,具有键 id、bags 和 amount。当我更新一组输入时,它们的值应该在 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;
);
根 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);
);
<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
);
);
这样做,您不必传递bags
和amount
,只需传递命令即可。然后,当订单发生变化时,会发出修改后的订单。
一个工作示例是here。
此外,我将value
属性添加到您的order
对象中。如果不保存,则无法正确计算袋子和体积的变化。
【讨论】:
【参考方案2】:如果 props 让您感到困惑,请务必阅读 Composing Components,其中谈到了“props down, events up”的约定。
道具是从组件外部控制的数据。组件不应修改其 props(就像您在 watch
中所做的那样,以及您在 v-model
中使用它们时隐式所做的那样)。
您可能希望从道具中初始化组件data
项目(给它们起与道具名称不同的名称!)然后您可以操纵这些值。
由于您希望父级知道值的更改,因此您应该在发生更改时emit events。父级可以捕获这些事件并采取适当的措施,例如将它们保存到订单对象和 localStorage。
【讨论】:
以上是关于VueJS 从根 Vue 实例中的组件访问数据的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Vue 类组件访问 VueJS 3 和 Typescript 中的 HTML 引用?