Vue3 + TypeScript 实现一个温度计

324 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

概述

炎炎夏日,让我们用 Vue3 + TypeScript 一起来实现一个温度计。如果觉得不错欢迎给我点赞评论。

我们先来看下完成的效果图

iShot_2022-06-19_11.34.36.gif

项目初始化

首先我们新建一个项目,执行如下命令

pnpm create vite vue-thermometer

选择 vue ,接着选择 vue-ts ,回车,等待项目安装完成, cd 进入项目根目录下,接着安装项目需要的依赖包

pnpm install

安装完成后,我们启动项目

pnpm run dev

控制台输出如下内容

vite v2.9.10 dev server running at:

> Local: http://localhost:3000/
> Network: use `--host` to expose

ready in 353ms.

说明项目正常启动了,下面我们接着开发

温度计

首先我们需要用 css 样式画一个温度计,然后用用 js 控制显示不同颜色

我们先来画底部,画一个有边框的同心圆

 <div class="thermometer-bg">
    <div class="thermometer">
        <div class="thermometer-bottom">
            <div class="thermometer-bottom-fill"></div>
        </div>
    </div>
</div>
.thermometer {
    width: 200px;
    margin: 0 auto;
    position: relative;
}

.thermometer-bottom,
.thermometer-bottom-fill {
    margin: 0 auto;
    border-radius: 50%;
    z-index: 0;
}
.thermometer-bottom{
     background-color: #ededfa;
    border: 15px solid #d8d9e8;
    margin: 0 auto;
}
.thermometer-bottom-fill {
    background-color: #db1d1d;
    height: 98px;
    width: 98px;
    position: relative;
    top: 11px;
    transition: top 0.5s cubic-bezier(0.33, 1, 0.68, 1);
}

截屏2022-06-17 下午11.53.51.png

这里我们画好的有边框的同心圆其实就是温度计的底部,接着我们温度计的顶部画出来

截屏2022-06-19 上午11.02.47.png

<div class="thermometer-body"></div>

画出来后我们继续

截屏2022-06-19 上午11.21.09.png

到这里温度计我们已经初步画出来了,但是这里要说明的是温度计底部和液体柱的连接处,我们使用伪元素进行了连接,完整的代码如下

<template>
    <div class="thermometer-bg">
        <div class="thermometer">
            <div class="thermometer-body">
                <div ref="thermometerFillRef" class="thermometer-body-fill"></div>
            </div>
            <div class="thermometer-bottom">
                <div class="thermometer-bottom-fill"></div>
            </div>
        </div>
    </div>
</template>
<script setup lang="ts">

</script>
<style scoped>

.thermometer {
    width: 200px;
    margin: 0 auto;
    position: relative;
}
.thermometer-bottom,
.thermometer-body {
    background-color: #ededfa;
    border: 15px solid #d8d9e8;
    margin: 0 auto;
}
.thermometer-bottom,
.thermometer-bottom-fill {
    margin: 0 auto;
    border-radius: 50%;
    z-index: 0;
}
.thermometer-bottom {
    height: 120px;
    width: 120px;
}
.thermometer-bottom::before {
    content: "";
    background-color: #db1d1d;
    height: 15px;
    width: 40px;
    position: absolute;
    left: 80px;
    z-index: 1;
}
.thermometer-bottom-fill {
    background-color: #db1d1d;
    height: 98px;
    width: 98px;
    position: relative;
    top: 11px;
    transition: top 0.5s cubic-bezier(0.33, 1, 0.68, 1);
}
.thermometer-body,
.thermometer-body-fill {
    margin: 0 auto;
    border-radius: 50px 50px 0 0;
    z-index: 1;
}
.thermometer-body {
    height: 325px;
    width: 60px;
    border-bottom: 0;
    position: relative;
    bottom: -23px;
    overflow: hidden;
}
.thermometer-body-fill {
    background-color: #db1d1d;
    height: 320px;
    width: 40px;
    position: relative;
    top: 160px;
    transition: top 0.5s linear;
}
</style>

现在的温度计是静态的,我们可以加点代码实现一个动态变化的温度计

import { ref, onMounted } from 'vue'

const thermometerFillRef = ref<HTMLDivElement | null>()

onMounted(() => {
    setTimeout(() => {
        // thermometerFillRef.value.style.setProperty("top", "20px")
    }, 1300);
})