组件传值
初入微前端—qiankun学习这一篇就够了
无论是vue还是react中我们传值都是在父组件中调用子模块中传递一个props给子组件,子组件创建时就可以拿到这个值去渲染或者怎么这样,而子组件如何传递值给父组件呢?我们可以通过父组件传递一个方法给子组件,子组件通过这个方法去改变父组件的值,并在父组件中完成响应。
微前端是什么
参考qiankun
其实说微前端,就是将一个一个项目单独隔离开,形成一个模块,在通过一个主应用去调用这些模块,并渲染形成页面,既然说到模块,在前端中模块与模块间相对独立隔离,互相不会影响的,所以在微前端中在两个模块之间是相对隔离,包括样式什么的,每个模块都有属于自己的沙箱。
应用间如何通信
其实微前端的模块也可以抽象成系统中的一个一个组件,页面变化的时候我就去渲染,如果不需要我了我就走了,传值方面也有很多的类似,主应用中分发props,子应用接收props并调用方法去改变主应用的值,主应用在响应式去通知大家我变了,就OK了。话不多说马上行动。
codding
前置内容
首先我们需要一个qiankun的API,initGlobalState,然后因为我们主系统是vue3的项目,所以这里通过reactive创建响应式的对象,而react中使用useStare差不多的效果。
编写store文件,用于存储全局状态
import { initGlobalState, MicroAppStateActions } from 'qiankun'
import { reactive } from 'vue'
type keys = keyof typeof initialState
const initialState = reactive({
ignore: 'marster',
user: {
name: 'xiaochen',
author: 'chenxiansheng',
developer: 'vue@next',
},
})
const actions: MicroAppStateActions & {
getGlobalState?: Function
useAppIgnore?: Function
} = initGlobalState(initialState)
// 在当前应用监听全局状态,
actions.onGlobalStateChange((newState, prev) => {
// newState变更后状态,prev变更前状态
console.log('main change', JSON.stringify(newState), JSON.stringify(prev))
Object.assign(initialState, newState)
console.log('state..', initialState)
})
// 定义一个获取state的方法下发到子应用
actions.getGlobalState = (key?: keys) => {
return key ? initialState[key] : initialState
}
//往里面注入一个方法让子元素传递一个版本信息出来。
actions.useAppIgnore = (name: string, developer: string) => {
actions.setGlobalState &&
actions.setGlobalState({
ignore: name,
user: {
developer: developer,
},
})
}
export default actions
修改qiankun文件传递方法和参数
import {
registerMicroApps,
runAfterFirstMounted,
setDefaultMountApp,
start,
} from 'qiankun'
// 引入vue实例
import { isLoading } from '@/App'
import store from '@/store/index'
/**
* 加载动画运行
* @param loading
*
*/
function loader(loading: boolean) {
isLoading.value = loading
// if(instance && instance.$children)
}
const microApps = [
{
name: 'sub-react',
developer: 'react',
entry: '//localhost:40001',
activeRule: '/sub-react',
},
{
name: 'sub-vite-react',
developer: 'vite-react',
entry: '//localhost:40002',
activeRule: '/sub-vite-react',
},
]
const apps = microApps.map((item) => {
return {
...item,
loader, // 给子应用配置加上loader方法
container: '#sub-container',
props: {
developer: item.developer, // 下发基础路由
routerBase: item.activeRule, // 下发基础路由
// 获取和修改全局的方法
getGlobalState: store.getGlobalState,
useAppIgnore: store.useAppIgnore,
},
}
})
registerMicroApps(apps, {
beforeMount: [
(app): any => {
console.log('开始挂载:', app.name)
},
],
afterMount: [
(app): any => {
console.log(app.name, '挂载成功了')
},
],
afterUnmount: [
(app): any => {
console.log('贾维斯卸载 ', app.name)
store.useAppIgnore!('marster', 'vue@next')
},
],
})
/**
* 设置默认进入的子应用
*/
// setDefaultMountApp('/sub-vite2-react')
start({
sandbox: {
experimentalStyleIsolation: true,
},
})
runAfterFirstMounted(() => {
console.log('贾维斯开机')
})
export { microApps }
export default apps
最后只要在子应用挂载时候测试一下调用修改名字就好了
在主应用中使用获取方法时候最好写在computed中,vue写ref里也是可以的,这里是因为我们没有直接改变主页面的响应式值,所以我们还是要吧组件对应的值变为响应式,从而让ver或react能够通知其对应的组件。
这样基本框架demo就完成了,实现后大概就是可以响应的改变名字
最后
其实传值的都是简单的,和现在开发中正常的传值都是差不多的逻辑,大家始终还是规范与单向数据流,这样保证了代码可读行,同时保证代码的健壮,不会一个长久代码你读起来,你却不知道他哪里来,他哪里改。到这里传值也就完成了。
up也在拼命学习中!!!!