问题描述
项目中通过v-for生成对应数量的容器,容器中根据条件加载对应的组件,我在加载的指标卡组件中,引入另一个tab容器组件时,发生了Unknown custom element报错,通过console,发现import后值是undefined,延迟1s打印可以获得正确结果
import tabContainer from '../tab/index.vue'
console.log('containerTab?:>>?',?tabContainer) //?undefined
setTimeout(() => {
console.log('containerTab?:>>?',?tabContainer) //?Object
}, 1000)
进入tabContainer文件,将其中引入的left组件删除后,可以在指标卡中正常引入
left 文件内容
<template>
<div class="grid-wrapper?my-wrapper">
<grid-layout
:ref="gridLayoutName"
:line-style="{color: '#C5533A',?size: '1px'}"
:layout="chartsOption"
:col-num="containerInit.colNum"
:row-height="containerInit.rowHeight"
:use-css-transforms="containerInit.useCssTransforms"
:is-draggable="!isDisDraggable"
:margin= "containerInit.margin"
>
<grid-item
v-loading="item.loading"
v-for="(item) in chartsOption"
:key="item.i"
:x="item.x"
:y="item.y || 0"
:w="item.w"
:h="item.h"
:i="item.i"
:min-h="containerInit.minH"
drag-ignore-from=".container-inner"
class="grid-item"
:class="{
active:?item.selected,
[`grid-item-${item.i}`]: true,
'theme-grid-item': parseInt(item.id) === 0,
'theme-grid-item-search': parseInt(item.id) === 2,
'theme-grid-item-MetricCard': parseInt(item.id) == 0 && item.feature.chartId == '18'
}"
@click.native.stop="selectContainer(item.i)"
@resized="resizeOrMove(item.i)"
@moved="resizeOrMove(item.i)"
@mouseenter.native.stop="showTips(item.i)"
@mouseleave.native.stop="hideTips(item.i)"
>
<el-dropdown @visible-change="visibleChange" v-if="item.i == currentHoverContainerIndex && !isPreviewToggle" class="actions-btn" @click.native.stop @command="handleCommand">
<span class="iconfont?icon-More"></span>
<el-dropdown-menu slot="dropdown" class="container-action-options">
<el-dropdown-item :command="'b'+item.i" v-if="item.id==0">
<span class="iconfont?icon-copy"></span>
复制
</el-dropdown-item>
<el-dropdown-item :command="'a'+item.i">
<span class="iconfont?icon-delect"></span>
删除
</el-dropdown-item>
<el-dropdown-item :command="'c'+item.i" v-if="item.id !== 2 && item.id !== 3">
<span class="iconfont?icon-move1"></span>
移动
</el-dropdown-item>
<el-dropdown-item :command="'d'+item.i" v-if="item.id === 0">
<span class="iconfont?icon-Viewdata"></span>
查看查询条件
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<div class="drag-handle" :class="{noShow: !item.nameToggle}">
<span class="tig-title-pannel?theme-tig-title-pannel-underTab" v-show="item.nameToggle">
<span class="title-text?theme-title-text-underTab">{{?item.name?}}</span>
<span calss="title-right" v-show="hasTitleSkin"><img :src="title_right_src"></span>
<div class="newMoreData" :class="{'visualMoreData':?isDisDraggable}" v-if="item.showMoreDataFlag" @click="getMoreData(item.i)">
<span class="newMoreDataLabel">更多数据</span>
<!--?<span?class="newMoreDataArrow"></span>?-->
<img class="newMoreDataArrow" src="/static/charts/images/newMoreData.svg">
</div>
</span>
</div>
<!--标签提示-->
<tip
:cur-chart-option="item"
:tip-style="'corner'"
:metrics-id="item.feature.metricList"
:is-tab="true"
:opacity="tipsArr[item.i]"
:class="{noTitle: !item.nameToggle}"
v-if="item.id === 0"
@handleCatQueryInfo="handleCatQueryInfo(item.i)"
@dimNumberRange="dimNumberRangeHander(item.i)"
>
</tip>
<!--?<container-inner?:index="item.i">图表组件</container-inner>?-->
<lazy-box :index="item.i" :key="item.i" ref="lazyBox">图表组件</lazy-box>
<border v-if="!isDisDraggable"></border>
</grid-item>
</grid-layout>
<moveContainer ref="moveContainer"></moveContainer>
<query-condition-dialog ref="queryConditionDialog"></query-condition-dialog>
<!--?<dimRangeDialog?ref="dimRangeDialog"?:selected-option="chartsOptionCopy"></dimRangeDialog>?-->
</div>
</template>
<script>
import {?GridLayout,?GridItem?} from '@suning/vue-grid-layout'
import {?containerInit?} from '../../static/configData'
import addPanel from './addPannel'
//?import?containerInner?from?'./containerInner'
import lazyBox from './lazyBox'
import eventBus from '../../utils/eventBus'
import leftMixin from '../../layout/mixins/leftMixin/leftMixin'
import border from '../../layout/left/border'
import {?getContainerByIndex,?getGuid,?isInHuiyanIframe,?getHYOrigin,?reportDefaultSearch?} from '../../utils/utils'
import Utils from '@/components/Utils'
import api from '@/web-design/api/charts'
import bus from '../../utils/eventBus'
import moveContainer from '../../layout/moveContainer'
import queryConditionDialog from '../../layout/queryConditionDialog'
//?import?dimRangeDialog?from?'../../layout/right/focus/chartFocus/dimRangeSetting/dimRangeSettingDialog'
export default {
name: 'Left',
components:?{
GridLayout,
GridItem,
addPanel,
border,
lazyBox,
moveContainer,
queryConditionDialog
//?dimRangeDialog
},
mixins:?[leftMixin],
props:?[
'containerIndex', //?当前第几个容器
'tabIndex' //?tab页面index
],
data()?{
return {
containerInit,
chartsOption:?[], //?必须要有本地的chartsOption,如果直接用computed里会先加载,但是dom加载在后
tipsArr:?[],
currentHoverContainerIndex: -1,
showMoredataMenu: false,
lastTop: 0 //?记录移动容器上次的top
}
},
computed:?{
chartsOptionCopy()?{
return this.$store.state.charts.chartsOption.filter(
item => !item.hide && !item.drop && item.tabContainerIndex === this.containerIndex && item.activeTabIndex == this.tabIndex
)
},
isPreviewToggle()?{
return this.$store.state.charts.previewToggle && this.$route.path !== '/visual'
},
isDisDraggable()?{
return this.$route.path === '/visual' || this.$store.state.charts.previewToggle
},
isVisual()?{
return this.$route.path === '/visual'
},
chartsOptionAll()?{
return this.$store.state.charts.chartsOption
},
//?该layout布局在tab切中
isLayoutInTab()?{
return true
},
gridLayoutName()?{
return `gridLayout_${this.tabIndex}`
},
hasTitleSkin()?{
//?return?config.title_left?&&?config.title_right
return this.$store.state.charts.themeService
},
//?title_left_src?()?{
//???return?'/static/skin/spring/image/secondTitleLeft.png'
//?},
title_right_src()?{
return '/static/skin/spring/image/secondTitleRight_modify.png'
},
handleContainerID()?{
const handleContainerID = {}
this.chartsOptionAll.filter(item => {
return !item.drop
}).map(item => {
return item.id
}).forEach(item => {
let containerID = handleContainerID[item]
if (containerID >= 0)?{
handleContainerID[item] = ++containerID
} else {
handleContainerID[item] = 1
}
})
return handleContainerID
},
systemConfig()?{
return this.$store.state.charts.systemConfig
}
},
//?监听vuex上的chartsOption,实时改变本地的chartsOption
watch:?{
chartsOptionCopy(value)?{
this.$nextTick(() => {
this.chartsOption = value
})
}
},
mounted()?{
//?等dom加载完毕后再改变本地的chartsOption
this.$nextTick(() => {
this.chartsOption = this.chartsOptionCopy
})
},
methods:?{
//?跳转到更多数据页
async getMoreData(index)?{
let chartsOption = getContainerByIndex(this.chartsOptionAll,?index)
const selectedReport = chartsOption.selectedReport
let selectedReportVersion = chartsOption.selectedReportVersion
if (selectedReport == '' || selectedReportVersion == '')?{
this.$message({
message: '未配置关联报表!',
type: 'error'
})
return
}
const selectedSystemId = chartsOption.selectedSystemId
const sourceQueryPanel = chartsOption.sourceQueryPanel
const queryPanelSelected = chartsOption.queryPanelSelected
const targetQueryPanel = chartsOption.targetQueryPanel
const customReference = chartsOption.feature.customReference
//?获取已上线的最新版本
let res = await api.getLatestOnlineVersion({?reportId:?selectedReport?})
//?console.log(res)
if (!res)?{
this.$message({
message: '更多数据打开异常!',
type: 'error'
})
return
}
if (res.statusCode == '0')?{
selectedReportVersion = res.data.versionId
}
let guidstr = this.getGuidStr() //?全局唯一标识符,用来确认唯一的链接参数
let paramsObj = {
linkIndex:?guidstr,
selectedReport:?selectedReport,
selectedReportVersion:?selectedReportVersion
}
let queryParams = {
reportId:?selectedReport,
versionId:?selectedReportVersion
}
if (queryPanelSelected && sourceQueryPanel && targetQueryPanel)?{ //?有查询面板传参
let queryInfoData = this.cloneQueryInoData(Number(sourceQueryPanel),?index)
if (queryInfoData)?{ //?查询面板是否有参数
paramsObj.queryInfo = {
targetQurryPanel:?targetQueryPanel,
value:?queryInfoData
}
}
}
if (customReference && customReference.length != 0)?{ //?是否有自定义传参
paramsObj.customReference = customReference
}
if (paramsObj.queryInfo || paramsObj.customReference)?{
queryParams.paramIndex = guidstr
this.saveDetailParams(paramsObj)
}
//?慧眼环境?or?天工环境
if (parent && isInHuiyanIframe() && !['alarm'].includes(this.$route.query.platform))?{
queryParams.other = true
let url = this.createDetailRouteUrl(queryParams,?selectedSystemId)
let myJson = {?type: 'openUrl',?reportId:?selectedReport,?url:?url,?paramIndex:?queryParams.paramIndex ? queryParams.paramIndex : '' }
let targetOrigin = getHYOrigin(window.env)
console.log('[postMessage]', `ntype: ${myJson.type}nreportId: ${myJson.reportId}nparamIndex: ${myJson.paramIndex}nurl: ${myJson.url}`)
//?发送poseMessage?给慧眼
parent.postMessage(JSON.stringify(myJson),?targetOrigin)
} else {
let url = this.createDetailRouteUrl(queryParams,?selectedSystemId)
//?生成的链接
window.open(url)
}
},
selectContainer(index)?{
//?关闭更多指标维度弹窗
bus.$emit(`cloneDimMetric_${index}`)
let selectedContainer = this.chartsOption.filter(each => each.i === index)[0]
if (selectedContainer && selectedContainer.id === 0)?{
document.getElementById('dashboard').click()
}
this.$store.commit('selectedChange',?index)
},
resizeOrMove(index)?{
this.$store.commit('resizeOrMove', this.chartsOption)
this.$nextTick(() => {
setTimeout(() => {
eventBus.$emit(`resizeOrMove_${index}`,?index)
this.$emit('resize')
}, 200)
})
},
handleCommand(command)?{
if (command[0] === 'c')?{ //?移动容器
this.$refs.moveContainer.showMoveContainer(command.slice(1))
return
}
if (command[0] === 'a')?{ //?删除容器
this.$store.commit('delContainer',?command.slice(1))
}
if (command[0] === 'b')?{ //?复制容器
this.checkAddContainer(this.handleContainerID) &&
this.$store.commit('copyContainer',?{?index:?command.slice(1)?})
}
if (command[0] === 'd')?{ //?查看查询条件
this.handleCatQueryInfo(command.slice(1))
}
this.selectContainer(command.slice(1))
},
checkAddContainer(obj)?{
if (!this.systemConfig.chartsNumber) return true
let currentNumber = 0
for (const key in obj)?{
currentNumber += obj[key]
}
if (currentNumber >= this.systemConfig.chartsNumber)?{
this.$message({?message: '已超过配置容器最大限制',?type: 'warning' })
return false
}
//?debugger
return true
},
/**
*?预览时的tips,当鼠标移入时显示,移出时消失
*/
showTips(index)?{
if (!this.tipsArr[index] && this.$route.path === '/visual')?{
this.$set(this.tipsArr,?index, true)
}
if (!this.isPreviewToggle)?{
this.currentHoverContainerIndex = index
}
},
visibleChange(value)?{
this.showMoredataMenu = value
},
hideTips(index)?{
if (this.tipsArr[index] && this.$route.path === '/visual')?{
this.$set(this.tipsArr,?index, false)
}
if (!this.isPreviewToggle && !this.showMoredataMenu)?{
this.currentHoverContainerIndex =