Javascript Vuex将数组更新为对象的值

Javascript Vuex将数组更新为对象的值,javascript,arrays,vue.js,vuejs2,vuex,Javascript,Arrays,Vue.js,Vuejs2,Vuex,在稍微嵌套的数据结构中更新Vuex存储中的数据时遇到问题 我的整个项目比下面的要复杂一些,但我现在遇到的问题是经过简化和设置的,这样每个项目页面都会有一个登录页,其中包含表的可见性以及单个表组件,其中有一个Vuetify v-data-table元素,它只是将标题和项目作为道具,并显示它们。它可以以以下形式可视化: - Project Page |- Landing page |- Table Visibility |- Table Component |

在稍微嵌套的数据结构中更新Vuex存储中的数据时遇到问题

我的整个项目比下面的要复杂一些,但我现在遇到的问题是经过简化和设置的,这样每个项目页面都会有一个登录页,其中包含表的可见性以及单个表组件,其中有一个Vuetify v-data-table元素,它只是将标题和项目作为道具,并显示它们。它可以以以下形式可视化:

- Project Page
  |- Landing page
     |- Table Visibility
     |- Table Component
        |- v-data-table
一种思考方法如下: 对于每种动物(项目页面),有三种不同的品种/类型,每个品种/类型具有不同的特征。因此,上述结构将成为:

- Dog
  |- Landing page
     |- Table Visibility
     |- German Shepherd
        |- v-data-table
     |- Bull Terrier
        |- v-data-table
     |- Labrador Retriever
        |- v-data-table
- Cat
  |- Landing page
     |- Table Visibility
     |- Russian Blue
        |- v-data-table
     |- British Shorthair
        |- v-data-table
     |- Persian
        |- v-data-table
- Bird
  |- Landing page
     |- Table Visibility
     |- Cockatiel
        |- v-data-table
     |- Parrot
        |- v-data-table
     |- Macaw
        |- v-data-table
当用户导航到任何项目页面时,他或她将能够通过表可见性组件选择哪些表可以查看。此组件的外观如下所示:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export const debug = process.env.NODE_ENV !== 'production'

function initialState() {
  return {
    pageItems: {},
    pageHeaders: {},
    pageName: '',
    tableTitles: {
      Dog: ['German Shepherd', 'Bull Terrier', 'Labrador Retriever'],
      Cat: ['Russian Blue', 'British Shorthair', 'Persian'],
      Bird: ['Cockatiel', 'Parrot', 'Macaw']
    },
    tableVisibility: {
      Dog: {
        German Shepherd: false, 
        Bull Terrier: false, 
        Labrador Retriever: false
      },
      Cat: {
        Russian Blue: false,
        British Shorthair: false,
        Persian: false
      },
      Bird: {
        Cockatiel: false, 
        Parrot: false,
        Macaw: false
      }
    }
  }
}

const state = {...initialState()}

const mutations = {
  setTableVisbility(state, payload) {
    const page = payload.page;
    const tables = payload.tables;
    // Vue.set(state.tableVisibility, page, tables)
    state.tableVisibility[page] = Object.assign({}, tables);
  }
}

const getters = {
  getTableVisibility: (state) => ( state.tableVisibility[state.PageName] ),
  getCurrentPageTableTitles: (state) => ( state.tableTitles[state.pageName] ),
}
export default new Vuex.Store({state, mutations, getters, strict: debug})
const state = {
    pageName: '',
    projects: {
        '123': { id: '123', name: 'Dog' },
        '234': { id: '234', name: 'Cat' }
        // ...
    },
    tables: {
        '123z': { id: '123z', projectId: '123', name: 'German Shepherd', visible: false }
    }
}
TableVisibility.vue####->现在将tableTitles作为父组件的道具拉入 正如我所说,整个项目比这更复杂(我在这里显示的存储功能实际上是在一个模块中,等等),但我甚至无法在LandingPage.vue组件中获取tableVisibility的更新值。我正在尝试几种不同的方法,将deep处理程序应用于watcher(和);我尝试在存储区中拆分数组功能,方法是使用splice()清除数组,然后将所有元素推回数组中;我已经尝试使用filter array方法尝试创建一个新数组;我尝试将tableVisibility存储为一个对象(表名为键,值为true或false),以便使用object.assign();我发现了这个关于规范化数据()的页面,但它似乎并没有非常复杂到已经有点简单的程度

