VueJS组件系统架构

时间:2017-09-19 13:59:09

标签: javascript vue.js vuejs2 vue-component vuex

我正在努力实现的目标

我正在努力为我正在开发的应用程序找到一个好的架构。

如果你看一些screenshots of the current version of our application,你会看到各种格式的数据表格/列表。第二个屏幕截图中的表格有自己的导航。在某些情况下,可以选择表行。在其他屏幕中,可以在指定的关键字上过滤项目列表,依此类推。

前端将在VueJS中重建。我不想为每个特定的屏幕构建一次性组件,而是希望有一个更通用的解决方案,我可以在整个应用程序中使用它。

我需要的是一个组件系统,其中根包含一组数据,子项提供(可能是多个)该数据的表示。根组件还包含 - 主要是用户指定的 - 配置,过滤器和选择,用于控制表示。

我试图实现的目标最好用some pseudocode来说明。

问题

存储数据的最佳方法是什么?子组件应如何访问此数据?

将带有道具的data-display数据传递给每个孩子对我来说似乎很麻烦。特别是因为表示可以隐式访问这些数据。

我应该使用Vuex吗?如何处理data-display的多个实例?我读了一些关于动态模块注册的内容,这有用吗?

有更好的方法吗?非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

我不确定我是否掌握了您的要求的所有细节,但了解数据在多个页面中很常见'在SPA。 我肯定会推荐Vuex:

  • 所有页面的相同数据
  • 通过组件计算属性访问, 哪些是对商店更改的反应,但也缓存以保存 如果依赖项没有变化则重新计算
  • 在道具(向下传递)和事件(向上传递)中保存了大量可能复杂的数据传递

查看伪代码,侧边栏上有三种类型的过滤器。将该数据也放在商店中,然后视图上的计算属性可以将过滤器应用于数据。然后可以单独测试计算逻辑。

<强> child.vue

<template>
  <div>{{ myChildData.someProperty }}</div>
</template>

<script>
export default {
  props: [...],
  data: function () {
    return {
      selection: 'someValue'  // set this by, e.g, click on template
    }
  },
  computed: {
    myChildData() {
      return this.$store.getters.filteredData(this.selection)
    }
  }
}
</script>

<强> store.js

const state = {
  myData: {
    ...
  },
  filters: {  // set by dispatch from sidebar component
    keyword: ...,
    toggle: ...,
    range: ...
  },
}

const getters = {
  filteredData: state => {
    return childSelection => {  // this extra layer allows param to be passed
      return state.myData
       .filter(item => item.someProp === state.filters.keyword)
       .filter(item => item.anotherProp === childSelection)
    }
  },
}

const mutations = {
  'SET_DATA' (state, payload) {
    ...
  },
  'SET_FILTER' (state, payload) {
    ...
  }
}

export default {
  state,
  getters,
  mutations,
}

通用儿童

可能有很多方法可以解决这个问题。我使用了组合,这意味着每个孩子都使用一个通用组件的瘦组件,但只有当孩子有特定数据或一些可以放入插槽的唯一标记时,你才需要这个组件。

<强> child1.vue

<template>
  <page-common :childtype="childType">
    <button class="this-childs-button" slot="buttons"></button>
  </page-common>
</template>

<script>
import PageCommon from './page-common.vue'
export default {
  props: [...],
  data: function () {
    return {
      childType: 'someType'
    }
  },
  components: {
    'page-common': PageCommon,
  }
}
</script>

<强> 页-common.vue

<template>
  ...
  <slot name="buttons"></slot>
</template>

<script>
export default {
  props: [
    'childtype'
  ],
  data: function () {
    return {
      ...
    }
  },
}
</script>

多个数据实例

同样,许多变化 - 我使用了一个具有属性作为索引的对象,因此存储变为

<强> store.js

const state = {
  myData: {
    page1: ...,  // be sure to explicitly name the pages here
    page2: ...,  // otherwise Vuex cannot make them reactive
    page3: ...,
  },
  filters: {  // set by dispatch from sidebar component
    keyword: ...,
    toggle: ...,
    range: ...
  },
}

const getters = {
  filteredData: state => {
    return page, childSelection => {  // this extra layer allows param to be passed
      return state.myData[page]  // sub-select the data required
       .filter(item => item.someProp === state.filters.keyword)
       .filter(item => item.anotherProp === childSelection)
    }
  },
}

const mutations = {
  'SET_DATA' (state, payload) {
    state.myData[payload.page] = payload.myData
  },
  'SET_FILTER' (state, payload) {
    ...
  }
}

export default {
  state,
  getters,
  mutations,
}