支持特性

  • 开发模式 Webpack 内存编译,热更新,DLL构建,Cache 和多进程编译

  • 支持服务端渲染和前端渲染模式

页面入口

说明:app/web/page 为页面入口
参考:https://github.com/easy-team/ves-admin/blob/master/app/web/page/admin/home/index.ts

import App from 'framework/app'; // 见下面 framework 介绍
import createStore from '../../store/index';
import createRouter from './router/index';
import entry from './view/home/index.vue';
export default new App({ entry, createStore, createRouter }).bootstrap();

Framework

说明:当前 app.ts 可以作为参考,自己根据需求可以修改, 后续考虑发布为独立的 npm 插件
参考:https://github.com/easy-team/ves-admin/blob/master/app/web/framework/app.ts

// ${root}/app/web/framework/app.ts

import Vue from 'vue';
import { sync } from 'vuex-router-sync';

export default class App {
  config: any;
  constructor(config) {
    this.config = config;
  }

  bootstrap() {
    if (EASY_ENV_IS_NODE) {
      return this.server();
    }
    return this.client();
  }

  create(initState) {
    const { entry, createStore, createRouter } = this.config;
    const store = createStore(initState);
    const router = createRouter();
    sync(store, router);
    return {
      router,
      store,
      render: h => { // not use ...entry, why ?
        return h(entry);
      },
    };
  }

  fetch(vm): Promise<any> {
    const { store, router } = vm;
    const matchedComponents = router.getMatchedComponents();
    if (!matchedComponents) {
      return Promise.reject('No Match Component');
    }
    return Promise.all(
      matchedComponents.map((component: any) => {
        const options = component.options;
        // 自动 fetch
        if (options && options.methods && options.methods.fetchApi) {
          return options.methods.fetchApi.call(component, { store, router, route: router.currentRoute });
        }
        return null;
      })
    );
  }

  client() {
    Vue.prototype.$http = require('axios');
    const vm = this.create(window.__INITIAL_STATE__);
    // 自动 fetch
    vm.router.afterEach(() => {
      this.fetch(vm);
    });
    const app = new Vue(vm);
    app.$mount('#app');
    return app;
  }

  server() {
    return context => {
      // store 实例必须以函数返回且在 render context 内部创建 ,否则容易造成单例问题
      const vm = this.create(context.state);
      const { store, router } = vm;
      router.push(context.state.url);
      return new Promise((resolve, reject) => {
        router.onReady(() => {
          this.fetch(vm).then(() => {
            context.state = store.state;
            return resolve(new Vue(vm));
          });
        });
      });
    };
  }
}

Vuex 使用

说明:store 实例必须以函数返回且在 render context 内部创建 ,否则容易造成单例问题
参考:https://github.com/easy-team/ves-admin/blob/master/app/web/page/store/index.ts

import Vue from 'vue';
import Vuex from 'vuex';
import RootState from './state';
import Admin from './modules/admin';

Vue.use(Vuex);

// 这里必须已函数的方式返回 store 实例,否则容易造成单例问题
export default function createStore(initState: any = {}) {
  const { title, url, origin, locale, csrf, admin } = initState;
  const state = { title, url, origin, locale, csrf };
  return new Vuex.Store<RootState>({
    state,
    modules: {
      admin: new Admin(admin)
    }
  });
}

TypeScript

Vue TypeScript 支持建议使用 vue-property-decoratorvuex-class 插件

  • 类型声明
// ${root}/app/web/typings/global.d.ts
declare var window: Window;
declare var EASY_ENV_IS_NODE: boolean;

interface Window {
  __INITIAL_STATE__: any;
}

// ${root}/app/web/typings/vue-shims.d.ts
declare module '*.vue' {
  import Vue from 'vue';
  export default Vue;
}

参考示例


Author: sky
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source sky !
 Previous
项目配置 项目配置
应用项目规范除了基础配置文件和特殊声明的文件外,所有代码文件已 .ts 作为后缀名详细情况请参考 https://github.com/easy-team/ves-admin 骨架项目规范               项目整体结构 ...
2019-12-23 sky
Next 
本地开发调试 本地开发调试
Node 调试ves debug 启动应用然后复制   chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9999/__ws_proxy__    到...
2019-12-23 sky