【问题标题】:VueJS component system architectureVueJS组件系统架构
【发布时间】:2018-02-28 08:35:49
【问题描述】:

我想要完成的事情

我正在尝试为我正在开发的应用程序找出一个好的架构。

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

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

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

some pseudocode 最好地说明了我想要实现的目标。

问题

存储数据的最佳方式是什么?子组件应该如何访问这些数据?

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

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

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

【问题讨论】:

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


    【解决方案1】:

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

    • 所有页面的数据相同
    • 通过组件计算属性访问, 它们对存储更改是反应性的,但也会缓存以保存 如果依赖项没有变化,则重新计算
    • 在 props(向下传递)和 events(向上传递)中节省了大量潜在的复杂数据传递

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

    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>
    

    page-common.vue

    <template>
      ...
      <slot name="buttons"></slot>
    </template>
    
    <script>
    export default {
      props: [
        'childtype'
      ],
      data: function () {
        return {
          ...
        }
      },
    }
    </script>
    

    多个数据实例

    同样,有很多变体——我使用了一个带有属性的对象作为索引,所以 store 变成了

    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,
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-17
      • 2022-08-20
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多