【Vue3+Vite+TS】6.0 组件四:趋势标记
必备UI组件
图标选择器将用到的组件:
无
组件设计
新建src\components\baseline\trend\src\index.vue
<template>
<div>
<div class="bs-wrapper">
<div class="text">{{ text }}</div>
<div class="icon">
<el-icon-arrowup
:style="{ color: upIconColor }"
v-if="type === 'up'"
></el-icon-arrowup>
<el-icon-arrowdown
:style="{ color: downIconColor }"
v-else
></el-icon-arrowdown>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
const props = defineProps({
//说明:标记当前趋势:上升(up)下降(down)
type: {
type: String,
default: 'up',
},
//说明:趋势显示的文字
//父组件传递过来的值或者插槽
text: {
type: String,
default: '',
},
upIconColor: {
type: String,
default: '#f5222d',
},
downIconColor: {
type: String,
default: '#52c41a',
},
})
</script>
<style lang="scss" scoped>
.bs-wrapper {
display: flex;
align-items: center;
.text {
font-size: 0.12rem;
margin-right: 0.04rem;
}
.icon {
svg {
width: 0.2rem;
height: 0.2rem;
}
}
}
</style>
新建src\components\baseline\trend\index.ts
import { App } from 'vue'
import Trend from './src/index.vue'
export { Trend }
//组件可通过use的形式使用
export default {
Trend,
install(app: App) {
app.component('bs-trend', Trend)
},
}
修改src\components\baseline\index.ts
import { App } from 'vue'
import ChooseArea from './chooseArea'
import ChooseIcon from './chooseIcon'
import Container from './container'
import Trend from './trend'
const components = [ChooseArea, ChooseIcon, Container, Trend]
export { ChooseArea, ChooseIcon, Container, Trend }
//组件可通过use的形式使用
export default {
install(app: App) {
components.map(item => {
app.use(item)
})
},
ChooseArea,
ChooseIcon,
Container,
Trend,
}
新建src\views\trend\index.vue
<template>
<div class="bs-wrapper">
<div class="flex">
<div><bs-trend text="营业额"></bs-trend></div>
<div><bs-trend text="营业额" type="down"></bs-trend></div>
</div>
<br />
<div class="flex">
<div>
<bs-trend text="营业额" up-icon-color="#52c41a"></bs-trend>
</div>
<div>
<bs-trend
text="营业额"
down-icon-color="#f5222d"
type="down"
></bs-trend>
</div>
</div>
<br />
<div class="flex">
<div><bs-trend text="营业额"></bs-trend></div>
<div><bs-trend text="营业额" type="down"></bs-trend></div>
</div>
<br />
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
.flex {
display: flex;
}
div {
margin-right: 0.1rem;
}
}
</style>
效果如下:
将组件改写为插槽用法
颜色翻转
修改src\components\baseline\trend\src\index.vue
<template>
<div>
<div class="bs-wrapper">
<div class="text">
<slot v-if="slots.default"></slot>
<div v-else>{{ text }}</div>
</div>
<div class="icon">
<el-icon-arrowup
:style="{
color: !reverseColor
? upIconColor
: DOWN_ICON_COLOR_DEFAULT,
}"
v-if="type === 'up'"
></el-icon-arrowup>
<el-icon-arrowdown
:style="{
color: !reverseColor
? downIconColor
: UP_ICON_COLOR_DEFAULT,
}"
v-else
></el-icon-arrowdown>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useSlots } from 'vue'
const UP_ICON_COLOR_DEFAULT = '#f5222d'
const DOWN_ICON_COLOR_DEFAULT = '#52c41a'
const props = defineProps({
//说明:标记当前趋势:上升(up)下降(down)
type: {
type: String,
default: 'up',
},
//说明:趋势显示的文字
//父组件传递过来的值或者插槽
text: {
type: String,
default: '',
},
upIconColor: {
type: String,
default: '#f5222d',
},
downIconColor: {
type: String,
default: '#52c41a',
},
//颜色翻转只在默认的颜色下生效
reverseColor: {
type: Boolean,
default: false,
},
})
let slots = useSlots()
console.log(slots)
</script>
<style lang="scss" scoped>
.bs-wrapper {
display: flex;
align-items: center;
.text {
font-size: 0.12rem;
margin-right: 0.04rem;
}
.icon {
svg {
width: 0.2rem;
height: 0.2rem;
}
}
}
</style>
修改src\views\trend\index.vue
<template>
<div class="bs-wrapper">
<div class="flex">
<div><bs-trend text="营业额"></bs-trend></div>
<div><bs-trend text="营业额" type="down"></bs-trend></div>
</div>
<br />
<div class="flex">
<div>
<bs-trend text="营业额" up-icon-color="#52c41a"></bs-trend>
</div>
<div>
<bs-trend
text="营业额"
down-icon-color="#f5222d"
type="down"
></bs-trend>
</div>
</div>
<br />
<div class="flex">
<div>
<bs-trend text="营业额" :reverse-color="true"></bs-trend>
</div>
<div>
<bs-trend
text="营业额"
type="down"
:reverse-color="true"
></bs-trend>
</div>
</div>
<br />
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
.flex {
display: flex;
}
div {
margin-right: 0.1rem;
}
}
</style>
自定义文字颜色
<!--
* @Author: your name
* @Date: 2021-12-23 00:07:25
* @LastEditTime: 2021-12-24 18:32:39
* @LastEditors: Please set LastEditors
* @Description: 基础组件:趋势标记
* @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
<div>
<div class="bs-wrapper">
<div class="text" :style="{ color: textColor }">
<slot v-if="slots.default"></slot>
<div v-else>{{ text }}</div>
</div>
<div class="icon">
<el-icon-arrowup
:style="{
color: !reverseColor
? upIconColor
: DOWN_ICON_COLOR_DEFAULT,
}"
v-if="type === 'up'"
></el-icon-arrowup>
<el-icon-arrowdown
:style="{
color: !reverseColor
? downIconColor
: UP_ICON_COLOR_DEFAULT,
}"
v-else
></el-icon-arrowdown>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useSlots } from 'vue'
const UP_ICON_COLOR_DEFAULT = '#f5222d'
const DOWN_ICON_COLOR_DEFAULT = '#52c41a'
const props = defineProps({
//说明:标记当前趋势:上升(up)下降(down)
type: {
type: String,
default: 'up',
},
//说明:趋势显示的文字
//父组件传递过来的值或者插槽
text: {
type: String,
default: '',
},
upIconColor: {
type: String,
default: '#f5222d',
},
downIconColor: {
type: String,
default: '#52c41a',
},
textColor: {
type: String,
default: '',
},
//颜色翻转只在默认的颜色下生效
reverseColor: {
type: Boolean,
default: false,
},
})
let slots = useSlots()
console.log(slots)
</script>
<style lang="scss" scoped>
.bs-wrapper {
display: flex;
align-items: center;
.text {
font-size: 0.12rem;
margin-right: 0.04rem;
}
.icon {
svg {
width: 0.2rem;
height: 0.2rem;
}
}
}
</style>
自定义图标
修改src\components\baseline\trend\src\index.vue
<!--
* @Author: your name
* @Date: 2021-12-23 00:07:25
* @LastEditTime: 2021-12-24 22:58:58
* @LastEditors: Please set LastEditors
* @Description: 基础组件:趋势标记
* @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
<div>
<div class="bs-wrapper">
<div class="text" :style="{ color: textColor }">
<slot v-if="slots.default"></slot>
<div v-else>{{ text }}</div>
</div>
<div class="icon">
<component
:is="currentIcon"
:style="{
color: !reverseColor
? upIconColor
: DOWN_ICON_COLOR_DEFAULT,
}"
v-if="type === 'up'"
></component>
<component
:is="currentIcon"
:style="{
color: !reverseColor
? downIconColor
: UP_ICON_COLOR_DEFAULT,
}"
v-else
></component>
</div>
</div>
</div>
</template>
<script lang="ts">
/**
* 枚举类型限制type的值
*/
export enum EnumTrend {
UP = 'up',
DOWN = 'down',
}
</script>
<script lang="ts" setup>
import { ref, useSlots, watchEffect, PropType } from 'vue'
const UP_ICON_COLOR_DEFAULT = '#f5222d' //绿色
const DOWN_ICON_COLOR_DEFAULT = '#52c41a' //红色
const props = defineProps({
//说明:标记当前趋势:上升(up)下降(down)
type: {
type: String as PropType<EnumTrend.UP | EnumTrend.DOWN>,
default: EnumTrend.UP,
validator(value: any) {
return [EnumTrend.UP, EnumTrend.DOWN].includes(value)
},
},
//说明:趋势显示的文字
//父组件传递过来的值或者插槽
text: {
type: String,
default: '',
},
icon: {
type: String,
},
upIconColor: {
type: String,
default: '#f5222d',
},
downIconColor: {
type: String,
default: '#52c41a',
},
/**
* 文字颜色
*/
textColor: {
type: String,
default: '',
},
//颜色翻转只在默认的颜色下生效
reverseColor: {
type: Boolean,
default: false,
},
})
let slots = useSlots()
console.log(slots)
let currentIcon = ref<string>('')
/**
* 自定义图标
* watchEffect:会执行第一次
*/
watchEffect(() => {
if (props.icon == null && props.icon != '') {
if (props.type === 'up') {
currentIcon.value = 'el-icon-arrowup'
} else {
currentIcon.value = 'el-icon-arrowdown'
}
} else {
currentIcon.value = props.icon
}
})
</script>
<style lang="scss" scoped>
.bs-wrapper {
display: flex;
align-items: center;
.text {
font-size: 0.12rem;
margin-right: 0.04rem;
}
.icon {
svg {
width: 0.2rem;
height: 0.2rem;
}
}
}
</style>
这里用到ts的枚举、断言等语法,看客朋友们如果不太理解,请自行百度学习。
修改src\views\trend\index.vue
<!--
* @Author: your name
* @Date: 2021-12-23 00:07:25
* @LastEditTime: 2021-12-24 23:20:09
* @LastEditors: Please set LastEditors
* @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
* @FilePath: \vue3-element-ui-baseline\src\components\baseline\trend\src\index.vue
-->
<template>
<div class="bs-wrapper">
<div class="flex">
<div><bs-trend text="营业额"></bs-trend></div>
<div><bs-trend text="营业额" type="down"></bs-trend></div>
</div>
<br />
<div class="flex">
<div>
<bs-trend
text="自定义颜色上升"
up-icon-color="#52c41a"
></bs-trend>
</div>
<div>
<bs-trend
text="自定义颜色下降"
down-icon-color="#f5222d"
type="down"
></bs-trend>
</div>
</div>
<br />
<div class="flex">
<div>
<bs-trend
text="翻转颜色上升"
text-color="#52c41a"
:reverse-color="true"
></bs-trend>
</div>
<div>
<bs-trend
text="翻转颜色下降"
type="down"
text-color="#f5222d"
:reverse-color="true"
></bs-trend>
</div>
</div>
<br />
<div class="flex">
<div>
<bs-trend
text-color="#52c41a"
icon="el-icon-carettop"
:reverse-color="true"
>
自定义图标上升
</bs-trend>
</div>
<div>
<bs-trend
type="down"
icon="el-icon-caretbottom"
text-color="#f5222d"
:reverWse-color="true"
>
自定义图标下降
</bs-trend>
</div>
</div>
<br />
</div>
</template>
<script lang="ts" setup></script>
<style lang="scss" scoped>
.bs-wrapper {
.flex {
display: flex;
}
div {
margin-right: 0.1rem;
}
}
</style>
发表评论 (审核通过后显示评论):