vue+qiankun微前端父子之间相互通信

qiankun父子之间相互通信

本功能实现:父传子、子传父
此链接有下载qiankun插件和qiankun的介绍:qiankun官网介绍

  1. 先创建两个项目 一个作为项目基座(vue-dp-base),一个作为子应用(vue-children)

  2. 配置基座父框架

    搭建基座及配置信息

     1. 下载插件
    
			npm install qiankun
     2.在main中导入qiankun 并启动
import { createApp } from 'vue'
import {registerMicroApps, start} from "qiankun";
import App from './App.vue'
import router from './routes/index'
const app = createApp(App)
// 基座的配置
const apps = [
    {
        name: "fileManagementApp", // 应用的名字 档案管理
        entry: "//localhost:20000", // 默认会加载这个html解析里面的js动态的执行(子应用必须支持跨域) fetch
        container: "#fileManagement", // 加载到哪个元素上面,容器名称
        activeRule: '/fileManagement',
        sandbox: {
            strictStyleIsolation:true,// 开启样式隔离
        }
    }
];
start();//开启
// 导出 qiankun 的启动函数export default start;
app.use(router)
app.use(ElementPlus, {
    locale:zhCn,
});
app.mount('#app')
		 3. 放置路由或按钮把子路由加载到相应的元素上面
			 - 可以放在app.vue中
			 - 也可以放到页面的按钮的点击事件中
<template>
  <div>
    <el-menu :router="true" mode="horizontal">
      <!--基座中可以放自己的路由-->
      <el-menu-item index="/">Home</el-menu-item>
      <!--引用其他子应用-->
      <el-menu-item index="/fileManagement">vue应用</el-menu-item>
    </el-menu>
    <router-view></router-view>
    <div id="fileManagement"></div>
  </div>
</template>
<template>
	 <a
	    href="javascript:;"
	    @click="goBBGL"
	  >
	   去往子路由档案管理
	  </a>
</template>
<script setup lang="ts">
const goBBGL = () => {
  let href = "/fileManagement";
  let title = "档案管理";
  let stateObj = {};
  window.history.pushState(stateObj, title, href);
};
</script>
			4. 基座设置路由 注意 最好是history模式
import { RouteRecordRaw, createRouter, createWebHistory,createWebHashHistory } from "vue-router";
const routes: Array<RouteRecordRaw> = []
// 路由
const router = createRouter({
    history: createWebHistory(),
    routes
})
// 导出
export default router 
			 5.配置基座的vuex 
			 	会涉及到更改更新相应的值 
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    token: ''
  },
  getters: {
  },
  mutations: {
    changeName(state, token){
      state.token= token;
    }
  },
  actions: {
    changeName(context, username){
      context.commit('changeToken', token);
    }
  },
  modules: {
  }
})
				 6.基座定义全局状态,并返回通信方法,子应用通过props获取通信方法
import { initGlobalState, MicroAppStateActions } from 'qiankun';

// 注意放到start()下面
const state = {
  token: 'abckdlajflajdf====jalkdjf------'
}
// 初始化 state
const actions: MicroAppStateActions = initGlobalState(state);

actions.onGlobalStateChange((state, prev) => {
  // state: 变更后的状态; prev 变更前的状态
  console.log(state, prev);
});
actions.setGlobalState(state);// 初始化了state

store.dispatch('changeToken', state.token);// 修改vuex中值
  1. 配置子应用

     1. 在子应用 mian.js中 设置补全路径,浏览器跨域的问题,需要拿到完整url
     2. 入口文件 main.js 修改,为了避免根 id #app 与其他的 DOM 冲突,需要限制查找范围
    
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";

Vue.config.productionTip = false;
let instance = null;
function render(props) {
  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}
/*eslint disable no undef*/
// 上方这一行用于eslint的忽略,因为下方代码的指向其实是不存在的,在有eslint的环境中不加入此行会报错
// 如果是qiankun框架使用它
if (window.__POWERED_BY_QIANKUN__) {
  store.state.isQiankun = true;
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 如果是独立运行的话
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}
function storeTest(props) {
  props.onGlobalStateChange((value, prev) => {
    console.log("从基座传过来的值onGlobalStateChange:", value.token);
  }, true);
  props.setGlobalState &&
    props.setGlobalState({
      ignore: props.token,
      user: {
        name: props.token,
      },
    });
}

// 子组件的协议就ok了
export async function bootstrap(props) {}
export async function mount(props) {
  storeTest(props);
  render(props);
}
export async function unmount(props) {
  instance.$destroy();
  instance.$el.innerHTML = "";
  instance = null;
}

		 3. 子路由打包配置修改 vue.config.js
