Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]似乎不支持hash路由 #118

Closed
cloydlau opened this issue Oct 28, 2019 · 19 comments · Fixed by #129
Closed

[Bug]似乎不支持hash路由 #118

cloydlau opened this issue Oct 28, 2019 · 19 comments · Fixed by #129

Comments

@cloydlau
Copy link

What happens?

用history路由是没问题的,hash路由模式下似乎不能正常地mount和unmount子系统
现象1:通过某个hash进入某个子系统之后,再导航切换回去,此时并不会触发render方法,会仍然停留在这个子系统
现象2:子系统a导航到子系统b时,子系统b会报没有导出生命周期方法的错,但如果单独加载其中任一一个子系统是ok的,可能跟没有正常地unmount有关
平时开发用history是挺好的,不过history需要后端支持才行,打包部署时多半还是要用hash,还是希望能支持hash路由

最小可复现仓库

https://github.com/CradelLau/microfrontend-demo

复现步骤,错误日志以及相关配置

npm install
npm run dev

相关环境信息

  • 浏览器版本
    chrome最新
  • 操作系统
    win10
  • Node 版本
    10+
@kuitos
Copy link
Member

kuitos commented Oct 28, 2019

qiankun 不限制你使用的路由模式,当前 url 应该匹配哪个应用是由 activeRule 配置决定的。

你这个场景的问题在于子应用真实的路由跟主应用配置的前缀并不是一一匹配的。

解决方案是每个子应用配置一个 base,并与主应用注册时设置的保持一致。
https://github.com/CradelLau/microfrontend-demo/blob/master/src/main.js#L51

@cloydlau
Copy link
Author

qiankun 不限制你使用的路由模式,当前 url 应该匹配哪个应用是由 activeRule 配置决定的。

你这个场景的问题在于子应用真实的路由跟主应用配置的前缀并不是一一匹配的。

解决方案是每个子应用配置一个 base,并与主应用注册时设置的保持一致。
https://github.com/CradelLau/microfrontend-demo/blob/master/src/main.js#L51

vue-router的base只支持history,不过我手动实现了下,仓库已更新
我知道您的意思,我就是修改activeRule配置来匹配的
问题1还是存在,比如主系统定义了一个‘/’的默认页面,一旦从主系统导航到某个子系统后,就无法跳转回这个默认页面了,不过这个倒不要紧,将这个默认页面也拆为一个子系统可以解决
现在发现在hash模式下,没有隔离全局css,改成history之后是可以隔离的,现在的仓库代码是hash的,可以复现

@kuitos
Copy link
Member

kuitos commented Oct 31, 2019

vue router base 支持 hash https://github.com/vuejs/vue-router/blob/dev/src/index.js#L59

没有隔离全局 css 是指子应用之间没有隔离还是主应用跟子应用之间没有隔离?

@cloydlau
Copy link
Author

cloydlau commented Oct 31, 2019

hash可以配置base 也可以生效 但这个base还是以history的方式来匹配的 比如我配置了一个叫/hello的base 一个叫/world的route 那么组合起来就是/hello#/world 但是匹配不到#/hello/world 这样就不行了
是子应用之间没有隔离 https://github.com/CradelLau/microfrontend-demo 可以复现

@yangangzhang
Copy link

@kuitos @CradelLau
我这里测试的是,应用包括主应用和子应用,必须一个vue-router的模式,不能既有hash模式又有history模式

@salchemist
Copy link

主应用和子应用都是hash模式情况下,主应用的路由调用pushState,不会触发子应用的popState,子应用路由不会被触发,需要手动调用子应用路由的push方法来更新子应用路由。

@kuitos
Copy link
Member

kuitos commented Nov 12, 2019

为啥主应用 pushState 需要触发子应用 popState?

@kybetter
Copy link

我们已经在实际项目中使用了乾坤(都是 Vue 框架),最终选定了 history 路由的方式,开始会遇到很多坑,比如子应用中的字体资源路径不对,子应用图片资源路径问题等等,子应用内容也放在了 vuex 中,这样可以在任何地方渲染子应用。最终实践下来感觉难度还是挺大的,至少在发布到生产环境前得做大量的测试和调整。

微前端这项技术还是需要继续进步才能够为广大人群接受。至少目前我感觉还是撼动不了 iframe 的地位,毕竟坑还是很多的。

@kuitos
Copy link
Member

kuitos commented Nov 12, 2019

