Appearance
子组件同步异步引入问题
目前页面都是组件化开发,对于页面使用到的子组件存在同步引入与异步引入的问题,不同的引入方式会影响页面对子组件的使用,建议都采用同步引入的方式来引入子组件。
子组件异步引用的问题
- TODO:页面使用到的子组件,如果是异步引入,子组件最终会编译程一个单独的JS文件,此处直接通过refs直接调用子组件的时候,由于子组件文件可能没有加载完成,可能存在获取子组件示例为空的情况
vue
<!-- 门户首页 -->
<template>
<!-- 容器 -->
<component ref="component" :is="activeComponent" />
</template>
<script>
import { mapGetters } from 'vuex';
import { GET_LAYOUT } from '@/store/login';
import { LAYOUT } from '@/assets/js/constant';
export default {
name: 'INDEX',
// TODO:页面使用到的子组件全部是异步引入
components: {
vDefault: () =>
import(
/* webpackChunkName: 'src/modules/home/index/default/index' */ '@/modules/home/index/default/index'
),
vAdmin: () =>
import(
/* webpackChunkName: 'src/modules/home/index/admin/index' */ '@/modules/home/index/admin/index'
),
vPoliceOfficer: () =>
import(
/* webpackChunkName: 'src/modules/home/index/police-officer/index' */ '@/modules/home/index/police-officer/index'
),
vEfmPur: () =>
import(
/* webpackChunkName: 'src/modules/home/index/efm-pur/index' */ '@/modules/home/index/efm-pur/index'
),
vIntegrationHb: () =>
import(
/* webpackChunkName: 'src/modules/home/index/integration-hb/index' */ '@/modules/home/index/integration-hb/index'
),
},
data() {
return {
open: false,
};
},
beforeRouteEnter(to, from, next) {
next((vm) => {
vm.onBeforeRouteEnter();
});
},
methods: {
/**
* 处理路由进入
* 1、如果页面打开过,切包含更新数据的方法,则需要更新页面
*/
onBeforeRouteEnter() {
if (this.open) {
// TODO:页面使用到的子组件,如果是异步引入,此处直接通过refs直接调用子组件的时候,由于子组件可能没有加载完成,此处存在获取子组件示例为空的情况
let el = this.$refs.component;
_.isFunction(el.updatePage) && el.updatePage();
}
this.open = true;
},
},
computed: {
...mapGetters([GET_LAYOUT]),
/**
* 当前激活的组件
* 1、根据当前系统布局返回不同的组件
* 2、警务传统布局也返回vDefault组件
* 3.采购档案
*/
activeComponent() {
switch (this.GET_LAYOUT) {
case LAYOUT.ADMIN:
return 'vAdmin';
case LAYOUT.POLICE_OFFICER:
return 'vPoliceOfficer';
case LAYOUT.EFM_PUR:
return 'vEfmPur';
case LAYOUT.INTEGRATION_HUBEI:
return 'vIntegrationHb';
default:
return 'vDefault';
}
},
},
};
</script>
子组件同步引用示例
- 页面在使用子组件时,如果子组件是同步引用的,由于编译时,子组件代码会与页面编译程一个JS文件,所以就不存在子组件文件没有加载完成的情况了。
vue
<!-- 门户首页 -->
<template>
<!-- 容器 -->
<component ref="component" :is="activeComponent" />
</template>
<script>
import { mapGetters } from 'vuex';
import { GET_LAYOUT } from '@/store/login';
import { LAYOUT } from '@/assets/js/constant';
// TODO:页面使用到的子组件都同步引用
import vDefault from '@/modules/home/index/default/index';
import vAdmin from '@/modules/home/index/admin/index';
import vPoliceOfficer from '@/modules/home/index/police-officer/index';
import vEfmPur from '@/modules/home/index/efm-pur/index';
import vIntegrationHb from '@/modules/home/index/integration-hb/index';
export default {
name: 'INDEX',
data() {
return {
open: false,
};
},
beforeRouteEnter(to, from, next) {
next((vm) => {
vm.onBeforeRouteEnter();
});
},
methods: {
/**
* 处理路由进入
* 1、如果页面打开过,切包含更新数据的方法,则需要更新页面
*/
onBeforeRouteEnter() {
if (this.open) {
let el = this.$refs.component;
_.isFunction(el.updatePage) && el.updatePage();
}
this.open = true;
},
},
computed: {
...mapGetters([GET_LAYOUT]),
/**
* 当前激活的组件
* 1、根据当前系统布局返回不同的组件
* 2、警务传统布局也返回vDefault组件
* 3.采购档案
*/
activeComponent() {
switch (this.GET_LAYOUT) {
case LAYOUT.ADMIN:
return vAdmin;
case LAYOUT.POLICE_OFFICER:
return vPoliceOfficer;
case LAYOUT.EFM_PUR:
return vEfmPur;
case LAYOUT.INTEGRATION_HUBEI:
return vIntegrationHb;
default:
return vDefault;
}
},
},
};
</script>