IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> BitMap实现打卡(一) -> 正文阅读

[JavaScript知识库]BitMap实现打卡(一)

BitMap实现打卡(一)

前提说明

  • 这里我们采用Vue3 + TS进行前端打卡页面的编写
  • 采用Element Plus: https://element-plus.org/zh-CN
  • 后端我们使用Spring Boot2.6.5 + JDK17进行编码

很显然,用这些主要是为了装x,其实用其他的并没有啥区别

前端环境搭建

创建项目

控制台输入指令

yarn create @vitejs/app clock_in

选择vue然后选择vue-ts

创建.env.development

# 开发环境
VITE_APP_TITLE = "打卡"
#端口号
VITE_APP_PORT = "3002"
# 请求接口
VITE_APP_DEV_URL = "http://localhost:8080"
# 前缀
VITE_APP_BASE_API = "/api"

创建.env.production

# 开发环境
VITE_APP_TITLE = "打卡"
#端口号
VITE_APP_PORT = "3002"
# 请求接口
VITE_APP_DEV_URL = "http://localhost:8080"
# 前缀
VITE_APP_BASE_API = "/api"

配置vite.js

import {defineConfig, loadEnv} from 'vite'
import vue from '@vitejs/plugin-vue'

const path = require('path')
const resolve = (dir: string) => path.join(__dirname, dir)

export default ({mode}) => defineConfig({
    plugins: [vue()],
    resolve: {
        alias: {
            '@': resolve('./src'),
            '@v': resolve('./src/views'),
            '@c': resolve('./src/components'),
            '@u': resolve('./src/utils'),
            '@a': resolve('./src/api'),
        },
    },
    server: {
        host: '0.0.0.0',
        port: Number(loadEnv(mode, process.cwd()).VITE_APP_PORT),
        strictPort: true,
        https: false,
        open: true,
        proxy: {
            '/api': {
                target: mode==='development'?loadEnv(mode, process.cwd()).VITE_APP_DEV_URL:loadEnv(mode, process.cwd()).VITE_APP_PROD_URL,
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/api/, '')
            }
        },
        hmr: {
            overlay: true
        }
    },
    build: {
        chunkSizeWarningLimit: 1500,
        rollupOptions: {
            output: {
                manualChunks(id) {
                    if (id.includes('node_modules')) {
                        return id.toString().split('node_modules/')[1].split('/')[0].toString();
                    }
                }
            }
        }
    }
})

安装包依赖

cnpm i

允许使用node(爆红再使用)

cnpm i --save-dev @types/node  

安装Element Plus

cnpm install element-plus --save 

安装sass

cnpm install sass --save 

修改main.ts

import {createApp} from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import zhCn from 'element-plus/es/locale/lang/zh-cn'


const app = createApp(App)

app.use(ElementPlus, {
    locale: zhCn,
})
app.mount('#app')

安装Axios

cnpm install axios --save 

安装moment.js

cnpm install moment --save

创建type.ts

export interface IResponse {
    success: boolean,
    errCode: string,
    errMessage: string,
    data: any
}

配置axios

import axios, {AxiosInstance, AxiosRequestConfig, AxiosResponse} from 'axios';
import {ElMessage} from "element-plus";
import {IResponse} from "./type";

let service: AxiosInstance = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_API + "/api",
    headers: {'Content-Type': 'application/json;charset=utf-8'}
});

// 请求拦截器
service.interceptors.request.use(
    (config: AxiosRequestConfig) => {
        return config;
    },
    (error: any) => {
        return Promise.reject(error);
    }
)

// 响应拦截器
service.interceptors.response.use(
    (response: AxiosResponse) => {
        let res: IResponse = response.data
        if (!res.success) {
            ElMessage.error({message: res.errMessage || '请求失败', duration: 5 * 1000})
        }
        return Promise.resolve(res.data)
    },
    (error: any) => {
        const {response} = error;
        if (response) {
            ElMessage.error({message: '请求失败', duration: 5 * 1000})
            return Promise.reject(response.data);
        } else {
            ElMessage.warning('网络连接异常,请稍后再试!');
        }
    }
);


export default service

编写测试接口

import request from "../util/request";

export const test = () => {
    return request({
        url: '/test',
        method: 'GET'
    })
}

创建一个打卡界面

<script setup lang="ts">
import {reactive, ref, unref} from "vue";
import {ElNotification} from "element-plus";
import moment from "moment";

interface ClockData {
  day: string,
  clock: boolean
}

// 是否已经打卡
let isClocked = ref<boolean>(false)
// 打卡信息
let clockData = ref<Array<ClockData>>([
  {
    "day": "2022-01-01",
    "clock": false
  },
  {
    "day": "2022-01-02",
    "clock": false
  },
  {
    "day": "2022-04-24",
    "clock": true
  },
  {
    "day": "2022-04-25",
    "clock": true
  }
])
// 打卡
const clockIn = async () => {
  ElNotification({showClose: true, message: '打卡成功', type: 'success', duration: 2000})
  isClocked.value = !unref(isClocked)
  clockData.value.push({
    day: moment().format("YYYY-MM-DD"),
    clock: unref(isClocked)
  })
  console.log(clockData)
}

// 判断是否打卡
const checkClockIn = () => {

}

</script>

<template>
  <div class="picker">
    <el-card style="height: 760px">
      <div style="display: flex;justify-content: space-between">
        <span style="font-size: 22px;display: block;margin-bottom: 30px;margin-left: 10px;">打卡</span>
        <span v-if="!isClocked"><el-button type="primary" class="el-icon-s-promotion" style="border: none"
                                           @click="clockIn"><span
            style="color: white;font-weight: bolder">未打卡</span></el-button></span>
        <span v-else><el-button type="success" class="el-icon-s-promotion" style="border: none"><span
            style="color: white;font-weight: bolder">已打卡</span></el-button></span>
      </div>
      <el-calendar :first-day-of-week="7">
        <template #dateCell="{ data }">
          <p>{{ data.day.split('-').slice(2).join('-') }}<br/></p>
          <div v-for="(item, index) in clockData" :key="index">
            <div v-if="data.day === item.day">
                  <span v-if="item.clock">
                 <i class="el-icon-check" style="color: green;font-weight: bolder;">已打卡</i>
                  </span>
            </div>
          </div>
        </template>
      </el-calendar>
    </el-card>
  </div>

</template>

<style scoped lang="scss">
.picker {
  display: flex;
  justify-content: center;
  align-items: center;
}

::v-deep(.el-calendar-table .el-calendar-day) {
  padding: 0;
}

::v-deep(.el-calendar-table td.is-today ) {
  background-color: #fff;
}

::v-deep(.el-calendar-table td.is-selected ) {
  background-color: #fff;
}

::v-deep(.el-calendar-table .el-calendar-day) {
  height: 60px;
  font-size: 12px;
  text-align: center;
}

::v-deep(.el-calendar-table:not(.is-range) td.prev) {
  .calendarFont {
    color: #C0C4CC;
  }

  pointer-events: none;
}

::v-deep(.el-calendar-table thead th) {
  font-size: 12px;
  padding-bottom: 6px;
}

.cal ::v-deep(.el-calendar-day .calendar_circle1) {
  margin: 0 auto;
  padding: 2px;
  text-align: center;
}

.cal ::v-deep(.el-calendar-day .calendar_circle2) {
  border: 1px solid #DE4747;
  border-radius: 50%;
  margin: 0 auto;
  padding: 2px;
  text-align: center;
}
</style>

image.png

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 12:02:02  更:2022-04-29 12:03:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:08:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码