<component :is=“ “/>动态组件在 el-tab-pane里的应用
添加新需求时翻到了以前的代码,之前选项卡有2项,就不辞辛苦的直接写template里了。这次又新增了两个选项卡页面。于是将以前的结构翻出来直接写循环了。代码在最后面,没什么参考价值可以忽略。
本篇的目的:主要是写完后,发现此页面还有一个选项卡页面,用来切换不同的组件。(后期又被需求拿掉了,但是页面上没删。)本着代码一致的原则,就手贱的改了下。这个项目用的是element UI。在用 el-tabs数据循环的时候,如果不在el-tab-pane的结构中写DOM,最后输出的是一个字符串。尝试了一些方法后,最后用<component :is="item.content" />解决了。具体代码如下图。vue 动态组件
-
<template>
-
<div class="app-container">
-
<section v-if="false">
-
<h2 id="tab" class="trendTitle">辅助分析工具</h2>
-
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
-
<template v-for="item in auxiliaryTool">
-
<!-- 额外增加v-if="true",不加:key标红 -->
-
<el-tab-pane v-if="true" :key="item.name" :label="item.title" :name="item.name">
-
<div v-if="item.isShow">
-
<component :is="item.content" />
-
</div>
-
</el-tab-pane>
-
</template>
-
</el-tabs>
-
</section>
-
</div>
-
</template>
-
-
<script>
-
import CrossArea from '@/views/smart/crossarea/crossarea';
-
import Inout from '@/views/smart/inout/inout';
-
import Quadif from '@/views/smart/quadif/quadif';
-
-
export default {
-
name: 'Trend',
-
components: {
-
CrossArea,
-
Inout,
-
Quadif,
-
BasisStructure,
-
TermStructure,
-
},
-
data() {
-
return {
-
activeName: '',
-
auxiliaryTool: [
-
{
-
title: '跨1',
-
name: 'crossArea',
-
content: CrossArea,
-
isShow: false,
-
},
-
{
-
title: '内2',
-
name: 'inout',
-
content: Inout,
-
isShow: false,
-
},
-
{
-
title: '品3',
-
name: 'quadif',
-
content: Quadif,
-
isShow: false,
-
},
-
],
-
};
-
},
-
methods: {
-
handleClick(val) {
-
this.auxiliaryTool = this.auxiliaryTool.map(item => {
-
if (item.name === val.name) {
-
item.isShow = true;
-
} else {
-
item.isShow = false;
-
}
-
return item;
-
});
-
this.$nextTick(() => {
-
document.getElementById('tab').scrollIntoView({
-
behavior: 'smooth',
-
block: 'start',
-
});
-
});
-
},
-
},
-
};
-
</script>
本文完,以下纯记录,懒得开新文了。
记录v-for循环el-tab-pane代码
-
<template>
-
<div class="app-container">
-
<section v-loading="loading">
-
<el-row :gutter="20">
-
<el-col :span="activeChart === 'first' || activeChart === 'second' ? 16 : 24">
-
<h3 class="chartTitle">{{ chartTitle }}</h3>
-
<el-tabs v-model="activeChart" type="card" @tab-click="handleClick2">
-
<template v-for="item in tabs">
-
<el-tab-pane v-if="item.hasOwnProperty('isPer') ? item.isPer : true" :key="item.name" :label="item.title" :name="item.name">
-
<div v-if="activeChart === item.name">
-
<line-chart v-show="ChartBoxShow" :chart-data="lineChartData" :height="chartHeight" />
-
<el-empty v-show="!ChartBoxShow" description="暂无数据" />
-
</div>
-
</el-tab-pane>
-
</template>
-
</el-tabs>
-
</el-col>
-
<el-col v-if="activeChart === 'first' || activeChart === 'second'" v-hasPermi="['price:trend:query']" :span="8">
-
<div v-dompurify-html.trim="coalAnalyze" class="artitle" :style="{ height: chartHeight }" />
-
</el-col>
-
<el-col v-if="activeChart === 'first' || activeChart === 'second'" v-hasPermi="['price:trend:query']" :span="24" class="explainBox">
-
<div v-dompurify-html.trim="coalExplain" class="artitle" />
-
</el-col>
-
</el-row>
-
</section>
-
</div>
-
</template>
-
-
<script>
-
import LineChart from '@/components/Echarts/LineCharts';
-
import { coalIndex, getGraph, getGraph2, getPreIindex, getReport } from '@/api/trend';
-
import { debounce, getTime, setMyOpts, sortSeriesByMaxValue } from '@/utils/global.js';
-
-
export default {
-
name: 'Trend',
-
components: {
-
LineChart,
-
},
-
data() {
-
return {
-
loading: true, // 遮罩层
-
isPer: false, //判断是否具有某个权限
-
// 图表
-
chartTitle: '标题',
-
chartHeight: '0', //设置图表高度
-
lineChartData: {}, // 图表数据
-
ChartBoxShow: true, //图表有无数据,是否显示
-
// 解释文字/后台输出的文字内容
-
coalAnalyze: '',
-
coalExplain: '',
-
// 选项卡
-
activeChart: this.isPer ? 'second' : 'three',
-
tabs: [
-
{
-
title: '总预测趋势图',
-
name: 'first',
-
isPer: false,
-
},
-
{
-
title: '区间预测图',
-
name: 'second',
-
isPer: false,
-
},
-
{
-
title: '预测指数图',
-
name: 'three',
-
},
-
{
-
title: '周环比分析图',
-
name: 'four',
-
},
-
],
-
};
-
},
-
computed: {
-
permissions() {
-
return this.$store.getters.permissions;
-
},
-
},
-
watch: {
-
isPer: {
-
handler: function(newVal) {
-
this.tabs = this.tabs.map(item => {
-
if (item.hasOwnProperty('isPer')) {
-
item['isPer'] = newVal;
-
}
-
return item;
-
});
-
},
-
deep: true,
-
},
-
},
-
created() {
-
this.isPer = this.permissions.some(permission => {
-
return '*:*:*' === permission || ['price:trend:query'].includes(permission);
-
});
-
this.activeChart = this.isPer ? 'second' : 'three';
-
// 设置图表高度
-
this.setChartHeight();
-
// 提交表单
-
this.getSubmit(this.queryParams);
-
this.getSubmit = debounce(function(data) {
-
this.handleClick2({ name: this.activeChart });
-
getReport().then(res => {
-
this.coalExplain = res.data
-
.map(item => {
-
if (!item.title.includes('分析')) {
-
return `
-
<h3>${item.title.includes('、') ? item.title.split('、')[1] : item.title}</h3>
-
<p>${item.desc.replace(/\r\n/gm, '<br/>')}</p>
-
`;
-
}
-
})
-
.join('');
-
this.coalAnalyze = res.data
-
.map(item => {
-
if (item.title.includes('分析')) {
-
return `
-
<h3>${item.title.includes('、') ? item.title.split('、')[1] : item.title}</h3>
-
<p>${item.desc.replace(/\r\n/gm, '<br/>')}</p>
-
`;
-
}
-
})
-
.join('');
-
});
-
});
-
},
-
methods: {
-
handleClick2(val) {
-
let obj = {
-
first: {
-
title: '1',
-
api: getGraph,
-
},
-
second: {
-
title: '1',
-
api: getGraph2,
-
},
-
three: {
-
title: '2',
-
api: getPreIindex,
-
},
-
four: {
-
title: '3',
-
api: getPreIindex,
-
},
-
// four: () => {
-
// return new Promise(async resolve => {
-
// this.chartTitle = '周环比分析';
-
// this.loading = true;
-
// let res = getPreIindex();
-
// resolve(res);
-
// });
-
// },
-
};
-
if (!obj[val.name].title || !obj[val.name].api) {
-
return;
-
}
-
this.getCharts(obj[val.name].title, obj[val.name].api).then(({ res, title }) => {
-
this.loading = false;
-
this.chartTitle = title;
-
this.ChartBoxShow = res['data'] ? true : false;
-
if (this.ChartBoxShow) {
-
let myChart = this.$store.state.echarts.init[0];
-
const customObj = {
-
first: {
-
title: {
-
subtext: '',
-
},
-
legend: {
-
top: '34px',
-
right: 'auto',
-
orient: 'horizontal',
-
},
-
grid: {
-
width: '72%',
-
top: '76px',
-
left: '38',
-
},
-
series: item => {
-
if (item.type === 'scatter') {
-
if (typeof item.label.formatter == 'string') {
-
return {
-
color: 'rgb(231,90,110)',
-
label: {
-
backgroundColor: 'rgba(231,90,110,.3)',
-
},
-
labelLayout: {
-
with: 160,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
return {
-
labelLayout() {
-
return {
-
width: typeof item.label.formatter == 'string' ? 160 : 140,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
};
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
} else {
-
if (item.name.includes('动力煤连续合约')) {
-
return {
-
markLine: null,
-
markPoint: {
-
symbol: 'circle',
-
symbolSize: 10,
-
label: {
-
show: false,
-
},
-
},
-
};
-
}
-
return {
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
},
-
},
-
second: {
-
legend: {
-
top: '48px',
-
right: 'auto',
-
orient: 'horizontal',
-
},
-
grid: {
-
width: '72%',
-
top: '76px',
-
left: '38',
-
},
-
series: item => {
-
if (item.type === 'scatter') {
-
if (typeof item.label.formatter == 'string') {
-
return {
-
color: 'rgb(231,90,110)',
-
label: {
-
backgroundColor: 'rgba(231,90,110,.3)',
-
},
-
labelLayout: {
-
with: 160,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
return {
-
labelLayout: {
-
with: 140,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
} else {
-
if (item.name.includes('动力煤连续合约')) {
-
return {
-
markLine: null,
-
markPoint: {
-
symbol: 'circle',
-
symbolSize: 10,
-
label: {
-
show: false,
-
},
-
},
-
};
-
}
-
if (item.name.includes('预测值上限') || item.name.includes('预测值下限')) {
-
return {
-
itemStyle: {
-
color: '#aaaaaa',
-
borderColor: '#aaaaaa',
-
},
-
lineStyle: {
-
color: '#aaaaaa',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
return {
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
},
-
},
-
three: {
-
legend: {
-
top: '48px',
-
right: 'auto',
-
orient: 'horizontal',
-
},
-
grid: {
-
width: '96%',
-
top: '76px',
-
left: '38',
-
},
-
yAxis: [
-
{
-
name: '',
-
},
-
],
-
series: item => {
-
if (item.type === 'scatter') {
-
return {
-
labelLayout: {
-
with: 140,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
} else {
-
return {
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
},
-
},
-
four: {
-
legend: {
-
top: '48px',
-
right: 'auto',
-
orient: 'horizontal',
-
},
-
grid: {
-
width: '96%',
-
top: '76px',
-
left: '38',
-
},
-
yAxis: [
-
{
-
name: '',
-
},
-
],
-
series: item => {
-
if (item.type === 'scatter') {
-
return {
-
labelLayout: {
-
with: 140,
-
x: myChart.getWidth() - 120,
-
draggable: true,
-
verticalAlign: 'middle',
-
},
-
markPoint: null,
-
markLine: null,
-
};
-
} else {
-
return {
-
markPoint: null,
-
markLine: null,
-
};
-
}
-
},
-
},
-
};
-
let custom = customObj[val.name];
-
this.lineChartData = setMyOpts(sortSeriesByMaxValue(res['data']), custom);
-
}
-
});
-
},
-
getCharts(title, api) {
-
return new Promise(async resolve => {
-
if (typeof api == 'function') {
-
this.loading = true;
-
let res = await api();
-
resolve({ res, title });
-
}
-
});
-
},
-
setChartHeight() {
-
// 设置图表高度
-
let halfWidth = (document.documentElement.clientWidth / 2) * 0.74;
-
this.chartHeight = (halfWidth / 4) * 3 'px';
-
window.onresize = () => {
-
return (() => {
-
halfWidth = (document.documentElement.clientWidth / 2) * 0.74;
-
this.chartHeight = (halfWidth / 4) * 3 'px';
-
})();
-
};
-
},
-
},
-
};
-
</script>
-
<style lang="scss" scoped>
-
@import '@/assets/styles/explain.scss';
-
.chartTitle {
-
text-align: center;
-
@include themeify {
-
color: themed('main-font-color');
-
}
-
}
-
.formBox {
-
margin: 0 0 30px;
-
}
-
.explainBox {
-
margin-top: 30px;
-
}
-
::v-deep .artitle {
-
margin-top: 0;
-
font-size: 16px;
-
}
-
::v-deep .artitle h3 {
-
margin: 6px auto 14px;
-
text-indent: 0;
-
font-size: 24px;
-
// font-weight: normal;
-
}
-
::v-deep .artitle p {
-
width: 98%;
-
line-height: 2;
-
margin: 10px auto;
-
text-indent: 0;
-
}
-
.trendTitle {
-
margin: 50px 0 20px;
-
text-align: left;
-
@include themeify {
-
color: themed('main-font-color');
-
}
-
}
-
.rangeSeparator {
-
display: inline-block;
-
height: 100%;
-
padding: 0 5px;
-
margin: 0;
-
text-align: center;
-
line-height: 32px;
-
font-size: 14px;
-
width: 5%;
-
@include themeify {
-
color: themed('main-font-color');
-
}
-
}
-
</style>
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhhkifee
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22