Browse Source

feat: first commit

master
domsgit 6 years ago
commit
37b63f1c0e
18 changed files with 7377 additions and 0 deletions
  1. 3
      .browserslistrc
  2. 21
      .gitignore
  3. 41
      README.md
  4. 23
      package.json
  5. BIN
      public/favicon.ico
  6. 17
      public/index.html
  7. 32
      src/App.vue
  8. 10
      src/api/index.js
  9. BIN
      src/assets/logo.png
  10. 57
      src/components/HelloWorld.vue
  11. 95
      src/main.js
  12. 5
      src/public-path.js
  13. 25
      src/router/index.js
  14. 76
      src/utils/request.js
  15. 5
      src/views/About.vue
  16. 22
      src/views/Home.vue
  17. 52
      vue.config.js
  18. 6893
      yarn.lock

3
.browserslistrc

@ -0,0 +1,3 @@
> 1%
last 2 versions
not dead

21
.gitignore

@ -0,0 +1,21 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

41
README.md

@ -0,0 +1,41 @@
# 微前端、微应用
## 作为单独项目开始
```bash
yarn serve
```
## 接入主服务
将下面的路由接入主服务中:
```js
import { RouteView } from '@/layouts'
// 测试微前端
export default {
path: '/testMicro/index',
component: RouteView,
name: 'testMicro',
redirect: '/testMicro',
meta: { title: '测试微前端', keepAlive: false },
children: [
{
path: '/testMicro',
name: 'testMicroHome',
meta: { title: '测试微前端home', keepAlive: true, icon: 'home', hiddenHeaderContent: true }
},
{
path: '/testMicro/about',
name: 'testMicroAbout',
meta: { title: '测试微前端about', keepAlive: true, icon: 'home', hiddenHeaderContent: true }
},
]
}
```
## 编译
```bash
yarn build
```

23
package.json

@ -0,0 +1,23 @@
{
"name": "test-micro",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"ant-design-vue": "^1.5.6",
"axios": "^0.19.2",
"utils": "^1.5.0",
"vue": "^2.6.11",
"vue-router": "^3.1.6"
},
"devDependencies": {
"@vue/cli-plugin-router": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"vue-template-compiler": "^2.6.11"
}
}

BIN
public/favicon.ico

Before After

17
public/index.html

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

32
src/App.vue

@ -0,0 +1,32 @@
<template>
<div id="app">
<!-- <div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div> -->
<router-view :key="(new Date()).getTime()" />
</div>
</template>
<style scoped lang="less">
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
</style>

10
src/api/index.js

@ -0,0 +1,10 @@
import { axios } from '@/utils/request'
// 测试接口
export function test (parameter) {
return axios({
url: '/department/getDepartmentList',
method: 'get',
params: parameter
})
}

BIN
src/assets/logo.png

Before After
Width: 200  |  Height: 200  |  Size: 6.7 KiB

57
src/components/HelloWorld.vue

@ -0,0 +1,57 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

95
src/main.js

@ -0,0 +1,95 @@
import Vue from 'vue'
import "./public-path";
import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
Vue.use(VueRouter)
Vue.config.productionTip = false
let instance = null;
let router = null;
/**
* 渲染函数
* 两种情况主应用生命周期钩子中运行 / 微应用单独启动时运行
*/
function render(props = {}) {
const { container } = props;
// 在 render 中创建 VueRouter,可以保证在卸载微应用时,移除 location 事件监听,防止事件污染
router = new VueRouter({
// 运行在主应用中时,添加路由命名空间 /vue
base: window.__POWERED_BY_QIANKUN__ ? "/testMicro" : process.env.BASE_URL,
mode: "history",
routes,
});
// 挂载应用
instance = new Vue({
router,
render: h => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时,直接挂载应用
if (!window.__POWERED_BY_QIANKUN__) {
render()
}
function storeTest(props) {
props.onGlobalStateChange &&
props.onGlobalStateChange(
(value, prev) => {
console.log(`[qiankun testMicro]: [onGlobalStateChange - ${props.name}]:`, value, prev)
localStorage.setItem('pro__Access-Token', JSON.stringify((value || {}).token || {}))
},
true,
);
// props.setGlobalState &&
// props.setGlobalState({
// ignore: props.name,
// user: {
// name: props.name,
// },
// });
}
/**
* bootstrap 只会在微应用初始化的时候调用一次下次微应用重新进入时会直接调用 mount 钩子不会再重复触发 bootstrap
* 通常我们可以在这里做一些全局变量的初始化比如不会在 unmount 阶段被销毁的应用级别的缓存等
*/
export async function bootstrap() {
console.log('[qiankun testMicro]: vue app bootstraped');
}
/**
* 应用每次进入都会调用 mount 方法通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log('[qiankun testMicro]: props from main framework', props);
props.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log("[qiankun testMicro]: [onGlobalStateChange]", state, prev);
});
// props.setGlobalState(state);
storeTest(props);
render(props);
}
/**
* 应用每次 切出/卸载 会调用的方法通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
console.log("[qiankun testMicro]: vue app unmount");
instance.$destroy();
instance = null;
router = null;
}

5
src/public-path.js

@ -0,0 +1,5 @@
if (window.__POWERED_BY_QIANKUN__) {
// 动态设置 webpack publicPath,防止资源加载出错
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

25
src/router/index.js

@ -0,0 +1,25 @@
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: function () {
// /* webpackChunkName: "about" */
return import('../views/About.vue')
}
}
]
export default routes