我正绞尽脑汁想弄清楚到底发生了什么事,我真的很感谢你的帮助

编辑
我已经更新了这个项目,使其包含getter,除了tableVisibility值之外,其他所有组件都在使用reactivity。我尝试将tableVisibility元素保留为数组,然后尝试将它们转换为对象,如本次编辑中所示,我尝试使用Vue.set更新值,但没有成功,然后尝试使用Object.assign,如当前版本所示。如果我离开某个页面,然后返回更新的值,那只是因为尽管我尝试使用Vue.set和Object.assign,但它们似乎正在失去反应性。

我给您的建议是开始考虑规范化数据。一些重大问题是:

  • 页面和表名在您的状态下完全是字符串硬代码。如果需要扩展页/表的数量,则会产生问题。
    tableVisibility
    也是如此
  • 您的状态是深度嵌套的,而您没有任何getter方法,这迫使您向Vue组件公开状态结构,这使得更新Vuex存储非常困难
首先,编写getter方法和变异方法;使它们足够通用,以便您可以在Vue组件中的任何位置重用,并强制所有Vue组件使用它们,而不是直接访问状态

例如:

const getters = {
    getCurrentActivePage: (state) => {}, // return pageName
    getProjects: (state) => {},
    getProjectById: (state) => (projectId) => {},
    getTablesOfProjects: (state) => (projectId) => {},
    getTable: (state) => (tableID) => {},
    isTableVisible: (state) => (tableID) => {}
}

const mutations = {
    setTableVisibility: (state, { tableID, newValue }) => {}
}
将UI逻辑与状态结构分离后,可以开始规范化状态数据。尝试将您的状态视为一个小型数据库,并对其进行逻辑设计。一种方法是:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export const debug = process.env.NODE_ENV !== 'production'

function initialState() {
  return {
    pageItems: {},
    pageHeaders: {},
    pageName: '',
    tableTitles: {
      Dog: ['German Shepherd', 'Bull Terrier', 'Labrador Retriever'],
      Cat: ['Russian Blue', 'British Shorthair', 'Persian'],
      Bird: ['Cockatiel', 'Parrot', 'Macaw']
    },
    tableVisibility: {
      Dog: {
        German Shepherd: false, 
        Bull Terrier: false, 
        Labrador Retriever: false
      },
      Cat: {
        Russian Blue: false,
        British Shorthair: false,
        Persian: false
      },
      Bird: {
        Cockatiel: false, 
        Parrot: false,
        Macaw: false
      }
    }
  }
}

const state = {...initialState()}

const mutations = {
  setTableVisbility(state, payload) {
    const page = payload.page;
    const tables = payload.tables;
    // Vue.set(state.tableVisibility, page, tables)
    state.tableVisibility[page] = Object.assign({}, tables);
  }
}

const getters = {
  getTableVisibility: (state) => ( state.tableVisibility[state.PageName] ),
  getCurrentPageTableTitles: (state) => ( state.tableTitles[state.pageName] ),
}
export default new Vuex.Store({state, mutations, getters, strict: debug})
const state = {
    pageName: '',
    projects: {
        '123': { id: '123', name: 'Dog' },
        '234': { id: '234', name: 'Cat' }
        // ...
    },
    tables: {
        '123z': { id: '123z', projectId: '123', name: 'German Shepherd', visible: false }
    }
}
其中,可以使用像nanoid这样的npm包自动生成id


