博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
如何构建Vue大型应用
阅读量:5948 次
发布时间:2019-06-19

本文共 3352 字,大约阅读时间需要 11 分钟。

Observable模式的MVVM让Vue在中小型Web应用中有天然的优势,但随着Vue的流行度日益增长,Vue在大型项目中的运用略显捉襟见肘。显然在高复杂度项目中,类型检查已成必需要素,而Vue2在TypeScript的类型检查支持又不够彻底,更重要的是Vuex的状态逻辑的模块化设计欠缺。

所以这里提出以下解决方案:

  • 业务逻辑模块化 - 将解决模块化这个重要问题
  • TypeScript - vue-cli3
  • TSX - 更好的模版类型推导
  • 依赖注入 - 目前最好的DI库inversify
  • 分包 - 使用lerna构建Monorepo

lerna初始化后,进行领域驱动设计,得到大的领域模块。在必要情况下,将可以进行分包,同时启用动态import懒加载或者是RequireJS等模块加载器,以提高构建时性能和运行性能。

在核心应用子项目的初始化使用vue-cli3建构,选择TypeScript作为主要语言,它将自动引入Webpack的ts-loder。

这是核心目录结构:

|-- App.vue|-- main.ts+-- modules/  |-- Todos/  |-- Navigation/  |-- Portal/  |-- Counter/  ...+-- lib/  |-- loader.ts  |-- moduleConnect.ts  ...+-- components/...复制代码

main.ts是默认的entry。

// ...// omit some modulesimport { load } from './lib/loader';const {  portal,  app,} = load({  bootstrap: 'Portal',  modules: {    Counter,    Todos,    Portal,    Navigation  },  main: App,  components: {    home: {      screen: TodosView,      path: '/',      module: 'todos',    },    counter: {      screen: CounterView,      path: '/counter',      module: 'counter',    },  }});Vue.prototype.portal = portal;new Vue(app).$mount("#app");复制代码

App.vue是主视图文件。

复制代码

modules包含全部的业务逻辑,也包括视图层状态和导航模块等,它将由Vuex来启动。 例如以下是Counter模块:

import { injectable } from "inversify";import Module, { state, action, computed } from "../../lib/baseModule";@injectable()export default class Counter extends Module {  @state count: number = 0;  @action  calculate(num: number, state?: any) {    state.count += num;  }  getViewProps() {    return {      count: this.count,      calculate: (num: number) => this.calculate(num)    }  }}复制代码

lib/loader.ts是应用配置加载器。

import { Container } from 'inversify';export function load(parmas: any = {}) {  const { bootstrap, modules, ...option } =  parmas;  const container = new Container({ skipBaseClassChecks: true });  Object.keys(modules).forEach(key => {    container.bind(key).to(modules[key]);  });  container.bind("AppOptions").toConstantValue(option);  const portal: any = container.get(bootstrap);  portal.bootstrap();  const app = portal.createApp();  return {    portal,    app,  };}复制代码

lib/moduleConnect.ts是ViewModule的View连接器。 这是一个高阶组件的连接器。

import { Component, Vue } from "vue-property-decorator";export default (ViewContainer: any, module: string) => {  @Component({    components: {      ViewContainer    }  })  class Container extends Vue {    get module() {      return this.portal[module];    }    render(createElement: any) {      const props = this.module.getViewProps();      return createElement(ViewContainer, {        props      })    }  }  return Container;}复制代码

components/Counter/index.tsx是Counter的组件。

import { Component, Vue, Prop } from "vue-property-decorator";import './style.scss';type Calculate = (sum: number) => void;@Componentexport default class CounterView extends Vue {  @Prop() count!: number;  @Prop(Function) calculate!: Calculate;   render(){    return (      
{this.count}
) }}复制代码

配合TSX的View组件模块,同时基于此架构等整体设计将很大程度上契合TypeScript的类型检查和推导。

在该Vue架构中最核心的设计部分应该是usm-vuex,它让Vuex进行业务模块化变得简单明了,配合View层的ViewModule,它能够让当前的架构设计变得高内聚低耦合,在复用性与维护性上大大提高,同时配合依赖注入(dependency injection),让模块间的依赖变得清晰易懂。对于现实中的大型应用还有很多其他细节部分待完善,这里就不敷述了。

usm-vuex Repo:

本文的架构完整Demo:

转载地址:http://jqdxx.baihongyu.com/

你可能感兴趣的文章
Spring MVC整合Velocity
查看>>
fiddler+android抓包工具配置使用
查看>>
Spring Data JPA 复杂/多条件组合分页查询
查看>>
css文本 颜色1
查看>>
博客搬家了
查看>>
JavaScript中的作用域,闭包和上下文
查看>>
Python中使用ElementTree解析xml
查看>>
Python LOGGING使用方法
查看>>
Dominating Patterns
查看>>
截取指定字符串
查看>>
metrics-server最新版本有坑,慎用
查看>>
linux虚拟文件系统浅析
查看>>
HBase数据压缩编码探索
查看>>
sprint计划会议总结
查看>>
团队项目冲刺1
查看>>
fon循环总是返回最后值问题
查看>>
Android新权限机制 AppOps
查看>>
“蓝桥杯”软件大赛入门训练4道题
查看>>
Unable to get the CMake version located at
查看>>
爬虫基本原理
查看>>