76
src/utils/request.js

@ -0,0 +1,76 @@
import Vue from 'vue'
import axios from 'axios'
import notification from 'ant-design-vue/es/notification'
import { VueAxios } from 'utils'
// import { ACCESS_TOKEN } from '@/store/mutation-types'
// 创建 axios 实例
const service = axios.create({
baseURL: process.env.NODE_ENV === 'production' ? 'http://api-test.qniao.cn/user-centre' : 'http://47.106.79.88:9000/user-centre',
timeout: 15000 // 请求超时时间
})
const err = (error) => {
console.log(error)
if (error.response) {
const data = error.response
// const token = Vue.ls.get(ACCESS_TOKEN)
// const token = JSON.parse(localStorage.getItem('pro__Access-Token') || '{}').value
const token = localStorage.getItem('pro__Access-Token')
console.log('token get from testmicro: ', token)
if (error.response.status === 403) {
notification.error({
message: '您暂时没有权限!',
description: data.message
})
}
if (error.response.status === 500) {
notification.error({
message: '服务器错误!',
description: data.message
})
}
if (error.response.status === 401 && !(data.result && data.code === 666)) {
notification.error({
message: '登录已失效',
description: '会话失效,请重新登录!'
})
if (token) {
// Vue.ls.remove(ACCESS_TOKEN)
localStorage.removeItem('pro__Access-Token')
window.location = service.baseURL
}
}
}
return Promise.reject(error)
}
// request interceptor
service.interceptors.request.use(config => {
// const token = Vue.ls.get(ACCESS_TOKEN)
// const token = JSON.parse(localStorage.getItem('pro__Access-Token') || '{}').value
const token = localStorage.getItem('pro__Access-Token')
console.log('token get from testmicro: ', token)
const _token = (JSON.parse(token) || {}).value
if (_token) {
config.headers['user-token'] = _token // 让每个请求携带自定义 token 请根据实际情况自行修改
}
return config
}, err)
// response interceptor
service.interceptors.response.use((response) => {
return response.data
}, err)
const installer = {
vm: {},
install (Vue) {
Vue.use(VueAxios, service)
}
}
export {
installer as VueAxios,
service as axios
}

5
src/views/About.vue

@ -0,0 +1,5 @@
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>

22
src/views/Home.vue

@ -0,0 +1,22 @@
<template>
<div class="home">
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
import { test } from '@/api'
export default {
name: 'Home',
components: {
HelloWorld
},
created() {
test()
}
}
</script>

52
vue.config.js

@ -0,0 +1,52 @@
const path = require('path');
const { name } = require('./package');
function resolve(dir) {
return path.join(__dirname, dir);
}
const port = 7101; // dev port
module.exports = {
/**
* You will need to set publicPath if you plan to deploy your site under a sub path,
* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
* then publicPath should be set to "/bar/".
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
outputDir: 'dist',
assetsDir: 'static',
filenameHashing: true,
// tweak internal webpack configuration.
// see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
devServer: {
// host: '0.0.0.0',
hot: true,
disableHostCheck: true,
port,
overlay: {
warnings: false,
errors: true,
},
headers: {
'Access-Control-Allow-Origin': '*',
},
},
// 自定义webpack配置
configureWebpack: {
devtool: 'source-map',
resolve: {
alias: {
'@': resolve('src'),
},
},
output: {
// 把子应用打包成 umd 库格式
library: `${name}-[name]`,
libraryTarget: 'umd',
jsonpFunction: `webpackJsonp_${name}`,
},
},
};

6893
yarn.lock
File diff suppressed because it is too large
View File

Loading…
Cancel
Save