【发布时间】:2020-03-21 22:28:25
【问题描述】:
我正在尝试使用 Vue 和 Electron 构建一个简单的任务管理应用程序。我的设置基于带有 Vuex 商店的 electron-vue boilerplate。 用户可以通过模式向列表中添加新项目(并编辑现有项目)。 modal 将信息发送到 store 操作,然后调用突变来更新 store 并将新项目推送到列表项数组。
这是设置:LayerItem 是 Layer 的子代LayerMap 的子代。数据从父 LayerMap 组件中的 store 接收,然后通过 props 提供给子组件。
重现问题:通过showEditItemDialog 中的Layer 组件创建一个新项目。在 SAVE_LAYER_ITEM 突变中,将创建一个新 ID 并将其分配给该新项目。之后,新项目将被推送到layer.items 数组。 UI 将被更新并且创建的项目是可见的。 item.text 显示正确。然而item.id 是不同的。我在突变中包含了console.log。记录的 id 与LayerItem 组件中的 UI 中显示的 id 不匹配,此处为 <p>{{ item.id }}</p>。因此,当在创建新项目后尝试编辑/更新新项目时,突变将创建一个新项目,而不是更新现有项目,因为在存储数组中找不到模式接收的 ID。
我知道代码很多,我尝试尽可能多地删除不必要的代码。在下面的示例中,我创建了一个新项目“test”,您可以看到存储的 ID 与 UI 中显示的 ID 不匹配。
LayerMap.vue
// 'layers' is a computed property and gets data from the store
<draggable
v-model="layers"
v-bind="getDragOptions"
>
<Layer v-for="(layer, index) in layers" :key="index" :layer="layer"></Layer>
</draggable>
<DetailsModal></DetailsModal>
// Inside computed
computed: {
layers() {
return this.$store.getters.allLayers
}
}
图层.vue
// 'layer' gets passed from parent as prop
<span primary-focus @click="showEditItemDialog">Add Item</span>
<draggable v-model="items" v-bind="dragOptions" class="items">
<LayerItem v-for="item in items" :item="item" :layer="layer" :key="item.id"></LayerItem>
</draggable>
// 'items' is a computed property
items: {
get() {
return this.layer.items
}
}
// Function to handle 'Add Item' click and send event which will be handled by DetailsModal.vue
methods: {
showEditItemDialog() {
let payload = {
layer: this.layer,
item: {
id: '',
text: ''
}
}
this.$bus.$emit('item-editing', payload)
}
}
LayerItem.vue
// Layer Item Component
<div class="layer-item" @click.prevent="startEditing">
<div class="item-body">
<p>{{ this.item.text }}</p>
<p>{{ item.id }}</p>
</div>
</div>
// Event will be sent on click with layer item details as parameter
methods: {
startEditing() {
let payload = {
layer: this.layer,
item: {
id: this.item.id,
text: this.item.text
}
}
this.$bus.$emit('item-editing', payload)
}
}
}
DetailsModal.vue
// 'editLayerForm' contains layer item id and text
<p>{{editLayerForm.id}}</p>
<div class="bx--form-item">
<input
type="text"
v-model="editLayerForm.text"
/>
</div>
// Inside <script>, event is received and handled, 'editLayerForm' will be updated with payload information
mounted() {
this.$bus.$on('item-editing', this.handleModalOpen)
},
methods: {
handleModalOpen(payload) {
this.layer = payload.layer
this.editLayerForm.id = payload.item.id
this.editLayerForm.text = payload.item.text
this.visible = true
console.log('editing', payload)
},
handleModalSave() {
let payload = {
layerId: this.layer.id,
item: {
id: this.editLayerForm.id,
text: this.editLayerForm.text
}
}
console.log('save', payload)
this.$store.dispatch('saveLayerItem', payload)
}
}
Store.js
const actions = {
saveLayerItem: ({ commit }, payload) => {
console.log('action item id', payload.item.id)
commit('SAVE_LAYER_ITEM', payload)
}
}
const mutations = {
SAVE_LAYER_ITEM: (state, payload) => {
let layer = state.map.layers.find(l => l.id === payload.layerId)
let itemIdx = layer.items.findIndex(item => item.id === payload.item.id)
console.log('mutation item id', payload.item.id)
if (itemIdx > -1) {
// For existing item
console.log('update item', payload.item)
Vue.set(layer.items, itemIdx, payload.item)
} else {
// For new item
payload.item.id = guid()
console.log('save new item', payload.item)
layer.items.push(payload.item)
}
}
}
【问题讨论】:
-
代码太多 :) ...您正在谈论您的
Layer Item Component显示错误id(顺便说一句,文本呢?)但item通过道具传递给组件。所以使用组件的代码(并传入项目)会更有趣(也许你的组件显示完全不同的项目?) -
@MichalLevý 感谢您的回复。我试图更新我的问题,删除不必要的代码并包含父组件。你知道出了什么问题吗?
-
还没有。
LayerItem.vue中的{{ this.item.text }}是真的吗? -
第一步。确认商店中
id的值 - 它是原始(记录)id还是id,如您的LayerItem.vue组件所示?使用 Vue 开发工具... -
@MichalLevý 再次感谢您的帮助!非常感谢!是的,
this.item.text显示了正确的值(我更新了原始问题中的文本)。使用 Vue 开发工具,商店会显示来自LayerItem.vue的值,而不是商店突变记录的值。
标签: javascript vue.js vuejs2 electron vuex