我们已经在实际项目中使用了乾坤(都是 Vue 框架),最终选定了 history 路由的方式,开始会遇到很多坑,比如子应用中的字体资源路径不对,子应用图片资源路径问题等等,子应用内容也放在了 vuex 中,这样可以在任何地方渲染子应用。最终实践下来感觉难度还是挺大的,至少在发布到生产环境前得做大量的测试和调整。

微前端这项技术还是需要继续进步才能够为广大人群接受。至少目前我感觉还是撼动不了 iframe 的地位,毕竟坑还是很多的。

可以把过程中碰到的问题分享出来,方便其他人也能快速找到解决方案😀

qiankun 目前在内部已服役近一年,支撑了 70+ 线上应用,基本的完备性应该还是值得信赖的,近期会开启文档站点的计划,会重点完善一下 qiankun 的文档跟实践指南,减少过程中大家走的弯路。

@wusp1994
Copy link
Contributor

wusp1994 commented Nov 13, 2019

@kybetter 请问你们子应用,不挂载到主应用的顶级组件app.vue(v-html在视图组件中,而不在app.vue中)是怎么做到的?

@kybetter
Copy link

@kybetter 请问你们子应用,不挂载到主应用的顶级组件app.vue(v-html在视图组件中,而不在app.vue中)是怎么做到的?

主应用里面:
1、设置activeRule ,示例:/micro
2、设置一个路由:/micro/* ,指向一个要展示子应用的组件比如: Micro.vue
这时访问 /micro 时就会加载子应用的资源,同时也会走配置好的路由。按照这个思路。
获取到后,就可以放到 vuex 中:

// App.vue 中
props: {
    loading: Boolean,
    content: String,
  },
  methods: {
    ...mapMutations({
      setHtml: 'micro/setHtml',
      setLoading: 'micro/setLoading',
    }),
  },
watch: {
    content(value) {
      this.setHtml(value)
    },
    loading(value) {
      this.setLoading(value)
    }
  }

Micro.vue 中接收 vuex 中设定的内容,再来展现就好了:

<template>
  <div>
    <div v-if="loading" v-loading="loading" />
    <div v-html="html" />
  </div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  name: 'micro-frontend',
  computed: mapState({
    html(state) {
      return state.micro.html;
    },
    loading(state) {
      return state.micro.loading;
    },
  }),
};
</script>

这样就不用拘泥于只能在 App.vue 文件中展现子应用数据了。

@wusp1994
Copy link
Contributor

好思路!!!谢谢 @kybetter

@wusp1994
Copy link
Contributor

@kybetter
image
你有遇到过吗?应该是子应用创建vue对象的时候,主应用的子组件还没加载到appContent造成的。找不到挂载的id=“app”的dom

@kybetter
Copy link

@kybetter
image
你有遇到过吗?应该是子应用创建vue对象的时候,主应用的子组件还没加载到appContent造成的。找不到挂载的id=“app”的dom

把单独的 new Vue()删掉,子应用不需要单独访问。

@wusp1994
Copy link
Contributor

@kybetter
image
这是我的子应用,你意思是把new Vue() 删掉?

@kybetter
Copy link

这个我不清楚了,之前遇到的问题是因为额外写了一个 new Vue()

@wusp1994
Copy link
Contributor

wusp1994 commented Nov 13, 2019

能看下你的代码吗,给个代码仓库什么的,学习学习?@kybetter

@kybetter
Copy link

能看下你的代码吗,给个代码仓库什么的,学习学习?@kybetter

https://github.com/kybetter/qiankun-error-sample

@mario-huang
Copy link

我们已经在实际项目中使用了乾坤(都是 Vue 框架),最终选定了 history 路由的方式,开始会遇到很多坑,比如子应用中的字体资源路径不对,子应用图片资源路径问题等等,子应用内容也放在了 vuex 中,这样可以在任何地方渲染子应用。最终实践下来感觉难度还是挺大的,至少在发布到生产环境前得做大量的测试和调整。
微前端这项技术还是需要继续进步才能够为广大人群接受。至少目前我感觉还是撼动不了 iframe 的地位,毕竟坑还是很多的。

可以把过程中碰到的问题分享出来,方便其他人也能快速找到解决方案😀

qiankun 目前在内部已服役近一年,支撑了 70+ 线上应用,基本的完备性应该还是值得信赖的,近期会开启文档站点的计划,会重点完善一下 qiankun 的文档跟实践指南,减少过程中大家走的弯路。

非常期待开启文档站点。我们这周把微前端上线了,躺了好多坑,我们差点放弃了。

szy1000 pushed a commit to szy1000/qiankun that referenced this issue Aug 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants