图是小红书博主格格不茹,以它为原型实现网站
1.实现一个card组件
所有页面都使用了卡片模式,所以将其生成一个卡片组件以便使用
1.卡片的宽高可自定义
2.卡面的标题和内容自定义
3.实现基本样式
4.不同单位最后的宽高是不同的,%需要减去padding的宽高,应该是可以使用box-sizing这个属性改变。
注意:最好是给一个默认值
在src/components中创建card文件夹-> 创建card-index.vue文件
<template>
<!-- 卡片样式模板 -->
<div class="card-style" :style="{ width: realWidth, height: realHeight }">
<div class="title">
<slot name="title"></slot>
</div>
<div class="content">
<slot name="content"></slot>
</div>
</div>
</template>
<script>
export default {
name: "Card",
props: {
// 卡片的宽度,默认200
cardWidth: {
type: Number,
default: 400,
},
// 卡片的高度,默认100
cardHeight: {
type: Number,
default: 250,
},
// 长宽单位,默认单位为px
unit: {
type: String,
default: "px",
},
},
computed: {
realWidth(val) {
if (val.unit === "%") {
return "calc(" + this.cardWidth + "% - 30px)";
} else {
return this.cardWidth + this.unit;
}
},
realHeight(val) {
if (val.unit === "%") {
return "calc(" + this.cardHeight + "% - 30px)";
} else {
return this.cardHeight + this.unit;
}
},
},
};
</script>
<style scoped lang="less">
.card-style {
background: #ffffff;
box-shadow: 0 4px 8px 0 #efefef, 0 6px 20px 0 #efefef;
border-radius: 10px;
padding: 15px;
}
.title {
color: #555555;
font-weight: 600;
font-size: 22px;
margin-left: 10px;
letter-spacing: 2px;
}
.content {
width: 100%;
height: calc(100% - 50px);
}
</style>
如何使用该组件呢?使用了父子组件传参,slot插槽
<template>
<card :cardWidth="cardWidth" :cardHeight="cardHeight" :unit="unit">
<template #title>本月支出占比</template>
</card>
</template>
<script>
// 引入组件
import Card from "@/components/card/card-index.vue";
export default {
name: "MonthPay",
components: {
Card,
},
data() {
return {
cardWidth: 100,
cardHeight: 34,
unit: "%",
};
},
};
</script>
<style scoped lang="less"></style>
2. vue中使用echarts
- 安装echarts
首先安装
npm install echarts --save
- 在文件中引入
import * as echarts from "echarts";
- 创建容器-注意容器需要在大小要不就会显示
<template>
<div id="barChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "Transaction",
data() {
return {
goodsData: [520,909,1769,841,977,1683,1138,1985,1512,758,1541,1482],
badsData: [129,72,190,238,208,8,34,37,64,64,116,95],
months: [1,2,3,4,5,6,7,8,9,10,11,12],
};
},
created() {
this.initCharts();
},
methods: {
initCharts() {
const options = {
tooltip: {
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
},
legend: {
data: ["好评", "差评"],
align: "right",
right: 10,
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: this.months,
},
],
yAxis: [
{
type: "value",
axisLabel: {
formatter: "{value}",
},
},
],
series: [
{
name: "好评",
type: "bar",
// 实现颜色的渐变
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#faa169",
},
{
offset: 1,
color: "#fed88c",
},
]),
data: this.goodsData,
},
{
name: "差评",
type: "bar",
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#70afc2",
},
{
offset: 1,
color: "#98d8c1",
},
]),
data: this.badsData,
},
],
};
const myChart = echarts.init(document.getElementById("barChart"));
myChart.setOption(options);
},
},
};
</script>
<style scoped lang="less">
#barChart {
height: 100%;
width: 100%;
}
</style>
- 如何查看echarts文档
官方文档地址:echarts.apache.org/zh/option.h…
比如我现在想实现给柱状图添加圆角
找到series->柱状图type是bar,找到对应的bar的属性->柱状图圆角是图形样式,找到itemStyle->找到对应的属性borderRadius,看右边文档怎么使用
所以我们需要在series中的itemStyle属性设置itemStyle
itemStyle: {
borderRadius: [5, 5, 0, 0],
},
const options = {
tooltip: {
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
},
legend: {
data: ["好评", "差评"],
align: "right",
right: 10,
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: this.months,
},
],
yAxis: [
{
type: "value",
axisLabel: {
formatter: "{value}",
},
},
],
series: [
{
name: "好评",
type: "bar",
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#faa169",
},
{
offset: 1,
color: "#fed88c",
},
]),
// 添加圆角
itemStyle: {
borderRadius: [5, 5, 0, 0],
},
data: this.goodsData,
},
{
name: "差评",
type: "bar",
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#70afc2",
},
{
offset: 1,
color: "#98d8c1",
},
]),
// 添加圆角
itemStyle: {
borderRadius: [5, 5, 0, 0],
},
data: this.badsData,
},
],
};
实现如下图
3.echarts中实现自适应
若不实现自适应,当我们窗口大小改变时,图表是不会变化的,如下图
在代码中添加就可以解决这个问题
window.onresize = function () {
myChart.resize();
};
<template>
<div id="barChart"></div>
</template>
<script>
import * as echarts from "echarts";
export default {
name: "Transaction",
data() {
return {
goodsData: [520,909,1769,841,977,1683,1138,1985,1512,758,1541,1482],
badsData: [129,72,190,238,208,8,34,37,64,64,116,95],
months: [1,2,3,4,5,6,7,8,9,10,11,12],
};
},
created() {
this.initCharts();
},
methods: {
initCharts() {
const options = {
tooltip: {
trigger: "axis",
axisPointer: {
// 坐标轴指示器,坐标轴触发有效
type: "shadow", // 默认为直线,可选为:'line' | 'shadow'
},
},
legend: {
data: ["好评", "差评"],
align: "right",
right: 10,
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
data: this.months,
},
],
yAxis: [
{
type: "value",
axisLabel: {
formatter: "{value}",
},
},
],
series: [
{
name: "好评",
type: "bar",
// 实现颜色的渐变
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#faa169",
},
{
offset: 1,
color: "#fed88c",
},
]),
data: this.goodsData,
},
{
name: "差评",
type: "bar",
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [
{
offset: 0,
color: "#70afc2",
},
{
offset: 1,
color: "#98d8c1",
},
]),
data: this.badsData,
},
],
};
const myChart = echarts.init(document.getElementById("barChart"));
myChart.setOption(options);
// 添加自适应
window.onresize = function () {
myChart.resize();
};
},
},
};
</script>
<style scoped lang="less">
#barChart {
height: 100%;
width: 100%;
}
</style>
4.解决左侧菜单栏刷新不高亮的问题
使用中发现,点击左侧菜单跳转后,菜单栏不能被高亮选中。若选择的是折叠的菜单的子菜单,刷新后菜单会折叠,并且菜单也不会被选中
需要用到default-active和router这两个属性
并且需要在路由中的meta中添加apiActiveMenu这个属性用来在menu中进行路径匹配
在menu.vue页面中el-menu-item和el-submenu中的index修改成对应的apiActiveMenu
activeRouter设置为$route.path
menu.vue全部代码如下
<template>
<div>
<div class="toggle-button" @click="toggleCollapse">
<span>|||</span>
</div>
<el-menu
class="menu-style"
background-color="#FDD78E"
text-color="#62504C"
active-text-color="#EFEFEF"
:collapse-transition="false"
:collapse="isCollapse"
unique-opened
router
:default-active="activeRouter"
>
<template v-for="item in menuList">
<el-submenu
v-if="item.children && item.children.length > 0"
:index="item.meta.apiActiveMenu"
:key="item.name"
>
<!-- 一级菜单 -->
<template slot="title">
<!-- 图标以及名称 -->
<i :class="item.meta.icon"></i>
<span class="title-style">{{ item.meta.name }}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item
v-for="subItem in item.children"
:index="subItem.meta.apiActiveMenu"
:key="subItem.name"
>
<i :class="subItem.meta.icon"></i>
<span class="title-style">{{ subItem.meta.name }}</span>
</el-menu-item>
</el-submenu>
<el-menu-item v-else :index="item.meta.apiActiveMenu" :key="item.path">
<i :class="item.meta.icon"></i>
<span class="title-style">{{ item.meta.name }}</span>
</el-menu-item>
</template>
</el-menu>
</div>
</template>
<script>
export default {
name: "Menu",
data() {
return {
isCollapse: false,
menuList: [],
activeRouter: "",
};
},
created() {
this.menuList = this.$store.state.permission.sidebarMenu;
this.activeRouter = this.$route.path;
},
methods: {
toggleCollapse() {
this.isCollapse = !this.isCollapse;
this.$emit("toggleCollapse", this.isCollapse);
},
gotoRoute(pathName) {
this.$router
.push({
name: pathName,
})
.catch((err) => {
console.log(err);
});
},
},
};
</script>
<style lang="less" scoped>
.toggle-button {
background-color: #fdd78e;
color: #6e595d;
padding: 6px;
line-height: 24px;
cursor: pointer;
letter-spacing: 0.1em;
text-align: center;
}
.menu-style {
width: 80%;
border: none;
margin: 5%;
}
.el-menu-item.is-active {
background-color: #624e4e !important;
border-radius: 15px;
font-weight: 600;
}
.el-submenu .el-menu-item {
min-width: 120px;
}
.el-menu-item:hover,
.el-menu-item:focus {
background-color: rgba(98, 78, 78, 0.1);
border-radius: 15px;
}
/deep/ .el-submenu__title:hover,
.el-submenu__title:focus {
background-color: rgba(98, 78, 78, 0.1);
border-radius: 15px;
}
.title-style {
padding-left: 10px;
}
</style>