diff --git a/stdiet-ui/src/store/modules/recipes.js b/stdiet-ui/src/store/modules/recipes.js index 3f3d903d7..ba1e69807 100644 --- a/stdiet-ui/src/store/modules/recipes.js +++ b/stdiet-ui/src/store/modules/recipes.js @@ -512,13 +512,13 @@ const getters = { (obj, cur) => { cur.igdList.forEach(igd => { obj.pWeight += (igd.weight / 100) * igd.proteinRatio; - obj.pHeat = obj.pWeight * 4; + obj.pCalories = obj.pWeight * 4; obj.fWeight += (igd.weight / 100) * igd.fatRatio; - obj.fHeat = obj.fWeight * 9; + obj.fCalories = obj.fWeight * 9; obj.cWeight += (igd.weight / 100) * igd.carbonRatio; - obj.cHeat = obj.cWeight * 4; - obj.totalHeat = obj.pHeat + obj.fHeat + obj.cHeat; - obj[`heat${cur.type}`] += + obj.cCalories = obj.cWeight * 4; + obj.totalCalories = obj.pCalories + obj.fCalories + obj.cCalories; + obj[`calories${cur.type}`] += (igd.weight / 100) * igd.proteinRatio * 4 + (igd.weight / 100) * igd.fatRatio * 9 + (igd.weight / 100) * igd.carbonRatio * 4; @@ -532,17 +532,17 @@ const getters = { pWeight: 0, fWeight: 0, cWeight: 0, - pHeat: 0, - fHeat: 0, - cHeat: 0, + pCalories: 0, + fCalories: 0, + cCalories: 0, // - totalHeat: 0, - heat1: 0, - heat2: 0, - heat3: 0, - heat4: 0, - heat5: 0, - heat6: 0, + totalCalories: 0, + calories1: 0, + calories2: 0, + calories3: 0, + calories4: 0, + calories5: 0, + calories6: 0, // totalWeight: 0, weight1: 0, @@ -554,7 +554,7 @@ const getters = { } ) ); - console.log(nutriData); + // console.log(nutriData); return nutriData; }, verifyNotRecData: state => { diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/BarChart/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/BarChart/index.vue deleted file mode 100644 index 6fdfab1c9..000000000 --- a/stdiet-ui/src/views/custom/recipesBuild/InfoView/BarChart/index.vue +++ /dev/null @@ -1,180 +0,0 @@ -<template> - <div :class="className" :style="{ height: height, width: width }" /> -</template> - -<script> -import echarts from "echarts"; -import VueScrollTo from "vue-scrollto"; -require("@/utils/echarts/myShine"); -import resize from "@/views/dashboard/mixins/resize"; -import { createNamespacedHelpers } from "vuex"; -const { mapMutations } = createNamespacedHelpers("recipes"); -const animationDuration = 6000; - -export default { - mixins: [resize], - props: { - className: { - type: String, - default: "chart", - }, - width: { - type: String, - default: "100%", - }, - height: { - type: String, - default: "300px", - }, - data: { - type: Array, - default: [], - }, - max: { - type: Number, - default: 0, - }, - }, - data() { - return { - chart: null, - nameDict: { - pHeat: "蛋白质", - fHeat: "脂肪", - cHeat: "碳水", - }, - }; - }, - mounted() { - this.$nextTick(() => { - this.initChart(); - }); - }, - beforeDestroy() { - if (!this.chart) { - return; - } - this.chart.dispose(); - this.chart = null; - }, - updated() { - // console.log("updated"); - }, - methods: { - ...mapMutations(["setCurrentDay"]), - initChart() { - this.chart = echarts.init(this.$el, "myShine"); - this.chart.on("click", this.handleOnClick); - this.updateChart(this.data.length > 0 ? this.data : {}); - }, - updateChart(source) { - // console.log(this.max); - this.chart.clear(); - this.chart.setOption({ - title: { - text: "营养统计", - }, - tooltip: { - trigger: "axis", - // appendToBody: true, - formatter: (params) => { - // console.log(params); - const [param] = params; - const { name } = param; - let totalHeat = 0; - const tooltips = params.reduce( - (arr, cur) => { - const { value, seriesName } = cur; - const nutriName = this.nameDict[seriesName]; - totalHeat += value[seriesName]; - const heatVal = value[seriesName].toFixed(1); - const weightVal = value[ - `${seriesName.substring(0, 1)}Weight` - ].toFixed(1); - arr.push( - `${cur.marker} ${nutriName}:${weightVal}克(${heatVal}千卡)` - ); - return arr; - }, - [name] - ); - tooltips[0] += ` - 共${totalHeat.toFixed(1)}千卡`; - return tooltips.join("</br>"); - }, - }, - dataset: { - dimensions: [ - "name", - "pWeight", - "pHeat", - "fWeight", - "fHeat", - "cWeight", - "cHeat", - ], - source, - }, - grid: { - top: 50, - left: 10, - right: 50, - bottom: 10, - containLabel: true, - }, - xAxis: { - type: "category", - // axisLabel: { - // rotate: 45, - // }, - }, - yAxis: { - type: "value", - name: "热量/千卡", - nameTextStyle: { - color: "#262626", - fontSize: 12, - }, - }, - series: ["pHeat", "fHeat", "cHeat"].map((dim, idx) => ({ - name: dim, - type: "bar", - barWidth: 24, - stack: "bar", - encode: { - y: dim, - x: 0, - }, - markLine: { - data: [{ name: "BMR", yAxis: this.max ? this.max - 400 : 0 }], - symbol: "none", - lineStyle: { - color: "#d96969", - }, - }, - itemStyle: { - borderWidth: 2, - borderColor: "#fff", - }, - })), - }); - }, - handleOnClick(params) { - // console.log(params); - const { dataIndex } = params; - this.setCurrentDay({ currentDay: dataIndex }); - VueScrollTo.scrollTo(`#recipes${dataIndex}`, 500, { - container: "#recipes_content", - }); - }, - }, - watch: { - data(newVal, oldVal) { - if (newVal) { - this.$nextTick(() => { - this.updateChart(newVal); - }); - } - }, - }, -}; -</script> diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/PieChart/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/PieChart/index.vue new file mode 100644 index 000000000..00c9a7c7c --- /dev/null +++ b/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/PieChart/index.vue @@ -0,0 +1,276 @@ +<template> + <div ref="echart" :style="{ height: height, width: width }" /> +</template> + +<script> +import echarts from "echarts"; +require("@/utils/echarts/myShine"); +import resize from "@/views/dashboard/mixins/resize"; +import { createNamespacedHelpers } from "vuex"; +const { mapMutations, mapState } = createNamespacedHelpers("recipes"); + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: "chart", + }, + width: { + type: String, + default: "100%", + }, + height: { + type: String, + default: "200px", + }, + data: { + type: Array, + default: [], + }, + subTitle: { + type: String, + default: "", + }, + title: { + type: String, + default: "", + }, + type: { + type: String, + default: "", + }, + }, + data() { + return { + chart: null, + }; + }, + computed: {}, + mounted() { + this.$nextTick(() => { + this.initChart(); + }); + }, + beforeDestroy() { + if (!this.chart) { + return; + } + this.chart.dispose(); + this.chart = null; + }, + methods: { + initChart() { + this.chart = echarts.init(this.$refs.echart, "myShine"); + if (this.data.length > 0) { + this.updateChart(this.data); + } + }, + backToAll() { + this.resetCurrentDay({ currentDay: -1 }); + }, + getTooltipArr(params) { + console.log(params); + let tooltips; + const { name, marker, percent, value } = params; + switch (this.type) { + case "nutrition": + const weight = value[1] / (name === "脂肪" ? 9 : 4); + tooltips = [ + `${marker} ${name}`, + `摄入量:${weight.toFixed(1)}克`, + `摄入热量:${value[1].toFixed(1)}千卡`, + `供能比:${percent}%`, + ]; + break; + case "calories": + tooltips = [ + `${marker} ${name}`, + `热量:${value[1].toFixed(1)}千卡`, + `占比:${percent}%`, + ]; + break; + case "weight": + tooltips = [ + `${marker} ${name}`, + `质量:${value[1].toFixed(1)}克`, + `占比:${percent}%`, + ]; + break; + } + return tooltips.join("</br>"); + }, + updateChart(source) { + console.log(source); + const total = source.reduce((acc, cur) => acc + cur[1], 0); + this.chart.clear(); + const option = { + title: { + text: this.title, + subtext: this.subTitle, + }, + legend: { + left: 100, + itemWidth: 8, + itemHeight: 8, + pageIconSize: 10, + textStyle: { + fontSize: 10, + }, + }, + dataset: { + source, + }, + tooltip: { + trigger: "item", + appendToBody: true, + formatter: this.getTooltipArr, + }, + graphic: [ + { + type: "group", + top: 60, + left: 10, + silent: true, + children: [ + { + type: "text", + style: { + text: this.type === "weight" ? "总质量" : "总热量约", + fill: "#606266", + }, + }, + { + type: "text", + top: 18, + left: 8, + style: { + text: `${total.toFixed(1)}${ + this.type === "weight" ? "克" : "千卡" + }`, + font: '14px "Microsoft YaHei", sans-serif', + }, + }, + ], + }, + { + type: "group", + top: 36, + right: 10, + silent: true, + children: source.map((item, idx) => { + const data = + this.type == "nutrition" + ? item[1] / (idx === 1 ? 9 : 4) + : item[1]; + return { + type: "text", + top: idx * 20, + right: 10, + style: { + text: `${item[0]}:${data.toFixed(1)}${ + this.type === "calories" ? "千卡" : "克" + }`, + fill: "#606266", + }, + }; + }), + }, + ], + series: [ + { + type: "pie", + radius: [0, 60], + center: ["50%", "55%"], + // labelLine: { + // length: 5, + // length2: 5, + // }, + label: { + show: true, + position: "inside", + color: "#fff", + fontSize: 12, + fontWeight: "bold", + }, + itemStyle: { + borderWidth: 1, + borderColor: "#fff", + }, + }, + ], + }; + // console.log(option); + this.chart.setOption(option); + }, + }, + watch: { + data(newVal, oldVal) { + if (newVal) { + this.$nextTick(() => { + this.updateChart(newVal); + }); + } + }, + }, +}; +</script> +<style lang="scss" scoped> +/deep/ :focus { + outline: 0; +} + +.aspect_pie_chart_wrapper { + width: 100%; + display: flex; + position: relative; + + & > div:nth-child(1) { + // width: 200px + } + + .small_table { + .my_cell { + padding: 2px 0 !important; + } + } + + .summary { + padding: 2px; + border-bottom: 1px solid #dfe6ec; + border-left: 1px solid #dfe6ec; + border-right: 1px solid #dfe6ec; + + & > div { + padding: 3px; + text-align: center; + } + } + + .see_all { + position: absolute; + bottom: 4px; + left: 24px; + padding: 0; + } + + .icon_btns { + position: absolute; + right: 0; + + em { + display: inline-block; + padding: 4px; + cursor: pointer; + } + + .sel_icon { + color: #1890ff; + } + } + + .table_zone { + margin-top: 26px; + } +} +</style> diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/index.vue new file mode 100644 index 000000000..d072c16a1 --- /dev/null +++ b/stdiet-ui/src/views/custom/recipesBuild/InfoView/DailyAnalyzeCom/index.vue @@ -0,0 +1,110 @@ +<template> + <div class="daily_analyze_com_wrapper"> + <pie-chart + title="营养统计" + :data="nutritionSource" + type="nutrition" + :subTitle="subTitle" + /> + <pie-chart + title="热量统计" + :data="caloriesSource" + type="calories" + :subTitle="subTitle" + /> + <pie-chart + title="质量统计" + :data="weightSource" + type="weight" + :subTitle="subTitle" + /> + <el-button size="mini" type="text" @click="backToAll" class="see_all" + >查看全部</el-button + > + </div> +</template> +<script> +import PieChart from "./PieChart"; +import { createNamespacedHelpers } from "vuex"; +const { mapGetters, mapMutations } = createNamespacedHelpers("recipes"); +export default { + name: "DailyAnalyzeCom", + data() { + return { + subTitle: "", + }; + }, + components: { + PieChart, + }, + methods: { + backToAll() { + this.resetCurrentDay({ currentDay: -1 }); + }, + ...mapMutations(["resetCurrentDay"]), + }, + computed: { + nutritionSource() { + const [data] = this.analyseData; + this.subTitle = data.name; + return [ + ["蛋白质", data.pCalories], + ["脂肪", data.fCalories], + ["碳水", data.cCalories], + ]; + }, + caloriesSource() { + const [data] = this.analyseData; + const source = [ + ["早餐", data.calories1], + ["午餐", data.calories3], + ["晚餐", data.calories5], + ]; + if (data.calories2) { + source.push(["早加餐", data.calories2]); + } + if (data.calories4) { + source.push(["午加餐", data.calories4]); + } + if (data.calories6) { + source.push(["晚加餐", data.calories6]); + } + return source; + }, + weightSource() { + const [data] = this.analyseData; + const source = [ + ["早餐", data.weight1], + ["午餐", data.weight3], + ["晚餐", data.weight5], + ]; + if (data.weight2) { + source.push(["早加餐", data.weight2]); + } + if (data.weight4) { + source.push(["午加餐", data.weight4]); + } + if (data.weight6) { + source.push(["晚加餐", data.weight6]); + } + return source; + }, + ...mapGetters(["analyseData"]), + }, +}; +</script> +<style lang="scss" scoped> +.daily_analyze_com_wrapper { + position: relative; + & > div:not(:nth-child(1)) { + margin-top: 12px; + } + + .see_all { + position: absolute; + top: 0; + right: 0; + } +} +</style> + diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/BarChart/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/BarChart/index.vue new file mode 100644 index 000000000..cc9489a3e --- /dev/null +++ b/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/BarChart/index.vue @@ -0,0 +1,221 @@ +<template> + <div :class="className" :style="{ height: height, width: width }" /> +</template> + +<script> +import echarts from "echarts"; +require("@/utils/echarts/myShine"); +import resize from "@/views/dashboard/mixins/resize"; +const animationDuration = 6000; + +export default { + mixins: [resize], + props: { + className: { + type: String, + default: "chart", + }, + width: { + type: String, + default: "100%", + }, + height: { + type: String, + default: "180px", + }, + data: { + type: Array, + default: [], + }, + max: { + type: Number, + default: 0, + }, + title: { + type: String, + default: "", + }, + type: { + type: String, + default: "", + }, + }, + data() { + return { + chart: null, + }; + }, + mounted() { + this.$nextTick(() => { + this.initChart(); + }); + }, + beforeDestroy() { + if (!this.chart) { + return; + } + this.chart.dispose(); + this.chart = null; + }, + computed: {}, + updated() { + // console.log("updated"); + }, + methods: { + initChart() { + this.chart = echarts.init(this.$el, "myShine"); + this.chart.on("click", this.handleOnClick); + if (this.data.length > 0) { + this.updateChart(this.data); + } + }, + getTooltipArr(params) { + // console.log(params); + const [param] = params; + const { name } = param; + let tooltips; + let total = 0; + switch (this.type) { + case "nutrition": + tooltips = params.reduce( + (arr, cur) => { + const { value, seriesName, seriesIndex, marker } = cur; + const calories = value[seriesIndex + 1]; + total += calories; + const weight = ( + calories / (seriesName === "脂肪" ? 9 : 4) + ).toFixed(1); + arr.push( + `${marker} ${seriesName}:${weight}克(${calories.toFixed( + 1 + )}千卡)` + ); + return arr; + }, + [name] + ); + tooltips[0] += ` - 约${total.toFixed(1)}千卡`; + break; + case "calories": + tooltips = params.reduce( + (arr, cur) => { + const { value, seriesName, seriesIndex, marker } = cur; + const calories = value[seriesIndex + 1]; + total += calories; + if (calories) { + arr.push(`${marker} ${seriesName}:${calories.toFixed(1)}千卡`); + } + return arr; + }, + [name] + ); + tooltips[0] += ` - 约${total.toFixed(1)}千卡`; + break; + case "weight": + tooltips = params.reduce( + (arr, cur) => { + const { value, seriesName, seriesIndex, marker } = cur; + const weight = value[seriesIndex + 1]; + total += weight; + if (weight) { + arr.push(`${marker} ${seriesName}:${weight.toFixed(1)}克`); + } + return arr; + }, + [name] + ); + tooltips[0] += ` - 共${total.toFixed(1)}克`; + break; + } + return tooltips.join("</br>"); + }, + updateChart(source) { + // console.log(this.max); + // console.log(source); + this.chart.clear(); + const option = { + title: { + text: this.title, + }, + legend: { + // type: "scroll", + left: 100, + itemWidth: 8, + itemHeight: 8, + pageIconSize: 10, + textStyle: { + fontSize: 10, + }, + }, + tooltip: { + trigger: "axis", + appendToBody: true, + formatter: this.getTooltipArr, + }, + dataset: { + source, + }, + grid: { + top: 50, + left: 10, + right: 50, + bottom: 10, + containLabel: true, + }, + xAxis: { + type: "category", + // axisLabel: { + // rotate: 45, + // }, + }, + yAxis: { + type: "value", + name: this.type === "weight" ? "质量/克" : "热量/千卡", + nameTextStyle: { + color: "#262626", + fontSize: 10, + }, + }, + series: source[0].slice(1).map((name, idx) => ({ + name, + type: "bar", + barWidth: 24, + stack: "bar", + encode: { + y: idx + 1, + x: 0, + }, + itemStyle: { + borderWidth: 2, + borderColor: "#fff", + }, + })), + }; + if (this.max) { + option.series[0].markLine = { + data: [{ name: "BMR", yAxis: this.max ? this.max - 400 : 0 }], + symbol: "none", + lineStyle: { + color: "#d96969", + }, + }; + } + this.chart.setOption(option); + }, + handleOnClick(params) { + // console.log(params); + const { dataIndex } = params; + this.$emit("onClick", dataIndex); + }, + }, + watch: { + data(newVal, oldVal) { + if (newVal) { + this.$nextTick(() => { + this.updateChart(newVal); + }); + } + }, + }, +}; +</script> diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/index.vue new file mode 100644 index 000000000..4b32c5999 --- /dev/null +++ b/stdiet-ui/src/views/custom/recipesBuild/InfoView/WeaklyAnalyzeCom/index.vue @@ -0,0 +1,110 @@ +<template> + <div class="weakly_analyze_com_wrapper"> + <bar-chart + :data="nutritionSource" + :max="max" + title="营养统计" + type="nutrition" + @onClick="handleOnClick" + /> + <bar-chart + :data="caloriesSource" + title="热量统计" + type="calories" + @onClick="handleOnClick" + /> + <bar-chart + :data="weightSource" + title="质量统计" + type="weight" + @onClick="handleOnClick" + /> + </div> +</template> +<script> +import { createNamespacedHelpers } from "vuex"; +const { mapState, mapGetters, mapMutations } = createNamespacedHelpers( + "recipes" +); +import VueScrollTo from "vue-scrollto"; +import BarChart from "./BarChart"; +export default { + name: "WeaklyAnalyzeCom", + components: { + BarChart, + }, + data() { + return {}; + }, + props: ["data"], + methods: { + handleOnClick(currentDay) { + this.setCurrentDay({ currentDay }); + VueScrollTo.scrollTo(`#recipes${currentDay}`, 500, { + container: "#recipes_content", + }); + }, + ...mapMutations(["setCurrentDay"]), + }, + computed: { + nutritionSource() { + return this.analyseData.reduce( + (arr, cur) => { + arr.push([cur.name, cur.pCalories, cur.fCalories, cur.cCalories]); + return arr; + }, + [["日期", "蛋白质", "脂肪", "碳水"]] + ); + }, + caloriesSource() { + return this.analyseData.reduce( + (arr, cur) => { + arr.push([ + cur.name, + cur.calories1, + cur.calories2, + cur.calories3, + cur.calories4, + cur.calories5, + cur.calories6, + ]); + return arr; + }, + [["日期", "早餐", "早加餐", "午餐", "午加餐", "晚餐", "晚加餐"]] + ); + }, + weightSource() { + return this.analyseData.reduce( + (arr, cur) => { + arr.push([ + cur.name, + cur.weight1, + cur.weight2, + cur.weight3, + cur.weight4, + cur.weight5, + cur.weight6, + ]); + return arr; + }, + [["日期", "早餐", "早加餐", "午餐", "午加餐", "晚餐", "晚加餐"]] + ); + }, + max() { + const { basicBMR } = this.healthyData || {}; + return basicBMR + ? parseFloat(basicBMR.substring(0, basicBMR.indexOf("千卡"))) + : 0; + }, + ...mapState(["healthyData"]), + ...mapGetters(["analyseData"]), + }, +}; +</script> +<style lang="scss" scoped> +.weakly_analyze_com_wrapper { + & > div:not(:nth-child(1)) { + margin-top: 12px; + } +} +</style> diff --git a/stdiet-ui/src/views/custom/recipesBuild/InfoView/index.vue b/stdiet-ui/src/views/custom/recipesBuild/InfoView/index.vue index 80f9ef9f2..a380e04f6 100644 --- a/stdiet-ui/src/views/custom/recipesBuild/InfoView/index.vue +++ b/stdiet-ui/src/views/custom/recipesBuild/InfoView/index.vue @@ -1,50 +1,46 @@ <template> <div class="recipes_build_info_view_wrapper"> - <div class="top" v-if="showChart"> - <BarChart - v-if="analyseData.length > 1" - :data="analyseData" - height="160px" - width="100%" - :max="max" - /> - <PieChart - v-if="analyseData.length === 1" - :data="analyseData" - height="160px" - width="100%" - /> - </div> - <div - class="content" - :style="`height: calc(100vh - ${showChart ? 192 : 32}px);`" - > - <TemplateInfoView v-if="!!temId" :data="templateInfo" /> - <HealthyView :data="healthyData" v-else-if="healthyDataType === 0" dev /> - <BodySignView :data="healthyData" v-else dev /> - </div> + <el-tabs v-model="activeName" @tab-click="handleOnTabClick"> + <el-tab-pane label="食谱分析" name="0" v-if="showChart"> + <div class="content"> + <WeaklyAnalyzeCom v-if="analyseData.length > 1" /> + <DailyAnalyzeCom v-else /> + </div> + </el-tab-pane> + <el-tab-pane label="模板信息" name="1" v-if="!!temId"> + <div class="content"> + <TemplateInfoView :data="templateInfo" /> + </div> + </el-tab-pane> + <el-tab-pane label="客户信息" name="2" v-else> + <div class="content"> + <HealthyView :data="healthyData" v-if="healthyDataType === 0" dev /> + <BodySignView :data="healthyData" v-else dev /> + </div> + </el-tab-pane> + </el-tabs> </div> </template> <script> import { createNamespacedHelpers } from "vuex"; const { mapActions, mapState, mapGetters } = createNamespacedHelpers("recipes"); -import BarChart from "./BarChart"; -import PieChart from "./PieChart"; import TemplateInfoView from "./TemplateInfoView"; import HealthyView from "@/components/HealthyView"; import BodySignView from "@/components/BodySignView"; +import WeaklyAnalyzeCom from "./WeaklyAnalyzeCom"; +import DailyAnalyzeCom from "./DailyAnalyzeCom"; export default { name: "InfoView", data() { const { temId } = this.$route.query; - return { temId }; + return { temId, activeName: "0" }; }, components: { - BarChart, - PieChart, HealthyView, BodySignView, TemplateInfoView, + WeaklyAnalyzeCom, + DailyAnalyzeCom, }, computed: { max() { @@ -64,16 +60,18 @@ export default { ]), ...mapGetters(["analyseData"]), }, + methods: { + handleOnTabClick(tab) { + this.activeName = tab.name; + }, + }, }; </script> <style lang="scss" scoped> .recipes_build_info_view_wrapper { - .top { - height: 160px; - } - .content { overflow: auto; + height: calc(100vh - 88px); } } </style>