完整的逻辑与Vuex解耦

时间:2018-03-12 06:31:47

标签: vue.js vue-router vuex

我正在用Vue Router和Vuex构建一个Vue Web应用程序,使用vue-cli构建脚手架。大多数项目结构非常简单,有一个主存储和简单的路由:

project/
├── src/
│   ├── components/
│   │    ├── Hosting/
│   │    └── Website/
│   ├── router/
│   ├── store/
│   ├── App.vue
│   └── main.js
└── index.html

Hosting路由的/hosting组件需要与网站的其他部分分离。该URL将托管将使用<iframe>加载到其他网站的组件。实现这种逻辑解耦的最佳方法是什么?我想过在store文件夹中包含一个Hosting目录,但不知道如何将其注入Hosting根组件。我查看了使用modules,但这并没有真正实现我想要的,因为所有模块都可以从每个组件访问。

请注意,我实际上并不需要/hosting端点使用与网站其余部分相同的路由,因为它只能作为src的{​​{1}}进行访问}。因此,如果我需要对webpack如何编译项目做一些事情(比如创建<iframe>目标除了hosting.html),我就可以做到。

2 个答案:

答案 0 :(得分:1)

你可以考虑Joachim给你的答案,我的意思是拆分为2个应用程序,我在我的应用程序上做这个(在webpack上提供配置)

webpack.config.js

...
entry: {
    './app-1.js': './src/app1/main.js',
    './app-2.js': './src/app2/main.js'
  },
  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/build/',
    filename: '[name]'
  },
...

如果您需要从两个应用程序访问同一个商店,我认为您应该重新考虑vuex中的模块解决方案。我将我的商店拆分为模块并在每个应用程序中加载所需的模块(在beforeCreate生命周期钩子中的App.vue中)。看起来像这样:

main1.js

import Vue from 'vue'
import App from './App.vue'
import { store } from '../store/store';

new Vue({
  el: '#app2',
  store: store,
  render: h => h(App)
});

main2.js

import Vue from 'vue'
import App from './App.vue'
import { store } from '../store/store';

new Vue({
  el: '#app1',
  store: store,
  render: h => h(App)
});

(请注意两个应用加载相同的商店)然后:

App1.vue

export default {
...
    beforeCreate() {
      // this is where we add dynamically specific modules used on this app.
      const store = this.$store;
      const modulesToBoDynamicallyRegistered = {
        [Types.module1.TYPE_NAME]:         module1,
        [Types.module2.TYPE_NAME]:         module2,
        [Types.module3.TYPE_NAME]:         module3,
        [Types.module4.TYPE_NAME]:         module4,
      };

      Object.keys(modulesToBoDynamicallyRegistered).forEach((moduleName) => {
        utils.registerModuleIfNotExists(store, moduleName, modulesToBoDynamicallyRegistered[moduleName]);
      });
    },
...
}

App2.vue

export default {
...
    beforeCreate() {
      // this is where we add dynamically specific modules used on this app.
      const store = this.$store;
      const modulesToBoDynamicallyRegistered = {
        [Types.module7.TYPE_NAME]:         module7,
        [Types.module9.TYPE_NAME]:         module9,
      };

      Object.keys(modulesToBoDynamicallyRegistered).forEach((moduleName) => {
        utils.registerModuleIfNotExists(store, moduleName, modulesToBoDynamicallyRegistered[moduleName]);
      });
    },
...
}

商店本身拥有通用模块:

store.js

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

import module5 from './modules/module5/index';
import module6 from './modules/module6/index';

Vue.use(Vuex);

export const store = new Vuex.Store({
  modules: {
    module5,
    module6,
  }
});

如果您需要registerModuleIfNotExists功能:

registerModuleIfNotExists: (store, moduleName, module) => {
    if (!(store && store.state && store.state[moduleName])) {
        store.registerModule(moduleName, module);
      } else {
        // re-use the already existing module
        throw `reusing module: ${moduleName}`;
      }
  },

答案 1 :(得分:0)

将托管组件视为一个完全独立的应用程序,您可以自由地将其托管在其他网站上。是的,创建一个hosting.html页面以显示在iframe和其他网站中。

这将使您自己对组件的使用与其在其他网站上托管的方式完全一致,并且还可以更轻松地查找错误。

您没有提及托管组件是否需要来自包含结构的任何数据或参数,但如果是这样,您应该在hosting.html的查询字符串中提供此内容。