vue分层项目架构搭建过程与踩过的坑

项目介绍:
公司已有saas项目,因为需求变动前后端都相应的做出架构调整,后端采用分层模式开发,要求每个模块可单独发布,可按客户需求单模块部署到客户服务器,所以前端的框架要求也要符合这个需求。

前端具体需求:
1、客户有自己的系统需要引入我们产品某一个模块,前提是客户的系统也是vue项目
2、客户没有自己的系统,需要我们某一个模块的整体可运行项目
3、客户自己的系统是非vue项目,引入我方产品模块

可行性分析:
需求1:vue项目引入我方模块,可采取疯转ui组件方式,供第三方 npm install 我方模块
把我方产品每个页面封装成一个组件,客户方只需建立的自己的router和对应的view层,view层页面只需放入组件
需求2:可将现有系统按模块拆分出多个子项目,每个项目都可publish和build,这样既能满足单独引入组件又可运行成为独立项目
需求3:可用需求2的方式,独立运行

架构目录思考:
由于一般vue项目的dist目录放置build后的文件,所以我在根目录先建立一个名为“package”目录用来放置npm run package后的文件
接下来是安排src下的目录
packages 目录 用来放置所有组件需要的资源和组件,npm run package会把此目录下的所有文件打包到根目录的package文件夹
view 目录 建立此子项目所有的路由支持页面,此目录vue开发最简单,只需要导入packages 目录下的组件放入页面就可以
router 目录 用于本项目独立运行的router设置
app.vue
main.js

packages目录下可自行安排,我先说说我自己的安排
components目录 放置所有组件 每个组件对应一个文件夹

每个目录都暴露一个Index.js,代码如下

import login from './login.vue'
// 可用于分组件引入,不做多解释
login.install = function (Vue) {
  Vue.component(login.name, login);
};
export default login

api目录 整理整个项目用到的所有请求地址,可暴露给第三方引用者灵活设置
libs目录 一些公用的js 其中axios封装采用的是iview-admin 项目中的封装方法,但是第一个坑也出现了,这个坑留到后面一起说,都是泪啊
styles目录 放所有的样式文件和样式需要的图片,这里也有坑,先挖出来 留在后面填
index.js

import './styles/index.less';
import login from './components/login/index.js'
const ydui = {
  login: login
}
const install = function (Vue, opts = {}) {
  Object.keys(ydui).forEach(key => {
    Vue.component(key, ydui[key]);
  });
  // 这里用于第三方设置本项目所有请求地址的url,
  // 因为是部署到第三方的服务器,所以这里要可灵活配置
  Vue.prototype.$YDUI = {
    baseUrl: opts.baseUrl || ''
  }
}

if (typeof window !== 'undefined' && window.Vue) {
  install(window.Vue);
}
const API = {
  install,
  ...ydui
}

export default API

踩过的坑:
整个框架搭建就是个坑坑洼洼过来的,前面的架构介绍现在总结起来看起来很简单,但这也是一个一个坑踩过来,整个过程不多说了,先说几个影响比较大的坑也是我费尽千辛万苦踩爬出来的

1、baseUrl问题,iview-admin 封装axios具体做法 自行查看
libs/api.request.js的修改

import HttpRequest from './axios'
import Vue from 'vue'
// 判断第三方是否设置了此组件暴露的全局属性,没有的话就用我方自己的url
let baseUrl = Vue.prototype.$YDUI : Vue.prototype.$YDUI.baseUrl ? '我方自己的url'
const axios = new HttpRequest(baseUrl)
export default axios

写完也一直没测试,我还觉得挺完美的,可在一个新项目引入此组件时问题就出来了,新项目引入和设置方法如下:

import ydcommon from 'yd-common'
import 'yd-common/package/ydcommon.min.css'
Vue.use(ydcommon, {
  baseUrl: 'http://gateway.dev.com'
})

悲剧的是,我的请求地址无法获取此设置的url,然后我就开始各种实验,在axios的拦截器里获取、自写wacth等方法都试过了,这个问题一直研究了半天,后来静下来又查看了iview-ui的源码才想明白了一个道理,iview-ui也有通用设置,但是他们获取通用设置的地方都是在vue组件内,想了想也就了然了,我封装的axios是在外部js里,先于vue运行,是无法获取后面设置的属性的,所以我就转变了个思路,让这个设置在组件里运用就能生效 所以libs/api.request.js我做了以下修改

const axios = function (api) {
    let url = api ? api : '我方url'
    return new HttpRequest(url)
}
export default axios

在组件里调用时要传参:

axios(this.$YDUI.baseUrl).request()

测试通过,长出了一口气,不管解决方法优雅不优雅吧,总算是解决了

2、图片不显示问题

上面的问题解决了 刚高兴了没一会,突然发现我组件中的大背景图都没出现,一开始没注意以为不是什么大事,可现在有时间研究了才发现不知道咋解决,尴尬不 -_-||
首先着手的是查看路径问题,因为在导出的icon都被转换成了base64码,所以对目录不对的问题就产生了怀疑,webpack设置里output.publishPath 我大胆尝试,有一次修改完测试直接黑屏报路径错误,所以之前对路径错误的怀疑直接否掉了,路径真错的话肯定会报错。
开始了我的baidu之旅,结果搜不到。。。是真的搜不到关于我的问题一点都没有,获取知识的主要途径断了我就开始了各种技术群 找大佬问,估计大佬们都日理万机没人理我,有几个理我的 也说不出个所以然来,但是我也不能停下我的各种尝试。
DuangDuangDuang。。。我擦,解决了!要问我咋解决的我只能说瞎猫碰死耗子,我只能把修改的地方放出来

module.exports = {
  entry: {
    'ydcommon': './src/packages/index.js'
  },
  output: {
    path: path.resolve(__dirname, '../package'),
    publicPath: './',
    library: 'ydcommon',
    libraryTarget: 'umd',
    umdNamedDefine: true
  }

其实这还有个坑,css的background里的图片都能显示了,但是在组件里的标签中的图片无法显示,只能把这些地方改用css写来规避了,能力有限只能取巧。

放出gitHub地址yd-cmmon,喜欢别忘了star,多多交流

发布了1 篇原创文章 · 获赞 1 · 访问量 134

猜你喜欢

转载自blog.csdn.net/zxcqq1985/article/details/104926922