const { defineConfig } = require("@vue/cli-service");
const path = require("path");
const { name } = require('./package');
module.exports = defineConfig({
  transpileDependencies: true,
  devServer: {
    port: 20000,
    open: "http://localhost:20000",
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
  },
  configureWebpack: {
    output: {
      library: "fileManagementApp",
      libraryTarget: "umd", // 打包的类型
       jsonpFunction: `webpackJsonp_${name}`,// 取决于webpack的版本(可不要,但小于webpack5.x则需要加上)
    },
  },
});
		 4. 修改子框架的路由 router目录下的index.js文件
import Vue from "vue";
import VueRouter from "vue-router";
Vue.use(VueRouter);
const routes = [];
const router = new VueRouter({
  mode: "history",
  base: window.__POWERED_BY_QIANKUN__ ? "/fileManagement" : "/",// 注意此处的名字要与基座中对应
  routes,
});

export default router;

		 5. 修改子框架的 mian.js
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
Vue.config.productionTip = false;
let instance = null;
function render(props) {
  instance = new Vue({
    router,
    store,
    render: (h) => h(App),
  })..$mount(container ? container.querySelector('#app') : '#app');
  // 可以给根路由另外起个名字 涉及到的文件 public下的index.html 和app.vue中的id
  // $mount("#app_children");
}
/*eslint disable no undef*/
// 上方这一行用于eslint的忽略,因为下方代码的指向其实是不存在的,在有eslint的环境中不加入此行会报错
// 如果是qiankun框架使用它
if (window.__POWERED_BY_QIANKUN__) {
  store.state.isQiankun = true;
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
// 如果是独立运行的话
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}
function storeTest(props) {
  props.onGlobalStateChange((value, prev) => {
    console.log("从基座传过来的值onGlobalStateChange:", value.token);
  }, true);
  props.setGlobalState &&
    props.setGlobalState({
      ignore: props.token,
      user: {
        name: props.token,
      },
    });
  console.log("子路由走这个方法=>setGlobalState", props.token);
}

// 子组件的协议就ok了
export async function bootstrap(props) {}
export async function mount(props) {
  storeTest(props);
  render(props);
}
export async function unmount(props) {
  instance.$destroy();
  instance.$el.innerHTML = "";
  instance = null;
}

4.基座(父应用)和子应用之间的数据互通。

 1. 修改基座项目里的mian.js
// 如果要在页面中使用,可以挂在到原型链上
Vue.prototype.$setGlobalState = actions.setGlobalState;
// 也可以将需要通信的数据在vuex中进行操作

actions.onGlobalStateChange((state, prev) => {
  // state: 变更后的状态; prev 变更前的状态
  console.log(state, prev);
  // 监听子应用数据更改
});
 2. 在app.vue中修改 或者在页面中使用
<script>
  export default {
    name: 'App',
    methods:{
      changeName(){
        this.$store.dispatch('changeToken','=======adlfkjads=====');
        this.$setGlobalState({token:'=======adlfkjads====='})// 将数据发送给子应用
      }
    }
  }
</script>
 3. 子应用 的mian.js
function storeTest(props) {
    props.onGlobalStateChange &&
      props.onGlobalStateChange(
        (value, prev) => {
          store.dispatch('changeName', value.username);
        },
        true,
      );
    if(props.setGlobalState){
        Vue.prototype.$setGlobalState = props.setGlobalState; // 同基座,将set方法加载到原型链上
    }
}
 4. 子应用中的 App.vue中
<div id="app">
    <button @click="changeToken">changeToken</button>
    {{ $store.state }}
    <br/>
</div>
<script>
  export default {
    name: 'App',
    methods:{
      changeToken(){
        this.$store.dispatch('changeName','====aldfj=====');
        this.$setGlobalState({token:'====aldfj====='});// 更改主应用数据
      }
    }
  }
</script>
<style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue3和qiankun都是目前前端领域非常流行的技术,它们可以在许多不同的场景下被应用。其中,Vue3是Vue框架的最新版本,它在设计之初就注重了性能和开发体验的优化,同时也增加了许多新功能,让开发者可以更加方便地构建高性能的web应用。而qiankun则是一款前端框架,它可以让不同的团队开发自己的应用,并将它们集成到一个统一的页面中,以提高开发效率和应用的可维护性。 Vue3借助新的响应式数据结构可以大幅度提升渲染性能,同时也改进了一些语法和 API,更加符合现代开发的规范,易于上手和使用。Vue3在开发途中使用了编译时优化,还引入了定制化渲染器,使得开发者可以更加轻松地根据不同的业务需求进行个性化开发,而不影响整体性能。 qiankun则将多个前端应用组装成一个整体,使用起来非常简单方便,并且具有高可扩展性和灵活性。它提供了诸如应用通信、共享状态、应用隔离等功能,便于管理和维护多个应用之间的依赖关系和协作。此外,qiankun还支持热更新,可以在应用代码发生变更时,不影响整体部署的运行,提高了开发迭代速度。 综上所述,Vue3和qiankun分别从不同的角度出发,为前端开发者提供了高效、易用的开发工具。在实际应用中,可以根据业务场景的需要,将两者结合起来,构建出更具扩展性、可维护性和性能的web应用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值