commit
37b63f1c0e
18 changed files with 7377 additions and 0 deletions
Unified View
Diff Options
-
3.browserslistrc
-
21.gitignore
-
41README.md
-
23package.json
-
BINpublic/favicon.ico
-
17public/index.html
-
32src/App.vue
-
10src/api/index.js
-
BINsrc/assets/logo.png
-
57src/components/HelloWorld.vue
-
95src/main.js
-
5src/public-path.js
-
25src/router/index.js
-
76src/utils/request.js
-
5src/views/About.vue
-
22src/views/Home.vue
-
52vue.config.js
-
6893yarn.lock
@ -0,0 +1,3 @@ |
|||||
|
> 1% |
||||
|
last 2 versions |
||||
|
not dead |
||||
@ -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? |
||||
@ -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 |
||||
|
``` |
||||
@ -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" |
||||
|
} |
||||
|
} |
||||
@ -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> |
||||
@ -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> |
||||
@ -0,0 +1,10 @@ |
|||||
|
import { axios } from '@/utils/request' |
||||
|
|
||||
|
// 测试接口
|
||||
|
export function test (parameter) { |
||||
|
return axios({ |
||||
|
url: '/department/getDepartmentList', |
||||
|
method: 'get', |
||||
|
params: parameter |
||||
|
}) |
||||
|
} |
||||
@ -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> |
||||
@ -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; |
||||
|
} |
||||
@ -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__; |
||||
|
} |
||||
@ -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 |
||||
@ -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 |
||||
|
} |
||||
@ -0,0 +1,5 @@ |
|||||
|
<template> |
||||
|
<div class="about"> |
||||
|
<h1>This is an about page</h1> |
||||
|
</div> |
||||
|
</template> |
||||
@ -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> |
||||
@ -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
File diff suppressed because it is too large
View File
Write
Preview
Loading…
Cancel
Save