即使没有规范化,我仍然建议您执行步骤1(解耦)。如果您的存储很复杂,您永远无法确定修改存储的状态是否会导致Vue组件崩溃。好的
getter
translations
至少会捕获无效数据并返回组件的默认值。

我的建议是开始考虑规范化数据。一些重大问题是:

  • 页面和表名在您的状态下完全是字符串硬代码。如果需要扩展页/表的数量,则会产生问题。
    tableVisibility
    也是如此
  • 您的状态是深度嵌套的,而您没有任何getter方法,这迫使您向Vue组件公开状态结构,这使得更新Vuex存储非常困难
首先,编写getter方法和变异方法;使它们足够通用,以便您可以在Vue组件中的任何位置重用,并强制所有Vue组件使用它们,而不是直接访问状态

例如:

const getters = {
    getCurrentActivePage: (state) => {}, // return pageName
    getProjects: (state) => {},
    getProjectById: (state) => (projectId) => {},
    getTablesOfProjects: (state) => (projectId) => {},
    getTable: (state) => (tableID) => {},
    isTableVisible: (state) => (tableID) => {}
}

const mutations = {
    setTableVisibility: (state, { tableID, newValue }) => {}
}
将UI逻辑与状态结构分离后,可以开始规范化状态数据。尝试将您的状态视为一个小型数据库,并对其进行逻辑设计。一种方法是:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
export const debug = process.env.NODE_ENV !== 'production'

function initialState() {
  return {
    pageItems: {},
    pageHeaders: {},
    pageName: '',
    tableTitles: {
      Dog: ['German Shepherd', 'Bull Terrier', 'Labrador Retriever'],
      Cat: ['Russian Blue', 'British Shorthair', 'Persian'],
      Bird: ['Cockatiel', 'Parrot', 'Macaw']
    },
    tableVisibility: {
      Dog: {
        German Shepherd: false, 
        Bull Terrier: false, 
        Labrador Retriever: false
      },
      Cat: {
        Russian Blue: false,
        British Shorthair: false,
        Persian: false
      },
      Bird: {
        Cockatiel: false, 
        Parrot: false,
        Macaw: false
      }
    }
  }
}

const state = {...initialState()}

const mutations = {
  setTableVisbility(state, payload) {
    const page = payload.page;
    const tables = payload.tables;
    // Vue.set(state.tableVisibility, page, tables)
    state.tableVisibility[page] = Object.assign({}, tables);
  }
}

const getters = {
  getTableVisibility: (state) => ( state.tableVisibility[state.PageName] ),
  getCurrentPageTableTitles: (state) => ( state.tableTitles[state.pageName] ),
}
export default new Vuex.Store({state, mutations, getters, strict: debug})
const state = {
    pageName: '',
    projects: {
        '123': { id: '123', name: 'Dog' },
        '234': { id: '234', name: 'Cat' }
        // ...
    },
    tables: {
        '123z': { id: '123z', projectId: '123', name: 'German Shepherd', visible: false }
    }
}
其中,可以使用像nanoid这样的npm包自动生成id


即使没有规范化,我仍然建议您执行步骤1(解耦)。如果您的存储很复杂,您永远无法确定修改存储的状态是否会导致Vue组件崩溃。好的
getter
translations
至少会捕获无效数据并返回组件的默认值。

Vue.set(state.tableVisibility,page,table)
:table应该是tables?这只是我在将代码从我的项目转录到这个更简单的项目时忘记修复的一个输入错误。现在编辑
Vue.set(state.tableVisibility,page,table)
:table应该是tables?这只是一个打字错误,我在将代码从我的项目转录到这个更简单的项目时忘记了纠正。谢谢你的帮助。我根据你的建议更新了项目(尽管我还没有将数据标准化),但它仍然会造成问题。第一篇文章中的代码已经更新,如果您能再看一看,我将不胜感激。没关系,上面所写的代码()可以正常工作。